Errors
Every failed request returns a JSON body and a matching HTTP status code in the response headers.
Error format
There are two response shapes depending on which layer rejected the request.
Standard envelope: returned by authentication and by endpoints that validate explicitly (for example, POST /bets):
{
"status": 400,
"message": "stake must be greater than 0",
"data": null
}
| Field | Type | Description |
|---|---|---|
status | integer | HTTP status code, mirrored from the response headers. |
message | string | Human-readable explanation. For multi-field validation, messages are joined with ; . |
data | string | Reserved for additional context. Currently always null. |
Framework fallback: returned when an exception is not handled explicitly (malformed JSON, type mismatch, unknown route, wrong method, wrong content type):
{
"timestamp": "2026-05-26T14:37:46.202+00:00",
"status": 400,
"error": "Bad Request",
"path": "/api/v2/bets"
}
Always branch on the HTTP status code rather than the body shape.
Common error responses
400 Bad Request
Returned for validation failures, malformed bodies, and badly-typed parameters. Validation on POST /bets returns the standard envelope; framework-level errors return the fallback.
Multi-field validation on POST /bets:
{
"status": 400,
"message": "selectionId is required; pricingProviderId is required; stake is required; price is required",
"data": null
}
Stake outside the market's stake limits. The message reports the effective maximum for the price you sent:
{
"status": 400,
"message": "Stake exceeds maximum of 1000",
"data": null
}
Betting a price that has since been withdrawn. Every price you are served is tradable at the moment it is sent, so you cannot pre-empt this by inspecting status; a price can be withdrawn between your read and your bet. Re-read the market and bet the new price:
{
"status": 400,
"message": "Selection price is not active",
"data": null
}
Betting a market or event that the provider has stopped trading. Unlike a withdrawn price, this does not clear on a re-read — the whole market type is closed until it reopens:
{
"status": 400,
"message": "Event market type is not tradable for this provider",
"data": null
}
Framework fallback (malformed JSON, wrong parameter type, invalid ISO-8601 timestamp, page_size outside 1-1000 on paginated list endpoints (/events, /competitions, /participants, /bets), non-numeric values in CSV filters like event_ids=abc):
{
"timestamp": "2026-05-26T14:37:46.202+00:00",
"status": 400,
"error": "Bad Request",
"path": "/api/v2/bets"
}
401 Unauthorized
Bearer token missing, malformed, or rejected. See Authentication for the full message list.
{
"status": 401,
"message": "Missing or invalid Authorization header",
"data": null
}
404 Not Found
Unknown route, or an entity ID does not exist (for example, GET /events/9999999999). Some 404 responses on this path return an empty body, so match on the status code.
{
"timestamp": "2026-05-26T14:36:30.235+00:00",
"status": 404,
"error": "Not Found",
"path": "/api/v2/nonsense"
}
409 Conflict
Returned by POST /bets when the bet_reference you sent already exists for your client with a different stake or price. The original bet is left unchanged and no duplicate is placed. Re-sending the same reference with the same stake and price instead returns the existing bet with a 201 (see Place a bet).
{
"status": 409,
"message": "A bet with reference 'order-12345' already exists with different stake",
"data": null
}
405 Method Not Allowed
Wrong HTTP verb on a known route (for example, POST /sports).
{
"timestamp": "2026-05-26T14:36:30.305+00:00",
"status": 405,
"error": "Method Not Allowed",
"path": "/api/v2/sports"
}
415 Unsupported Media Type
POST /bets sent without Content-Type: application/json, or with a different content type.
{
"timestamp": "2026-05-26T14:37:46.633+00:00",
"status": 415,
"error": "Unsupported Media Type",
"path": "/api/v2/bets"
}
500 Internal Server Error
Unexpected server-side failure. Retry with exponential backoff; contact your integration manager if the failure persists.
Notes
- Multi-field validation errors are joined into a single
messageseparated by;. - Empty response bodies on 404 are expected for some lookups. Always branch on the status code.
- Framework-fallback responses do not currently expose a machine-readable error code; rely on the HTTP status.
- Retry only
5xxand idempotent reads. Never retryPOST /betson4xx.