statshawk
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.

CodeStatusWhat it meansRetry?
BAD_REQUEST400A parameter is malformed or missing (bad date format, invalid id shape).No, fix the request
UNKNOWN_STAT400The stat key on an analysis endpoint isn't a real measure. The error object carries machine-readable valid_stats (every phase-qualified measure id for the resolved sport, or for all sports when no competition was supplied), aliases (the accepted friendly names), and a capabilities pointer at GET /v1/competitions/{comp}/capabilities: self-correct from those.No, fix the stat key
STAGE_NOT_SUPPORTED400The stage selector isn't valid for this competition.No, fix the selector
UNAUTHORIZED401Missing or invalid API key (X-API-Key or Authorization: Bearer).No, fix the key
INVALID_API_KEY401Legacy variant of the same condition; treat identically to UNAUTHORIZED.No, fix the key
TIER_REQUIRES_PAID403Free-tier key calling a paid endpoint (/v1/analysis/*).Upgrade
NOT_FOUND404The resource id (person, team, contest, competition) doesn't exist.No
QUOTA_EXCEEDED429Monthly unit allowance is gone.Upgrade or wait: X-Account-Quota-Reset carries the period-end timestamp
RATE_LIMIT_EXCEEDED429Outpaced your plan's requests-per-second ceiling.Honor Retry-After (usually 1s), then retry
RATE_LIMIT_BACKEND_UNAVAILABLE503The rate-limit backend is unreachable; the API fails closed.Exponential back-off; clears on recovery
INTERNAL_ERROR500Something broke on our side.Retry once, then page support with request_id
CACHE_ERROR500The cache layer failed while serving the request.Retry once, then page support
NOT_SUPPORTED501The competition doesn't support this capability. The body carries machine-readable league and capability fields.No, feature-detect via /v1/competitions/{comp}/capabilities
PROVIDER_ERROR502 / 503An upstream data provider failed (502) or all of them did (503).Exponential back-off, 3–5 attempts
DB_UNAVAILABLE503Database connection pool exhausted or unreachable.Exponential back-off, 3–5 attempts
AUTH_BACKEND_UNAVAILABLE503Key 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 envelope
{
  "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

On this page