Get started
Rate limits
Per-plan throughput, the headers that report it, why a 503 is not a 429, and how to back off.
Limits exist so one integration cannot degrade another. They are generous for normal play and tight enough to contain a runaway retry loop.
Response headers
Every authenticated response carries your current standing:
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 574
X-RateLimit-Reset: 1756487400
Retry-After: 12X-RateLimit-Limitinteger | Requests permitted in the current window. |
X-RateLimit-Remaininginteger | Requests left in it. |
X-RateLimit-Resetunix seconds | When the window rolls over. |
Retry-Afterseconds | Present only on a 429. Wait at least this long. |
What is limited
Limits are per operator account, not per credential — minting more credentials does not buy more throughput. Money endpoints are limited separately from reads, so a burst of reporting queries cannot starve settlement.
- Money — bet, win, refund, rollback.
- Sessions — creating and closing sessions.
- Reads — catalogue, transactions, reporting.
- Public — the unauthenticated catalogue and contact endpoints, limited by IP.
Your plan's throughput
The figure below is the floor your account is guaranteed across the authenticated endpoints. Individual routes may allow more — a plan raises a limit, it never lowers one.
Sandbox300/min | Enough to build and test against. |
Starter600/min | A first live casino. |
Growth1,800/min | Several brands at once. |
Business6,000/min | Volume. |
Enterpriseagreed | Written into the contract. |
If you are hitting these in normal play that is a conversation rather than a hard ceiling — ask, and we will look at the traffic with you.
503 is different from 429, and you must handle it
A 429 means you asked for too much. A 503 means we could not serve you: under saturation the platform sheds load rather than falling over, and it sheds from the bottom — unauthenticated traffic first, then Sandbox and Starter, and only past its own capacity anything above that.
{
"error": {
"code": "SERVICE_UNAVAILABLE",
"message": "the platform is shedding load — retry shortly",
"request_id": "7c2e1f90-…",
"retryable": true
}
}!Treat 503 as retryable, not fatal
Retry-After and use the same backoff you use for a 429.Settlement is never shed. Wins, refunds, rollbacks and crash cash-outs are excluded at every pressure level, whatever your plan. Refusing a bet is survivable; refusing the win that follows one would leave a player short and a ledger half-written. Health and status are never shed either.
When you are limited
{
"error": {
"code": "RATE_LIMITED",
"message": "too many requests; retry after 12s",
"request_id": "7c2e1f90-…",
"retryable": true
}
}!Back off exponentially, and add jitter
function backoff(attempt, retryAfterSeconds) {
// Honour the server's own number when it gives one.
if (retryAfterSeconds) return retryAfterSeconds * 1000;
const base = Math.min(2 ** attempt * 250, 30_000);
return base * (0.5 + Math.random()); // jitter: 50–150% of base
}Edge protection
Traffic also passes a WAF and an edge rate limiter before it reaches the API. A request blocked there gets a Cloudflare error page rather than our JSON envelope — if you see HTML where you expected JSON, that is what happened, and it usually means an unusual request pattern rather than an outage.