# List fixtures in a competition and kickoff window

`GET /v1/fixtures`

Fixtures of one competition whose kickoff (as known at `known_at`) lies in
`[from, to)`. The window is required and bounded to 92 days; a wider or
inverted window is a `422 invalid-range`. Stable order: `kickoff_at`
ascending, then `id` ascending. Kickoff is always known (precision may be
`day` for an early listing). Only what sources holding a display right for
fixtures stated is served: a fixture known only through other sources is not
listed. A page holds `limit` items while more follow, and `next_cursor` never
refers to a fixture that is not listed.

Parameters:
- `competition_id` (query, string, required): Competition identifier (`cmp_<digits>`). A retired identifier filters, and is authorized, as the competition it resolves to at `known_at` (`resolution.competition_id`).
- `season_id` (query, string, optional): Season identifier (`ssn_<digits>`). A retired identifier filters by the season it resolves to at `known_at` (`resolution.season_id`).
- `from` (query, timestamp, required): Inclusive lower bound of the kickoff window (UTC).
- `to` (query, timestamp, required): Exclusive upper bound of the kickoff window (UTC); at most 92 days after `from`.
- `known_at` (query, timestamp, optional): Knowledge cutoff (UTC); the answer reflects only what OddsFinder had recorded by this instant. Default is the request time. Must not be in the future.
- `cursor` (query, string, optional): Opaque page cursor from a previous `page.next_cursor`; filters must be repeated unchanged.
- `limit` (query, integer, optional): Maximum items per page.

Returns `200`: One page of fixtures.
- `items` (array of objects):  See [the fixture object](obj-Fixture.md).
- `page` (object)
  - `next_cursor` (string, nullable): Cursor for the next page, or `null` on the last page.
  - `limit` (integer)
- `knowledge` (object): The effective knowledge cutoff of the response. Under a grant freshness delay it is never later than the request time minus the delay, whatever `known_at` asked for.
  - `known_at` (timestamp): RFC 3339 instant in UTC with `Z` suffix; optional fractional seconds up to microseconds.
  - `as_requested` (boolean): True when the caller supplied `known_at`; false when it defaulted to the request time.
- `resolution` (object): How each identifier filter of a list read resolved at `known_at`, by parameter name; present when a supplied filter names a registered entity the caller is served and its grant admits (an entity outside a competition restriction, or one the single read answers as unknown, is not echoed and the filter applies as given). A retired identifier (`status` `alias`) filters, and for a competition is authorized, as its `canonical_id`; list items themselves never carry a resolution.
  - `team_id` (object): How the requested identifier resolved. Present whenever the requested identifier is not the canonical one, and optional otherwise.
    - `requested_id` (string): OddsFinder identifier, `<prefix>_<digits>`, a per-kind sequence number without padding, leading zeros, grouping or sign (1 to 9223372036854775807). The prefix names the kind; the per-kind schemas fix it where a field or parameter has one kind. `Resolution` uses this generic form because its identifiers are of the resource's kind.
    - `canonical_id` (string): OddsFinder identifier, `<prefix>_<digits>`, a per-kind sequence number without padding, leading zeros, grouping or sign (1 to 9223372036854775807). The prefix names the kind; the per-kind schemas fix it where a field or parameter has one kind. `Resolution` uses this generic form because its identifiers are of the resource's kind.
    - `status` (enum): `canonical`: the requested identifier is the identity itself; `alias`: it was retired by a merge decision and resolves to `canonical_id`. One of: `canonical`, `alias`.
    - `decision_id` (string, nullable): Identifier of a merge or reversal decision (`dec_<digits>`), a record you can cite.
    - `decided_at` (timestamp, nullable): A `Timestamp`, or `null` when unknown; the owning object says why.
  - `competition_id` (object): How the requested identifier resolved. Present whenever the requested identifier is not the canonical one, and optional otherwise.
    - `requested_id` (string): OddsFinder identifier, `<prefix>_<digits>`, a per-kind sequence number without padding, leading zeros, grouping or sign (1 to 9223372036854775807). The prefix names the kind; the per-kind schemas fix it where a field or parameter has one kind. `Resolution` uses this generic form because its identifiers are of the resource's kind.
    - `canonical_id` (string): OddsFinder identifier, `<prefix>_<digits>`, a per-kind sequence number without padding, leading zeros, grouping or sign (1 to 9223372036854775807). The prefix names the kind; the per-kind schemas fix it where a field or parameter has one kind. `Resolution` uses this generic form because its identifiers are of the resource's kind.
    - `status` (enum): `canonical`: the requested identifier is the identity itself; `alias`: it was retired by a merge decision and resolves to `canonical_id`. One of: `canonical`, `alias`.
    - `decision_id` (string, nullable): Identifier of a merge or reversal decision (`dec_<digits>`), a record you can cite.
    - `decided_at` (timestamp, nullable): A `Timestamp`, or `null` when unknown; the owning object says why.
  - `season_id` (object): How the requested identifier resolved. Present whenever the requested identifier is not the canonical one, and optional otherwise.
    - `requested_id` (string): OddsFinder identifier, `<prefix>_<digits>`, a per-kind sequence number without padding, leading zeros, grouping or sign (1 to 9223372036854775807). The prefix names the kind; the per-kind schemas fix it where a field or parameter has one kind. `Resolution` uses this generic form because its identifiers are of the resource's kind.
    - `canonical_id` (string): OddsFinder identifier, `<prefix>_<digits>`, a per-kind sequence number without padding, leading zeros, grouping or sign (1 to 9223372036854775807). The prefix names the kind; the per-kind schemas fix it where a field or parameter has one kind. `Resolution` uses this generic form because its identifiers are of the resource's kind.
    - `status` (enum): `canonical`: the requested identifier is the identity itself; `alias`: it was retired by a merge decision and resolves to `canonical_id`. One of: `canonical`, `alias`.
    - `decision_id` (string, nullable): Identifier of a merge or reversal decision (`dec_<digits>`), a record you can cite.
    - `decided_at` (timestamp, nullable): A `Timestamp`, or `null` when unknown; the owning object says why.

