Skip to content

Seller API overview

The Seller API is the panel’s own API, for your shop, Discord bot or scripts. It uses a token instead of a Google sign-in, and it can do what the panel’s License keys, Users, Subscriptions, Variables, Files and Audit log pages do.

https://panel.eonauth.fyi/seller/v1

Every path in this reference is relative to it, for example POST /seller/v1/license/create.

Create a token in the panel under Seller API & stores → New token (see Seller API & stores). Send it on every request:

Authorization: Bearer eon_sk_...
  • A token belongs to one app. Calls about any other app answer 403 FORBIDDEN.
  • It is shown once. Only a hash is stored, so a lost token can’t be recovered; revoke it and make a new one.
  • Everything a token changes is in the audit log as api-token:<token name>.

Keep tokens on your server. Never put one in a client app, a browser, or a public repository.

Managers don’t get the Seller API by default. Creating a token needs App settings: All on the app, plus All on every scope ticked, and only an owner can grant All. Otherwise an owner creates the token and hands it over.

A token is not tied to a person. It keeps All on its scopes whatever the holder’s own permissions are. The keys it makes belong to the token, not the holder. It also keeps working after the manager who made or holds it is disabled or deleted. See Giving a token to someone.

A token acts like a manager with All access to the features you ticked, and nothing else.

Scope Lets the token
licenses Generate, list, search, revoke, delete, import and export keys (Licenses)
users List, ban, pause, rename, delete users; time tools; blacklist; free devices (Users)
logins Read a user’s sessions and sign-in events (Logins and audit)
subscriptions List, create, edit and delete tiers (Subscriptions)
variables List, read, create, edit and delete variables (Variables)
files List, upload, edit and delete files (Files)
audit Read the app’s audit log (Logins and audit)

A call outside the token’s scopes answers 403 FORBIDDEN. A few routes are never open to tokens: owner-only actions (forced HWID resets, resetting every HWID) and anything under App settings (such as update builds). They are marked not available to tokens in this reference.

  • GET routes take query parameters.
  • POST routes take a JSON body. Send Content-Type: application/json. Unknown fields are refused, so a typo can’t be silently ignored.
  • The one exception is file upload, which takes the raw file as the body.
  • IDs carry a prefix: app_, tier_, lic_, usr_, var_, file_, bl_, dev_, bat_, then 32 hex characters.
  • Times are unix seconds.

Success:

{ "ok": true, "data": { "...": "..." } }

Failure:

{ "ok": false, "error": { "code": "INVALID_REQUEST", "message": "duration_days: duration_days is required for preset 'custom' and not allowed otherwise" } }

Some errors add error.details. Check ok (or the HTTP status) first, then read data or error.code. The message is meant for people and may change; the code won’t.

List routes take page (from 1) and page_size (1 to 100, default 50) and answer:

{ "ok": true, "data": { "items": [], "total": 120, "page": 1, "page_size": 50 } }

120 requests per minute per token, counted per Cloudflare location. Over the limit you get:

HTTP/1.1 429 Too Many Requests
Retry-After: 60
{ "ok": false, "error": { "code": "RATE_LIMITED", "message": "Too many requests" } }

Wait for Retry-After seconds. If your shop sends bursts, queue the calls instead of retrying in a loop.

HTTP code When
400 INVALID_REQUEST A field is missing, has the wrong type, or breaks a rule. The message names the field
401 UNAUTHORIZED No token, a malformed one (Missing or malformed API token), or an unknown or revoked one (Invalid or revoked API token)
402 PLAN_LIMIT Your plan’s limit for keys, users, apps or storage is reached
403 FORBIDDEN Outside the token’s scopes, another app, or owner-only
403 QUOTA_EXCEEDED A trial or free key limit is reached
404 NOT_FOUND No such record in this app, or no such route
405 INVALID_REQUEST A method other than GET or POST
409 CONFLICT The key mask can’t make enough new keys, or a key or name is taken
409 HWID_RESET_COOLDOWN, HWID_RESET_QUOTA_EXCEEDED A HWID reset is too soon or over the allowance
413 INVALID_REQUEST A file is too large
429 RATE_LIMITED See Rate limits
500 INTERNAL Something went wrong on our side; safe to retry reads, check before retrying writes

All codes are listed in Error codes.

Generate two month keys for the Default tier. Find your app ID and tier IDs with GET /tiers.

Terminal window
curl -X POST https://panel.eonauth.fyi/seller/v1/license/create \
-H "Authorization: Bearer $EONAUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"app_id":"app_ea9745b1df9e4a9bacb22cb1c200993b","tier_id":"tier_048ef9f8f38c4ab2af05db05bbde4aed","preset":"month","quantity":2,"note":"order 1042"}'

The response holds the keys. They are shown only here; store or deliver them right away.

{
"ok": true,
"data": {
"batch_id": "bat_00c349d64f1d4fd8a44d9b4dc004bc1e",
"app_id": "app_ea9745b1df9e4a9bacb22cb1c200993b",
"tier": "Default",
"preset": "month",
"type": "days",
"duration_days": 30,
"key_mask": "*****-*****-*****-*****-*****",
"created_at": 1794497606,
"kind": "paid",
"price_cents": 0,
"base_price_cents": 0,
"licenses": [
{ "id": "lic_59872ba8a1e94a5db020e505c9790731", "key": "7DY5Q-3BK6F-K8SVH-J4MRT-2WQ9Z" },
{ "id": "lic_8e1f0c2b7a5d4e3f9a6b1c0d2e3f4a5b", "key": "N4XKP-8QJ2M-RT6VW-C3HZL-9YBDA" }
],
"notice": "Keys are shown once. Only their hashes are stored."
}
}