Getting started
Error codes
Every machine-readable error code, with an example body and retry guidance.
Every error code in one place
Status codes tell the HTTP story; the error.code field tells the API story. Codes are
SCREAMING_SNAKE_CASE and stable across versions — pattern-match on them, not on the message.
| Code | Status | What it means | Retry? |
|---|---|---|---|
BAD_REQUEST | 400 | A parameter is malformed or missing (bad date format, invalid id shape). | No — fix the request |
UNKNOWN_STAT | 400 | The stat key on an analysis endpoint isn't a real measure. The message lists the valid keys. | No — fix the stat key |
STAGE_NOT_SUPPORTED | 400 | The stage selector isn't valid for this competition. | No — fix the selector |
UNAUTHORIZED | 401 | Missing or invalid API key (X-API-Key or Authorization: Bearer). | No — fix the key |
INVALID_API_KEY | 401 | Legacy variant of the same condition; treat identically to UNAUTHORIZED. | No — fix the key |
TIER_REQUIRES_PAID | 403 | Free-tier key calling a paid endpoint (/v1/analysis/*). | Upgrade |
NOT_FOUND | 404 | The resource id (person, team, contest, competition) doesn't exist. | No |
QUOTA_EXCEEDED | 429 | Monthly unit allowance is gone. | Upgrade or wait — X-RateLimit-Reset carries the period-end timestamp |
RATE_LIMIT_EXCEEDED | 429 | Too many requests in the per-second/per-window cap. | Back off briefly, then retry |
INTERNAL_ERROR | 500 | Something broke on our side. | Retry once, then page support with request_id |
CACHE_ERROR | 500 | The cache layer failed while serving the request. | Retry once, then page support |
NOT_SUPPORTED | 501 | The competition doesn't support this capability. The body carries machine-readable league and capability fields. | No — feature-detect via /v1/competitions/{comp}/capabilities |
PROVIDER_ERROR | 502 / 503 | An upstream data provider failed (502) or all of them did (503). | Exponential back-off, 3–5 attempts |
DB_UNAVAILABLE | 503 | Database connection pool exhausted or unreachable. | Exponential back-off, 3–5 attempts |
AUTH_BACKEND_UNAVAILABLE | 503 | Key validation backend is down (this is not an invalid key). | Exponential back-off, 3–5 attempts |
Example body
Every error body has the same envelope — just the error object, no meta. Some codes add
extra fields inside error beside code/message; NOT_SUPPORTED carries league and
capability so clients can feature-detect without string-matching:
{
"error": {
"code": "NOT_SUPPORTED",
"message": "play_by_play is not available for epl",
"league": "epl",
"capability": "play_by_play"
}
}See also
- Errors — status code semantics and back-off curves
- Rate limits — the throttling headers
- Quotas — what a unit is, and how the cap works