Rate limits and errors

Every limit is per minute, and every failure comes with a stable code. Handle the few codes that matter to your flow and log the rest.

Rate limits

Over a limit you get HTTP 429 with E1002, and nothing happens: no charge, no order. Wait for the minute to roll over and retry.

EndpointsLimitCounted per
/cs2 /rust /extra120 a minuteIP address. Counted before the key is looked up, so guessing keys is throttled too.
/cs2 /rust /extra30 a minuteAccount (all keys together). Shared by every key on the account, across all three buy endpoints.
/products60 a minuteIP address
/stock60 a minuteIP address
/balance120 a minuteIP address
/limits120 a minuteIP address
/order120 a minuteIP address
/replace60 a minuteIP address
/replace20 a minuteKey
/preorder/hours /preorder/cancel60 a minuteIP address
/preorder/hours /preorder/cancel20 a minuteAccount (all keys together). Shared by every key on the account, across both pre-order endpoints.
/me120 a minuteIP address
/orders60 a minuteIP address
/ledger60 a minuteIP address
/orders30 a minuteAccount (all keys together)
/ledger30 a minuteAccount (all keys together)
/webhooks /webhooks/{id} /webhooks/{id}/rotate /webhooks/{id}/enable /webhooks/{id}/test /webhooks/{id}/deliveries120 a minuteIP address
/webhooks /webhooks/{id} /webhooks/{id}/rotate /webhooks/{id}/enable /webhooks/{id}/test20 a minuteAccount (all keys together). Changes only: creating, deleting, rotating, enabling and testing endpoints.
/webhooks/{id}/test6 a minuteAccount (all keys together). On top of the limit on changes.

Buys count per account, so every key on it shares one allowance. Most reads count per IP address. /me returns this table as rateLimits, so your code can read it.

Errors

Every failed request has a code like E1401 in the X-Error-Code header, in every format. With result=json the body has the same code and an error sentence.

402 Payment Required
{  "ok": false,  "code": "E1401",  "error": "Not enough balance on the account this key belongs to. Reference E1401."}

Branch on code. The error sentence is safe to show your own customers, but its wording can change, so do not parse it.

What to do

CodeWhat to do
E1002Wait for the next minute and retry.
E1401Top up, then retry. Nothing was charged.
E1501Not enough stock. Retry later, or add preorder=1.
E1503The supplier is briefly down. Retry shortly; nothing was charged.
E1506Wait the Retry-After seconds, or add preorder=1.
E1502Delivery failed and your balance was refunded. Retry.
E1301That Idempotency-Key was used with other parameters. Use a new key for a new order.
E1302The first call with that key is still running. Retry shortly with the same key.
E1701 to E1708Your own API protection refused it. Check your settings.
E1000Our side. Retry, and contact support if it keeps happening.

Only E1506 comes with a Retry-After header. The full list is in Error codes.

Rate limits and errors · API docs · nfa.pub