Rate limits
API requests to the order placement and cancellation endpoints are rate-limited per user. The goal is to keep the exchange responsive for everyone — including you when you need to cancel quickly.At a glance
Buckets are sized to permit short bursts (seeding a market, cleaning up stale orders) while capping the sustained rate. If you exhaust the burst budget, requests are rejected until the window rolls over.
Bulk endpoints (
cancelAllOrders, cancelAllOrdersForGame, cancelAllForLeague) are not gated by the per-request rate limit — they batch internally. They are governed by the cancel-all behavior described below.
editOrder is counted against the place bucket because it functionally posts a new order.
Cancelling many orders at once
If you need to cancel a large set of orders, use a bulk endpoint rather than looping individualcancel calls:
POST /session/cancelMultiple— pass an array ofsessionIDs; one HTTP request, the server cancels them all (subject to internal rate limiting).POST /session/cancelAllOrdersForGame— every open order on a specific game.POST /session/cancelAllOrders— every open order on your account.
cancel calls will hit the burst budget fast and force unnecessary 429s on your client.
Response headers
Every rate-limited response sets a standardRetry-After header (in seconds). Most retry-aware HTTP clients (axios-retry, urllib3 retries, tenacity, etc.) will honor this automatically.
Error response shape
When you exceed a limit (or hit another throttle condition described below), the response body always has the same envelope:details are what you should branch on in code. The top-level code mirrors the HTTP status, and message is intended for humans.
Throttle error codes
Three distinct conditions can throttle or block a request. They all share the same envelope but have differentdetails.code values so you can handle each correctly.
RATE_LIMITED (HTTP 429)
You exceeded the per-second bucket on a place or cancel endpoint. Slow down and retry.
retryAfterSeconds and retry. If you hit this consistently, slow your request rate.
CANCEL_QUEUE_FULL (HTTP 429)
A second-layer guard on the cancel pipeline. You’re sending cancels faster than the system can drain them, even after the per-second rate limit. This is rare in normal use.
RATE_LIMITED — wait and retry. If you hit this often, batch your cancels by using cancelMultiple or cancelAllOrdersForGame instead of looping individual cancel calls.
CANCEL_ALL_IN_PROGRESS (HTTP 423)
A cancelAll-style operation is currently running for your account. Individual cancel requests are temporarily locked out so they don’t race with the bulk operation.
- If the order you tried to cancel already existed when you (or your bot) called
cancelAllOrders, no action needed — the in-progress cancelAll will cancel it. You can drop the retry. - If the order was placed after cancelAll started, wait
retryAfterSecondsand retry the individual cancel.
Cancel-all behavior
When you callPOST /session/cancelAllOrders (or pauseOrders):
- The system acquires a per-user lock and begins cancelling each of your open orders.
- While that bulk operation is in progress, individual cancel requests (
cancel,cancelMultiple,cancelByReference) from your account return423 CANCEL_ALL_IN_PROGRESS— see above. - The bulk operation drains at ~15 cancels/second, so a
cancelAllover 150 orders takes roughly 10 seconds. - When it completes, the lock is released and your individual cancel calls work normally.
cancelAll and then need to ensure a specific order is gone, wait for the cancelAll to complete rather than retrying individual cancels — the cancelAll has already scoped that order for cancellation.
