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 message lists the valid keys.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-RateLimit-Reset carries the period-end timestamp
RATE_LIMIT_EXCEEDED429Too many requests in the per-second/per-window cap.Back off briefly, then retry
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