# Errors

**Errors** are RFC 9457 Problem Details (`application/problem+json`). `type` is `urn:oddsfinder:problem:<slug>`; the catalogue is in `components.x-problem-types`.

Problem types:

- `400` `invalid-request`: Malformed path/query/header value, unknown query parameter, or malformed/expired cursor. `errors` lists each offending parameter.
- `401` `unauthenticated`: No credential, or an invalid, expired or revoked credential. `WWW-Authenticate` names the accepted schemes.
- `403` `forbidden`: The principal or client scope does not permit the operation at all.
- `403` `not-entitled`: A grant, source-rights, territory, lookback or freshness restriction denies this request; `restriction` names it.
- `404` `not-found`: No such path, or no entity with that identifier is visible to the caller at the requested knowledge cutoff.
- `405` `method-not-allowed`: The path exists but not for this method.
- `422` `invalid-range`: A well-formed window is inverted, wider than the operation's bound, or otherwise too large for the operation to answer.
- `422` `unsupported-historical-capability`: A `valid_at`, `known_at` or other time parameter this operation does not support or cannot answer faithfully (for example a `known_at` earlier than the retained correction history). Today's state is never served instead.
- `429` `rate-limited`: The `requests_per_minute` rate limit is used up for the calendar minute, the organization's or, for a caller without an organization, the default per-caller limit; `limit_kind` (`requests_per_minute`) and `limit` name it and `Retry-After` is the end of the minute. Every request counts towards it, failed ones (403, 404, other 4xx, 5xx, a refusal by a daily allowance), `/v1/me/*` and paths without an operation included, so a credential missing the operation's scope receives this problem instead of `403 not-entitled` once its minute is used; a refusal by the rate limit itself does not count, except for a caller without an organization, whose refusals count towards its minute too (it is still refused only until the minute ends). No usage is metered for the rejected request. When a daily allowance is exhausted too, the answer is `quota-exceeded`.
- `429` `quota-exceeded`: A daily allowance of the organization (`requests_per_day`, or a per-dataset allowance) is exhausted for its UTC day; `limit_kind` and `limit` name it and `Retry-After` is the end of the latest-ending exhausted period. No usage is metered for the rejected request. A daily allowance counts the requests in flight and the served ones (a failed request releases what it reserved); metered usage counts served requests only. A used-up per-minute rate limit alone is `rate-limited`.
- `500` `internal-error`: Unexpected failure; `request_id` identifies the server-side record.
- `503` `unavailable`: A service this operation depends on is temporarily unavailable; nothing is served in its place.
- `503` `policy-unavailable`: Your access, quota or usage records cannot be checked right now, so the request is refused rather than served unchecked.

The problem object:
- `type` (string)
- `title` (string)
- `status` (integer)
- `detail` (string)
- `instance` (string): Request path.
- `request_id` (uuid): Server-generated request identifier (UUID); not an entity identifier.
- `errors` (array of objects): Per-parameter detail for `invalid-request`.
  - `location` (enum):  One of: `path`, `query`, `header`, `body`.
  - `name` (string)
  - `message` (string)
- `restriction` (enum): For `not-entitled`: which restriction denied the request. One of: `scope`, `dataset`, `competition`, `territory`, `lookback`, `freshness`, `source_rights`.
- `retry_after_seconds` (integer)
