Errors
The API uses standard HTTP status codes. There are two error body shapes.
Most errors: plain text
Lookups and business-rule failures return a short plain-text body with the status code:
HTTP/1.1 404 Not Found
ORG_NOT_FOUND
Don't parse these as JSON. Branch on the status code; the body is a short
human/diagnostic string (sometimes a stable token like ORG_NOT_FOUND or
PAYMENT_FAILED).
Body validation: JSON
When a request body fails validation (e.g. the newsletter email), you get
422 Unprocessable Entity with a JSON map of field → reason:
{
"errors": {
"email": "email"
}
}
The value is the failed rule (required, email, max, …).
Status codes you'll see
| Status | Meaning |
|---|---|
200 | Success (also used by odds when status: "unavailable" — check the body). |
204 | Success, no content (newsletter subscribe, unsubscribe). |
400 | Malformed request — bad path/query param or unparseable JSON. |
404 | Org / event / resource not found, or not public. |
409 | Action not allowed right now (e.g. registration window closed). |
422 | Request body failed validation (JSON errors map). |
429 | Rate limited — 60/min per IP. |
500 | Unexpected server error — safe to retry. |
A note on "unavailable" responses
Some endpoints return 200 with an in-body status rather than an HTTP error.
The clearest example is odds: when probabilities can't be computed
yet (no scores), the response is 200 with "status": "unavailable" and a
message. Always check status on those payloads.