Licenses
Every route on this page needs the licenses scope.
Generate keys
Section titled “Generate keys”/seller/v1/license/createscope: licensesGenerates up to 500 keys in one batch. The raw keys are in this response only; EonAuth keeps just their hashes.
| Field | Type | Required | Notes |
|---|---|---|---|
app_id |
string | yes | Your token’s app |
tier_id |
string | yes | A tier in that app, not archived |
preset |
string | yes | day, week, month, two_months, year, lifetime, custom or one_time |
duration_days |
integer | with custom |
1 to 36500. Required for custom, refused for anything else |
quantity |
integer | yes | 1 to 500 |
max_hwid_resets |
integer | no | 0 to 100, default 1 |
key_mask |
string | no | 8 to 64 characters; each * becomes a random character. Default *****-*****-*****-*****-***** |
kind |
string | no | paid (default), trial or free. See kinds |
note |
string | no | Up to 200 characters, searchable. Handy for an order number |
hwid_check |
boolean or null | no | true always lock the account to one PC, false never, null or absent follow the app |
save_mask_as_default |
boolean | no | Also make key_mask this token’s default mask |
{ "app_id": "app_ea9745b1df9e4a9bacb22cb1c200993b", "tier_id": "tier_048ef9f8f38c4ab2af05db05bbde4aed", "preset": "month", "quantity": 2, "key_mask": "SHOP-****-****-****-****", "note": "order 1042"}{ "ok": true, "data": { "batch_id": "bat_00c349d64f1d4fd8a44d9b4dc004bc1e", "app_id": "app_ea9745b1df9e4a9bacb22cb1c200993b", "tier": "Default", "preset": "month", "type": "days", "duration_days": 30, "key_mask": "SHOP-****-****-****-****", "created_at": 1794497606, "kind": "paid", "price_cents": 0, "base_price_cents": 0, "licenses": [ { "id": "lic_59872ba8a1e94a5db020e505c9790731", "key": "SHOP-7DY5-3BK6-FK8S-VHJ4" }, { "id": "lic_c41d0e7f2a9b4c58b1e6d3f0a7b2c9e4", "key": "SHOP-N4XK-P8QJ-2MRT-6VWC" } ], "notice": "Keys are shown once. Only their hashes are stored." }}typeisdays,lifetimeorone_time.duration_daysisnullfor lifetime and one-time keys.price_centsis the price booked for each key (from Prices);0for trial and free keys or when no price is set.
Errors you may see:
| Status | Code | Why |
|---|---|---|
| 400 | INVALID_REQUEST |
duration_days missing for custom (or given for another preset), the tier is archived, or the mask can’t make that many keys, e.g. A mask without '*' is one fixed key: generate 1, or add '*' |
| 402 | PLAN_LIMIT |
Your plan’s key limit is reached |
| 403 | QUOTA_EXCEEDED |
The app’s trial or free key limit is reached |
| 404 | NOT_FOUND |
Tier not found in this app |
| 409 | CONFLICT |
Most keys the mask can make already exist: add * |
List keys
Section titled “List keys”/seller/v1/licensesscope: licenses| Query | Notes |
|---|---|
app_id |
Your token’s app |
tier_id |
Only this tier |
status |
unused, active, redeemed, expired or banned |
kind |
paid, trial or free |
q |
A whole key, key ID, batch ID, the last four characters, a username, a HWID, or text in the note |
page, page_size |
See paging |
Newest first.
{ "ok": true, "data": { "items": [ { "id": "lic_29a9789d2f1640e88617a4d5f61116ac", "app_id": "app_ea9745b1df9e4a9bacb22cb1c200993b", "app_name": "My App", "tier_id": "tier_048ef9f8f38c4ab2af05db05bbde4aed", "tier_name": "Default", "key_hint": "5G2T", "type": "days", "duration_days": 30, "expires_at": null, "status": "redeemed", "max_hwid_resets": 1, "hwid_check": null, "note": null, "batch_id": "bat_f56412014c1946e4b58561e840e2f20e", "kind": "paid", "price_cents": 0, "base_price_cents": 0, "created_by": "tok_2ad338dbbfe44929977a4c4525a9e274", "created_by_type": "admin", "created_by_email": null, "created_at": 1794497605, "activated_at": 1794497605, "consumed_at": null, "user_id": "usr_4d97591b6d9040f38bc196b6b4ac0236", "username": "alice", "login_method": "key", "user_banned": 0, "hwid": "95d4f53f6a9e855cb8a0a7d1a98770c287452aa2af71c77b4be6a3e99703754f", "hwid_resets_used": 0, "hwid_resets_allowed": 1 } ], "total": 1, "page": 1, "page_size": 50 }}key_hintis the last four characters. The whole key is never returned again.- For a key linked to a user,
hwid,hwid_resets_usedandhwid_resets_allowedare the user’s, since the PC lock lives on the account. - A redeemed key’s time is on the user’s subscription, so its own
expires_atstaysnull; read the user’ssubscriptionsfrom List users. - Booleans stored as numbers (
user_banned) are0or1.
List key IDs
Section titled “List key IDs”/seller/v1/licenses/idsscope: licensesThe same filters as List keys, returning only IDs, up to 1,000. Use it to feed a bulk action.
{ "ok": true, "data": { "ids": ["lic_031dad0a9be0457c9d6294b30591abc7", "lic_35a8aa990ea445c5baf193c8aa4bb6a9"], "truncated": false, "limit": 1000 } }truncated: true means more than 1,000 keys matched; narrow the filter.
Revoke a key
Section titled “Revoke a key”/seller/v1/license/revokescope: licensesBans the key. Sessions using it end at once, and the time it granted is taken off its user.
| Field | Type | Required | Notes |
|---|---|---|---|
license_id |
string | yes | |
reason |
string | no | Up to 200 characters |
{ "ok": true, "data": { "revoked": true, "sessions_revoked": 0 } }Unrevoke a key
Section titled “Unrevoke a key”/seller/v1/license/unrevokescope: licenses| Field | Type | Required |
|---|---|---|
license_id |
string | yes |
{ "ok": true, "data": { "unrevoked": true, "status": "unused" } }status is what the key goes back to.
Reset a key’s HWID
Section titled “Reset a key’s HWID”/seller/v1/license/reset-hwidscope: licensesFrees the PC lock (the user’s, when the key is linked to one), within the allowance and the app’s cooldown. The user’s open sessions end.
| Field | Type | Required | Notes |
|---|---|---|---|
license_id |
string | yes | |
force |
boolean | no | Ignore the allowance. Owner only, so a token gets 403 FORBIDDEN (Owner role required) |
{ "ok": true, "data": { "reset": true, "hwid_resets_used": 1, "user_id": "usr_4d97591b6d9040f38bc196b6b4ac0236" } }409 HWID_RESET_QUOTA_EXCEEDED when the allowance is used up, 409 HWID_RESET_COOLDOWN when the
last reset was too recent.
Delete a key
Section titled “Delete a key”/seller/v1/license/deletescope: licenses| Field | Type | Required | Notes |
|---|---|---|---|
license_id |
string | yes | |
delete_user |
boolean | no | Also delete the account the key is linked to, with all its keys. Default false |
{ "ok": true, "data": { "deleted": true, "user_deleted": false, "allowance_refunded": false } }allowance_refunded is true when an unused reseller key was deleted and its allowance given back.
Bulk actions
Section titled “Bulk actions”/seller/v1/licenses/bulkscope: licensesOne action on up to 1,000 keys.
| Field | Type | Required | Notes |
|---|---|---|---|
action |
string | yes | revoke, unrevoke, reset_hwid, delete or set_hwid_check |
license_ids |
string[] | yes | 1 to 1000 |
reason |
string | no | For revoke |
delete_users |
boolean | no | For delete: also delete the linked accounts |
hwid_check |
boolean or null | for set_hwid_check |
true lock, false don’t lock, null follow the app |
force |
boolean | no | For reset_hwid. Owner only, not available to tokens |
{ "action": "revoke", "license_ids": ["lic_59872ba8a1e94a5db020e505c9790731", "lic_c41d0e7f2a9b4c58b1e6d3f0a7b2c9e4"], "reason": "refund" }{ "ok": true, "data": { "action": "revoke", "requested": 2, "revoked": 2, "sessions_revoked": 0, "skipped": { "not_found": 0, "not_allowed": 0 } } }What comes back depends on the action:
| Action | Fields |
|---|---|
revoke |
revoked, sessions_revoked |
unrevoke |
unrevoked |
reset_hwid |
reset, no_hwid (nothing to reset), quota_exceeded, cooldown |
delete |
deleted, users_deleted, keys_deleted_with_users, allowance_refunded, skipped_in_use, skipped_users |
set_hwid_check |
updated |
Every answer also has action, requested and skipped. Keys that don’t exist or that the token
may not touch are counted in skipped instead of failing the whole call.
Import keys
Section titled “Import keys”/seller/v1/licenses/importscope: licensesBrings in keys from another system, so customers keep the keys they already have.
| Field | Type | Required | Notes |
|---|---|---|---|
app_id |
string | yes | |
tier_id |
string | yes | |
keys |
string[] | yes | 1 to 1000 keys, 16 to 80 characters each |
preset |
string | yes | As for Generate keys |
duration_days |
integer | with custom |
1 to 36500 |
max_hwid_resets |
integer | no | 0 to 100, default 1 |
note |
string | no | Up to 200 characters |
{ "ok": true, "data": { "batch_id": "bat_ce498fb66b78436bad2e1eaccbeede3b", "imported": 2, "duplicates": 0 } }Keys that already exist are skipped and counted in duplicates.
Add time to unused keys
Section titled “Add time to unused keys”/seller/v1/licenses/add-timescope: licensesAdds days to every key nobody has used yet, for example to make up for downtime before launch.
| Field | Type | Required | Notes |
|---|---|---|---|
app_id |
string | yes | |
days |
integer | yes | 1 to 3650 |
tier_id |
string | no | Only this tier |
include_reseller_keys |
boolean | no | Also resellers’ keys. Default false |
{ "ok": true, "data": { "updated": 5 } }Export keys
Section titled “Export keys”/seller/v1/licenses/exportscope: licensesThe same filters as List keys, up to 5,000 rows, newest first.
{ "ok": true, "data": { "items": [ { "id": "lic_031dad0a9be0457c9d6294b30591abc7", "key_hint": "TC67", "tier": "Default", "type": "one_time", "duration_days": null, "status": "unused", "username": null, "hwid": null, "note": null, "batch_id": "bat_f99b1a4b2952481aaa9ded6bcb99280f", "created_at": 1794497606, "activated_at": null, "expires_at": null } ], "truncated": false }}