Guide

Rate limits & quotas

Per-minute limits, monthly quotas, caching and ETags.

Per-minute limit

Each key has a sliding one-minute window (30/min on trial, 120/min on standard). The window is smoothed across minute boundaries, so bursting 120 at 0:59 and 120 at 1:01 does not work — spread requests out or respect Retry-After.

Monthly quota

Quota counts requests, not rows: a 1,000-row page costs the same as a 1-row page, so use big pages. Every request counts, including cache hits, 304s and errors you caused (400/404). Requests rejected with 401/403/429 do not count. Quota resets at 00:00 UTC on the 1st.

Headers

HeaderMeaning
X-RateLimit-LimitRequests allowed per minute for this key.
X-RateLimit-RemainingRequests left in the current window.
X-RateLimit-ResetUnix seconds when the window rolls over.
X-Quota-LimitMonthly request quota (or `unlimited`).
X-Quota-RemainingRequests left this month.
X-Quota-ResetUnix seconds of the next monthly reset.
Retry-AfterOn 429 only: seconds to wait.
X-Request-IdQuote this when reporting a problem.
X-Cache`HIT` or `MISS` — whether the response came from the API cache.
Example response headers
X-RateLimit-Limit: 600
X-RateLimit-Reset: 1791927720
X-Quota-Limit: unlimited
X-Quota-Reset: 1793491200
X-RateLimit-Remaining: 592
X-Quota-Remaining: unlimited
ETag: "bb35cfa6474384c560b9e3d8445cc5031cfedee6"
Cache-Control: public, max-age=86400
X-Cache: HIT

Caching & ETags

Every 200 carries an ETag and Cache-Control: public, max-age=N. N is 86,400 (24h) when the request can't be affected by games finishing today or yesterday (a past season, or a to date before yesterday), otherwise 900 (15 min). Send If-None-Match to get a 304 when nothing changed — it still counts as a request but moves no bytes. Responses are shared across customers: two keys asking the same question get the same cached bytes.

Handling 429

429 rate_limited
{
  "error": {
    "code": "rate_limited",
    "message": "rate limit of 30 requests/minute exceeded — retry in 12s"
  }
}
429 quota_exceeded
{
  "error": {
    "code": "quota_exceeded",
    "message": "monthly quota of 2000 requests exhausted — resets 2026-11-01"
  }
}

Branch on error.code: rate_limited → sleep Retry-After seconds and retry; quota_exceeded → stop until X-Quota-Reset or upgrade. Don't retry 400s.