Rate limits
A per-key token bucket governs request rates; a hard monthly quota governs volume.
Two independent caps apply to every request, both per API key:
- A rate limit — a token bucket sized by your plan smooths short-term throughput.
- A monthly quota — the standard plan includes 10,000 requests per calendar month, enforced as a hard cap: requests past it are rejected until the month resets.
All keys see the same endpoints and data — the plan changes throughput and included volume, not features.
What counts
Every authenticated REST request draws one token and one unit of monthly quota. When your bucket is empty, further requests are rejected until it refills:
// 429 Too Many Requests
{ "error": "rate limit exceeded" }Back off and retry after a short delay. Spikes are smoothed by the bucket's burst capacity; steady
throughput above your refill rate is what triggers 429s.
When your monthly quota is used up, requests are rejected until the next calendar month starts:
// 429 Too Many Requests
{ "error": "monthly quota exceeded" }Response headers
Every metered response tells you where you stand — no need to count client-side:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Your token bucket's capacity (the burst allowance). |
X-RateLimit-Remaining | Whole tokens left in the bucket after this request. |
X-Quota-Limit | Your monthly request quota (10,000 on the standard plan). |
X-Quota-Remaining | Requests left in the current calendar month. |
X-Quota-Reset | When the quota resets (RFC 3339, UTC — the start of next month). |
Either kind of 429 also carries Retry-After — the number of seconds to wait before retrying
(a second or two for a rate-limit 429; up to the month boundary for a quota 429).
Checking your usage
The headers above are authoritative per request; your dashboard shows the same request volume and remaining allowance for each key. Rate-limit and quota enforcement live in the API itself; the dashboard reads the same usage events the API records per request.
WebSocket connections
The WebSocket channel is metered differently from REST — a persistent connection isn't a stream of discrete requests, so the token-bucket model doesn't map cleanly onto it. It's a tier-gated feature, capped by concurrent connections rather than metered per message:
- Concurrent-connection cap. On the standard plan a key may hold 5 concurrent connections
(the cap is tier-based). Opening one past the cap is refused with an
errorframe (code: "connection_limit") followed by a close — not a queue. - Minting the ticket is one metered request.
POST /v1/{game}/ws-tokenis an ordinary authenticated REST call, so it draws one token and one unit of monthly quota like any other. The messages pushed over the open connection afterwards are not billed — an open subscription accrues no per-message or per-heartbeat charges for its lifetime. - Disconnecting frees the slot immediately, including a heartbeat-timeout close.
Reuse one connection across many matches (that's what
subscribeis for) rather than opening one per match, and reconnect with backoff rather than in a tight loop.