The free key reads yesterday again: our one-month trial of today on the free key has finished. Read the changelog

Errors

Every refusal tells you what to do about it.

The shape

Errors use the same envelope as everything else. error.code is stable and safe to branch on; error.message is for humans and may be reworded.

{
  "error": {
    "code": "plan_required",
    "message": "Half-time prices need the Archive plan.",
    "your_plan": "free",
    "needs_plan": "archive",
    "upgrade_url": "/pricing?from=odds"
  },
  "meta": { "request_id": "01J9QW3C7M4KX2VB" }
}

The codes

400 invalid_parameter: a filter was the wrong type or outside its range. The message names the parameter.

401 missing_key / 401 unknown_key: no X-API-Key header, or one we do not recognise. A rotated key gives this.

403 plan_required: a valid key on a plan that does not reach this endpoint. Always names the plan needed.

403 outside_plan_window, a free key asking for a match or a date older than its window. The error states the window and names the plan that carries older matches.

404 not_found: no such match, club or competition.

429 rate_limited: see rate limits.

500 server_error: ours, not yours. Quote the request_id.

request_id

Every response carries one, success or failure. Quote it in a support thread and we can find the exact call you made rather than asking you to describe it.

What to retry

Retry 429 after retry-after, and 500 with a backoff. Never retry 400, 401, 403 or 404: the answer will not change.