Errors: `400` Malformed parameter or cursor (`invalid-request`).; `401` Missing or invalid credential (`unauthenticated`).; `403` Operation not permitted (`forbidden`) or restricted by grants/rights (`not-entitled`).; `422` Well-formed but unanswerable (`invalid-range`, `unsupported-historical-capability`).; `429` The per-minute rate limit is used up (`rate-limited`) or a daily allowance is exhausted (`quota-exceeded`). Failed requests (403, 404, other 4xx, 5xx) use up the per-minute rate limit too.; `500` Unexpected failure (`internal-error`); `request_id` identifies the server-side record.; `503` A service this operation depends on, or the access check, is temporarily unavailable (`unavailable`, `policy-unavailable`).

Example request (200 · Window):

```bash
curl -G https://api.example.com/v1/fixtures \
  -H "X-API-Key: $ODDSFINDER_API_KEY" \
  -d competition_id=cmp_1 \
  -d from=2026-10-01T00:00:00Z \
  -d to=2026-10-08T00:00:00Z \
  -d known_at=2026-10-01T00:00:00Z
```

Example response (200):

```json
{
  "items": [
    {
      "id": "fx_1",
      "competition_id": "cmp_1",
      "season_id": "ssn_1",
      "stage_id": "stg_1",
      "home_team_id": "tm_1",
      "away_team_id": "tm_2",
      "kickoff_at": "2026-10-03T16:30:00Z",
      "kickoff_precision": "minute",
      "status": "scheduled",
      "venue": "Northbridge Park",
      "venue_id": "ven_1",
      "kickoff_revisions": [
        {
          "id": "rev_1",
          "revision_no": 1,
          "kickoff_at": "2026-10-03T14:00:00Z",
          "kickoff_precision": "minute",
          "status": "scheduled",
          "recorded_at": "2026-09-01T09:00:00Z",
          "reason": "initial"
        },
        {
          "id": "rev_2",
          "revision_no": 2,
          "kickoff_at": "2026-10-03T16:30:00Z",
          "kickoff_precision": "minute",
          "status": "scheduled",
          "recorded_at": "2026-09-25T09:00:00Z",
          "reason": "kickoff_correction"
        }
      ],
      "result": {
        "id": "res_1",
        "version": 1,
        "status": "pending",
        "result_kind": null,
        "score_ht": null,
        "score_ft": null,
        "score_et": null,
        "score_pens": null,
        "retracted": false,
        "decided_at": null,
        "recorded_at": "2026-09-01T09:00:00Z"
      },
      "knowledge": {
        "known_at": "2026-10-01T00:00:00Z",
        "as_requested": true
      },
      "sources": {
        "status": "included",
        "items": [
          {
            "source": "synthetic_alpha",
            "observed_at": "2026-09-25T08:55:00Z",
            "recorded_at": "2026-09-25T09:00:00Z",
            "precision": "minute"
          }
        ]
      }
    }
  ],
  "page": {
    "next_cursor": null,
    "limit": 50
  },
  "knowledge": {
    "known_at": "2026-10-01T00:00:00Z",
    "as_requested": true
  },
  "resolution": {
    "competition_id": {
      "requested_id": "cmp_1",
      "canonical_id": "cmp_1",
      "status": "canonical",
      "decision_id": null,
      "decided_at": null
    }
  }
}
```
