> ## Documentation Index
> Fetch the complete documentation index at: https://docs.therundown.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Events

> Get events with market-based odds, opening and closing snapshots, best lines, and delta feeds

## Overview

The V2 events endpoints return events with a **market-based data model** where odds are organized by market (moneyline, spread, total, player props, etc.), each containing participants with lines and prices per sportsbook.

<Note>
  The `market_ids` parameter defaults to `1,2,3` (Moneyline, Spread, Total) if not specified — `1,2,3,563` for soccer leagues and NHL. To get player props or other markets, you must explicitly request them.
</Note>

Opening and closing endpoints return **snapshots**, while [market history](/api-reference/v2/markets#endpoints) returns recorded price changes. Historical access and its available lookback depend on your plan.

<Info>
  For a detailed breakdown of how events, markets, participants, lines, and prices relate, see the [Data Model](/reference/data-model). For delta-based polling strategies, see the [Efficient Polling guide](/guides/efficient-polling).
</Info>

<Note>
  For V2 endpoints, use the `event_id` returned in event payloads as the canonical identifier for path parameters, WebSocket filters, and local cache keys. The payload's `event_uuid` field is compatibility-only and may differ from `event_id`.
</Note>

<Note>
  For MLB doubleheaders and makeup games, the nested `schedule` object includes `game_number` (`1` or `2` for a true doubleheader) and `game_type` (`doubleheader`, `makeup`, or `doubleheader_makeup`). Both fields are omitted for ordinary games, so no headline parsing is required.
</Note>

## Key Parameters

These parameters are shared across most event endpoints:

| Parameter | Type | Default | Description |
| - | - | - | - |
| `market_ids` | query | `1,2,3` | Comma-separated market IDs, **max 12 per request** (more returns a `400`). `1`=Moneyline, `2`=Spread, `3`=Total. Soccer leagues and NHL default to `1,2,3,563`. See [Market IDs](/reference/markets) for the full list. |
| `affiliate_ids` | query | all | Comma-separated sportsbook IDs to include. E.g., `19,23` for DraftKings and FanDuel. On these event endpoints, `0` is a scores-only sentinel: the response keeps events, scores, and status and omits markets and price objects. |
| `offset` | query | `0` | UTC offset in **minutes** for the date boundary. Use `300` for US Central Time, `240` for Eastern, `360` for Mountain, `420` for Pacific. Without this, the API day boundary is midnight UTC. |
| `event_status` | query | none | Comma-separated event statuses to **include** (e.g., `STATUS_IN_PROGRESS,STATUS_HALFTIME`). Applied before `exclude_status`. |
| `exclude_status` | query | none | Comma-separated event statuses to exclude (e.g., `STATUS_FINAL`). |
| `main_line` | query | `false` | Set to `true` to return only the main/consensus line for spreads and totals. |
| `participant_ids` | query | none | Comma-separated participant IDs to filter by (max 99). Filter on the stable `participant.id` — see the [Participant object](/reference/data-model#participant-object) reference. Useful for player props. |
| `participant_type` | query | none | Filter by participant type: `TYPE_TEAM`, `TYPE_PLAYER`, or `TYPE_RESULT`. |
| `hide_no_markets` | query | `false` | Set to `true` to exclude events that have no market data. |

***

## Endpoints

<Accordion title="GET /api/v2/sports/{sportID}/events/{date} — Events by sport and date">
  The primary endpoint for building odds screens. Returns all events for a sport on a given date, with full market/odds data.

  ### Path Parameters

  | Parameter | Description |
  | - | - |
  | `sportID` | Sport ID (e.g., `4` for NBA) |
  | `date` | Date in `YYYY-MM-DD` format |

  <CodeGroup>
    ```bash cURL theme={null}
    curl -H "X-TheRundown-Key: $THERUNDOWN_API_KEY" "https://therundown.io/api/v2/sports/4/events/2026-02-26?market_ids=1,2,3&offset=300"
    ```

    ```bash DraftKings + FanDuel only theme={null}
    curl -H "X-TheRundown-Key: $THERUNDOWN_API_KEY" "https://therundown.io/api/v2/sports/4/events/2026-02-26?market_ids=1,2,3&affiliate_ids=19,23&offset=300"
    ```

    ```bash Player props theme={null}
    curl -H "X-TheRundown-Key: $THERUNDOWN_API_KEY" "https://therundown.io/api/v2/sports/4/events/2026-02-26?market_ids=29,35,39&offset=300"
    ```

    ```python Python theme={null}
    import os
    import requests
    from datetime import date

    response = requests.get(
        f"https://therundown.io/api/v2/sports/4/events/{date.today()}",
        headers={"X-TheRundown-Key": os.environ["THERUNDOWN_API_KEY"]},
        params={"market_ids": "1,2,3", "offset": "300"}
    )

    for event in response.json()["events"]:
        teams = event["teams"]
        print(f"{teams[0]['name']} @ {teams[1]['name']}")
    ```

    ```javascript Node.js 22+ (server) theme={null}
    const API_KEY = process.env.THERUNDOWN_API_KEY;
    if (!API_KEY) throw new Error("Set THERUNDOWN_API_KEY in the Node.js server environment");
    const today = new Date().toISOString().split("T")[0];
    const resp = await fetch(
      `https://therundown.io/api/v2/sports/4/events/${today}?market_ids=1,2,3&offset=300`,
      { headers: { "X-TheRundown-Key": API_KEY } }
    );
    const data = await resp.json();

    data.events.forEach((event) => {
      console.log(`${event.teams[0].name} @ ${event.teams[1].name}`);
    });
    ```
  </CodeGroup>

  ### Example Response

  ```json theme={null}
  {
    "meta": {
      "delta_last_id": "7f2a1b3c-4d5e-6f7a-8b9c-0d1e2f3a4b5c"
    },
    "events": [
      {
        "event_id": "401584701-d1f2-43e7-b5a6-9c8d7e6f5a4b",
        "sport_id": 4,
        "event_uuid": "11f1-197d-e93ea800-8c2a-ef6a554ca62d",
        "event_date": "2026-02-27T00:30:00Z",
        "rotation_number_away": 501,
        "rotation_number_home": 502,
        "score": {
          "event_id": "401584701-d1f2-43e7-b5a6-9c8d7e6f5a4b",
          "event_status": "STATUS_SCHEDULED",
          "score_away": 0,
          "score_home": 0,
          "winner_away": 0,
          "winner_home": 0,
          "score_away_by_period": [],
          "score_home_by_period": [],
          "venue_name": "Madison Square Garden",
          "venue_location": "New York, NY",
          "game_clock": 0,
          "display_clock": "0:00",
          "game_period": 0,
          "broadcast": "ESPN",
          "event_status_detail": "7:30 PM ET",
          "updated_at": "2026-02-26T12:00:00Z"
        },
        "teams": [
          {
            "team_id": 51,
            "name": "Cleveland Cavaliers",
            "mascot": "Cavaliers",
            "abbreviation": "CLE",
            "record": "42-14",
            "is_away": true,
            "is_home": false
          },
          {
            "team_id": 56,
            "name": "New York Knicks",
            "mascot": "Knicks",
            "abbreviation": "NYK",
            "record": "35-21",
            "is_away": false,
            "is_home": true
          }
        ],
        "schedule": {
          "season_type": "Regular Season",
          "season_year": 2026,
          "event_name": "Cleveland Cavaliers at New York Knicks",
          "league_name": "NBA"
        },
        "markets": [
          {
            "id": 28401,
            "market_id": 1,
            "period_id": 0,
            "name": "Moneyline",
            "market_description": "Pick the winner of the game",
            "participants": [
              {
                "id": 51,
                "type": "TYPE_TEAM",
                "name": "Cleveland Cavaliers",
                "lines": [
                  {
                    "id": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
                    "value": "",
                    "prices": {
                      "19": { "id": "194920001", "price": -145, "is_main_line": true, "updated_at": "2026-02-26T16:30:00Z" }
                    }
                  }
                ]
              },
              {
                "id": 56,
                "type": "TYPE_TEAM",
                "name": "New York Knicks",
                "lines": [
                  {
                    "id": "b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7",
                    "value": "",
                    "prices": {
                      "19": { "id": "194920002", "price": 122, "is_main_line": true, "updated_at": "2026-02-26T16:30:00Z" }
                    }
                  }
                ]
              }
            ]
          },
          {
            "id": 28402,
            "market_id": 2,
            "period_id": 0,
            "name": "handicap",
            "market_description": "Spread: Win or lose by margin of points",
            "participants": [
              {
                "id": 51,
                "type": "TYPE_TEAM",
                "name": "Cleveland Cavaliers",
                "lines": [
                  {
                    "id": "c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8",
                    "value": "-3.5",
                    "prices": {
                      "19": { "id": "194920003", "price": -110, "is_main_line": true, "updated_at": "2026-02-26T16:30:00Z" }
                    }
                  }
                ]
              },
              {
                "id": 56,
                "type": "TYPE_TEAM",
                "name": "New York Knicks",
                "lines": [
                  {
                    "id": "d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9",
                    "value": "3.5",
                    "prices": {
                      "19": { "id": "194920004", "price": -110, "is_main_line": true, "updated_at": "2026-02-26T16:30:00Z" }
                    }
                  }
                ]
              }
            ]
          },
          {
            "id": 28403,
            "market_id": 3,
            "period_id": 0,
            "name": "Total Over/Under",
            "market_description": "Combined score of both teams",
            "participants": [
              {
                "id": 0,
                "type": "TYPE_RESULT",
                "name": "Over",
                "lines": [
                  {
                    "id": "e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0",
                    "value": "224.5",
                    "prices": {
                      "19": { "id": "194920005", "price": -110, "is_main_line": true, "updated_at": "2026-02-26T16:30:00Z" }
                    }
                  }
                ]
              },
              {
                "id": 1,
                "type": "TYPE_RESULT",
                "name": "Under",
                "lines": [
                  {
                    "id": "f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1",
                    "value": "224.5",
                    "prices": {
                      "19": { "id": "194920006", "price": -110, "is_main_line": true, "updated_at": "2026-02-26T16:30:00Z" }
                    }
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  }
  ```
</Accordion>

<Accordion title="GET /api/v2/events/{eventID} — Single event">
  Returns a single event with full market data. Use when you already have an event ID and need its current odds.

  ### Path Parameters

  | Parameter | Description |
  | - | - |
  | `eventID` | Canonical V2 event ID from the `event_id` field |

  <Note>
    Pass `event_id`, not `event_uuid`, to `GET /api/v2/events/{eventID}` and other per-event V2 endpoints.
  </Note>

  <CodeGroup>
    ```bash cURL theme={null}
    curl -H "X-TheRundown-Key: $THERUNDOWN_API_KEY" "https://therundown.io/api/v2/events/EVENT_ID?market_ids=1,2,3"
    ```

    ```bash All markets with main lines only theme={null}
    curl -H "X-TheRundown-Key: $THERUNDOWN_API_KEY" "https://therundown.io/api/v2/events/EVENT_ID?market_ids=1,2,3,94&main_line=true"
    ```

    ```python Python theme={null}
    import os
    import requests

    resp = requests.get(
        "https://therundown.io/api/v2/events/EVENT_ID",
        headers={"X-TheRundown-Key": os.environ["THERUNDOWN_API_KEY"]},
        params={"market_ids": "1,2,3"}
    )
    event = resp.json()["events"][0]
    print(f"{event['teams'][0]['name']} vs {event['teams'][1]['name']}")
    ```

    ```javascript Node.js 22+ (server) theme={null}
    const API_KEY = process.env.THERUNDOWN_API_KEY;
    if (!API_KEY) throw new Error("Set THERUNDOWN_API_KEY in the Node.js server environment");
    const resp = await fetch(
      "https://therundown.io/api/v2/events/EVENT_ID?market_ids=1,2,3",
      { headers: { "X-TheRundown-Key": API_KEY } }
    );
    const data = await resp.json();
    const event = data.events[0];
    console.log(`${event.teams[0].name} vs ${event.teams[1].name}`);
    ```
  </CodeGroup>

  ### Example Response

  ```json theme={null}
  {
    "meta": {
      "delta_last_id": "8a3b2c1d-5e4f-6a7b-8c9d-0e1f2a3b4c5d"
    },
    "events": [
      {
        "event_id": "401584701-d1f2-43e7-b5a6-9c8d7e6f5a4b",
        "sport_id": 4,
        "event_uuid": "11f1-197d-e93ea800-8c2a-ef6a554ca62d",
        "event_date": "2026-02-27T00:30:00Z",
        "score": {
          "event_id": "401584701-d1f2-43e7-b5a6-9c8d7e6f5a4b",
          "event_status": "STATUS_IN_PROGRESS",
          "score_away": 62,
          "score_home": 55,
          "score_away_by_period": [28, 18, 16],
          "score_home_by_period": [24, 19, 12],
          "game_period": 3,
          "display_clock": "4:32",
          "broadcast": "ESPN",
          "event_status_detail": "3rd Quarter - 4:32",
          "updated_at": "2026-02-27T01:45:00Z"
        },
        "teams": [
          { "team_id": 51, "name": "Cleveland Cavaliers", "abbreviation": "CLE", "is_away": true, "is_home": false },
          { "team_id": 56, "name": "New York Knicks", "abbreviation": "NYK", "is_away": false, "is_home": true }
        ],
        "schedule": {
          "season_type": "Regular Season",
          "season_year": 2026,
          "event_name": "Cleveland Cavaliers at New York Knicks"
        },
        "markets": [
          {
            "id": 28401,
            "market_id": 1,
            "period_id": 0,
            "name": "Moneyline",
            "market_description": "Pick the winner of the game",
            "participants": [
              {
                "id": 51,
                "type": "TYPE_TEAM",
                "name": "Cleveland Cavaliers",
                "lines": [
                  {
                    "id": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
                    "value": "",
                    "prices": {
                      "19": { "id": "194930001", "price": -220, "is_main_line": true, "updated_at": "2026-02-27T01:42:00Z" }
                    }
                  }
                ]
              },
              {
                "id": 56,
                "type": "TYPE_TEAM",
                "name": "New York Knicks",
                "lines": [
                  {
                    "id": "b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7",
                    "value": "",
                    "prices": {
                      "19": { "id": "194930002", "price": 180, "is_main_line": true, "updated_at": "2026-02-27T01:42:00Z" }
                    }
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  }
  ```

  <Note>
    **`participant.id` is the stable join key — join on `id`, not `name`.** What `id` points to depends on `participant.type`:

    * **`TYPE_TEAM`** — `id` is the normalized team ID, stable across seasons, and matches `event.teams[].team_id`. Full record at `GET /api/v2/teams/{team_id}`.
    * **`TYPE_PLAYER`** — `id` is the player ID. Full record (team, names, position) at `GET /api/v2/players/{player_id}`.
    * **`TYPE_RESULT`** — `id` is a small outcome index (e.g. `0`/`1` for Over/Under), not a team or player resource key.

    Joining on `id` resolves shared-name collisions. To filter the response server-side, pass `participant_ids` (comma-separated, max 99) with `participant_type` set to `TYPE_TEAM`, `TYPE_PLAYER`, or `TYPE_RESULT`. To resolve a name to an `id` once, use `GET /api/v2/teams/{team_id}/players` or `GET /api/v2/sports/{sportID}/teams`. See the [Participant object](/reference/data-model#participant-object) reference for full definitions.
  </Note>

  <Note>
    Live score metadata is best-effort. Fields such as `venue_name` and `venue_location` may be empty strings even when `event_status` is `STATUS_IN_PROGRESS`.
  </Note>
</Accordion>

<Accordion title="GET /api/v2/events/{eventID}/openers — Opening prices">
  Returns the earliest recorded price for each available line at each sportsbook. An opening snapshot is available before, during, or after the event when a price has been recorded.

  The response uses the standard `events` envelope array, even for one event ID. `market_ids` defaults to `1,2,3` (`1,2,3,563` for soccer and NHL), accepts at most 12 IDs, and respects your sportsbook access. `main_line=true` selects main lines in the snapshot. Use history to follow which line was main at each timestamp. Set `hide_closed=true` only when you want to exclude currently closed lines.

  <CodeGroup>
    ```bash cURL theme={null}
    curl -H "X-TheRundown-Key: $THERUNDOWN_API_KEY" "https://therundown.io/api/v2/events/EVENT_ID/openers?market_ids=1,2,3"
    ```

    ```bash Hide closed lines theme={null}
    curl -H "X-TheRundown-Key: $THERUNDOWN_API_KEY" "https://therundown.io/api/v2/events/EVENT_ID/openers?market_ids=1,2,3&hide_closed=true"
    ```

    ```python Python theme={null}
    import os
    import requests

    resp = requests.get(
        "https://therundown.io/api/v2/events/EVENT_ID/openers",
        headers={"X-TheRundown-Key": os.environ["THERUNDOWN_API_KEY"]},
        params={"market_ids": "1,2,3"}
    )
    openers = resp.json()
    print(openers["events"][0]["markets"])
    ```

    ```javascript Node.js 22+ (server) theme={null}
    const API_KEY = process.env.THERUNDOWN_API_KEY;
    if (!API_KEY) throw new Error("Set THERUNDOWN_API_KEY in the Node.js server environment");
    const resp = await fetch(
      "https://therundown.io/api/v2/events/EVENT_ID/openers?market_ids=1,2,3",
      { headers: { "X-TheRundown-Key": API_KEY } }
    );
    const data = await resp.json();
    console.log(data.events[0].markets);
    ```
  </CodeGroup>

  ### Example Response

  The response uses the same event structure as `GET /api/v2/events/{eventID}`, with prices reflecting the first recorded lines from each sportsbook.

  ```json theme={null}
  {
    "meta": {},
    "events": [{
      "event_id": "401584701-d1f2-43e7-b5a6-9c8d7e6f5a4b",
      "sport_id": 4,
      "markets": [
        {
          "id": 28401,
          "market_id": 1,
          "period_id": 0,
          "name": "Moneyline",
          "market_description": "Pick the winner of the game",
          "participants": [
            {
              "id": 51,
              "type": "TYPE_TEAM",
              "name": "Cleveland Cavaliers",
              "lines": [
                {
                  "id": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
                  "value": "",
                  "prices": {
                    "19": { "id": "194910001", "price": -130, "is_main_line": true, "updated_at": "2026-02-24T14:00:00Z" }
                  }
                }
              ]
            },
            {
              "id": 56,
              "type": "TYPE_TEAM",
              "name": "New York Knicks",
              "lines": [
                {
                  "id": "b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7",
                  "value": "",
                  "prices": {
                    "19": { "id": "194910002", "price": 110, "is_main_line": true, "updated_at": "2026-02-24T14:00:00Z" }
                  }
                }
              ]
            }
          ]
        }
      ]
    }]
  }
  ```
</Accordion>

<Accordion title="GET /api/v2/events/{eventID}/closing — Closing prices">
  Returns the latest recorded price at or before the scheduled event start. Before that time, the snapshot is provisional. Period markets use the event start time as their closing cutoff.

  The response uses the standard `events` envelope array, even for one event ID. `market_ids` defaults to `1,2,3` (`1,2,3,563` for soccer and NHL), accepts at most 12 IDs, and respects your sportsbook access. `main_line=true` selects main lines in the snapshot. Use history to follow which line was main at each timestamp. Omit `hide_closed` (or use `false`) to retrieve a completed historical snapshot.

  <CodeGroup>
    ```bash cURL theme={null}
    curl -H "X-TheRundown-Key: $THERUNDOWN_API_KEY" "https://therundown.io/api/v2/events/EVENT_ID/closing?market_ids=1,2,3"
    ```

    ```python Python theme={null}
    import os
    import requests

    resp = requests.get(
        "https://therundown.io/api/v2/events/EVENT_ID/closing",
        headers={"X-TheRundown-Key": os.environ["THERUNDOWN_API_KEY"]},
        params={"market_ids": "1,2,3"}
    )
    closing = resp.json()
    print(closing["events"][0]["markets"])
    ```

    ```javascript Node.js 22+ (server) theme={null}
    const API_KEY = process.env.THERUNDOWN_API_KEY;
    if (!API_KEY) throw new Error("Set THERUNDOWN_API_KEY in the Node.js server environment");
    const resp = await fetch(
      "https://therundown.io/api/v2/events/EVENT_ID/closing?market_ids=1,2,3",
      { headers: { "X-TheRundown-Key": API_KEY } }
    );
    const data = await resp.json();
    console.log(data.events[0].markets);
    ```
  </CodeGroup>

  ### Example Response

  Same event envelope as openers, with prices reflecting the latest recorded lines at or before event start.

  ```json theme={null}
  {
    "meta": {},
    "events": [{
      "event_id": "401584701-d1f2-43e7-b5a6-9c8d7e6f5a4b",
      "sport_id": 4,
      "markets": [
        {
          "id": 28402,
          "market_id": 2,
          "period_id": 0,
          "name": "handicap",
          "market_description": "Spread: Win or lose by margin of points",
          "participants": [
            {
              "id": 51,
              "type": "TYPE_TEAM",
              "name": "Cleveland Cavaliers",
              "lines": [
                {
                  "id": "c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8",
                  "value": "-4.5",
                  "prices": {
                    "19": { "id": "194940001", "price": -108, "is_main_line": true, "updated_at": "2026-02-27T00:28:00Z" }
                  }
                }
              ]
            },
            {
              "id": 56,
              "type": "TYPE_TEAM",
              "name": "New York Knicks",
              "lines": [
                {
                  "id": "d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9",
                  "value": "4.5",
                  "prices": {
                    "19": { "id": "194940002", "price": -112, "is_main_line": true, "updated_at": "2026-02-27T00:28:00Z" }
                  }
                }
              ]
            }
          ]
        }
      ]
    }]
  }
  ```
</Accordion>

<Accordion title="GET /api/v2/events/{eventID}/best-line — Best available line">
  Returns the best moneyline, spread, and total across all tracked sportsbooks for an event. Compares prices across books and returns the most favorable line for each side.

  ### Additional Parameters

  | Parameter | Default | Description |
  | - | - | - |
  | `period` | `period_full_game` | Period to get best line for. Options: `period_full_game`, `period_first_half`, `period_second_half`, `period_first_period` through `period_fourth_period`, plus live equivalents. |

  <CodeGroup>
    ```bash Full game best line theme={null}
    curl -H "X-TheRundown-Key: $THERUNDOWN_API_KEY" "https://therundown.io/api/v2/events/EVENT_ID/best-line"
    ```

    ```bash First half best line theme={null}
    curl -H "X-TheRundown-Key: $THERUNDOWN_API_KEY" "https://therundown.io/api/v2/events/EVENT_ID/best-line?period=period_first_half"
    ```

    ```bash Best line from specific books theme={null}
    curl -H "X-TheRundown-Key: $THERUNDOWN_API_KEY" "https://therundown.io/api/v2/events/EVENT_ID/best-line?affiliate_ids=19,23,22"
    ```

    ```python Python theme={null}
    import os
    import requests

    resp = requests.get(
        "https://therundown.io/api/v2/events/EVENT_ID/best-line",
        headers={"X-TheRundown-Key": os.environ["THERUNDOWN_API_KEY"]},
    )
    best = resp.json()["best_lines"]
    print(f"Best ML away: {best['moneyline']['away']['price']}")
    ```

    ```javascript Node.js 22+ (server) theme={null}
    const API_KEY = process.env.THERUNDOWN_API_KEY;
    if (!API_KEY) throw new Error("Set THERUNDOWN_API_KEY in the Node.js server environment");
    const resp = await fetch(
      "https://therundown.io/api/v2/events/EVENT_ID/best-line",
      { headers: { "X-TheRundown-Key": API_KEY } }
    );
    const data = await resp.json();
    console.log("Best ML away:", data.best_lines.moneyline.away.price);
    ```
  </CodeGroup>

  ### Example Response

  ```json theme={null}
  {
    "event_id": "401584701-d1f2-43e7-b5a6-9c8d7e6f5a4b",
    "sport_id": 4,
    "best_lines": {
      "moneyline": {
        "away": { "price": -140, "affiliate_id": 23, "affiliate_name": "FanDuel" },
        "home": { "price": 125, "affiliate_id": 22, "affiliate_name": "BetMGM" }
      },
      "spread": {
        "away": { "value": "-3.5", "price": -105, "affiliate_id": 22, "affiliate_name": "BetMGM" },
        "home": { "value": "3.5", "price": -108, "affiliate_id": 23, "affiliate_name": "FanDuel" }
      },
      "total": {
        "over": { "value": "224.5", "price": -108, "affiliate_id": 19, "affiliate_name": "DraftKings" },
        "under": { "value": "224.5", "price": -105, "affiliate_id": 22, "affiliate_name": "BetMGM" }
      }
    }
  }
  ```
</Accordion>

<Accordion title="GET /api/v2/delta — Event delta feed">
  Returns events that have changed since your last request, identified by a cursor (`last_id`). Use this for efficient polling instead of re-fetching all events.

  ### Parameters

  | Parameter | Type | Required | Description |
  | - | - | - | - |
  | `last_id` | query | Yes | 36-character UUID cursor. Use empty string for initial fetch, then pass the `delta_last_id` from the previous response. |
  | `sport_id` | query | No | Filter by sport ID |
  | `affiliate_ids` | query | No | Comma-separated sportsbook IDs |

  <Warning>
    Each delta payload contains the **full event update** as a JSON string. Parse the `json` field within each delta item to get the event data.
  </Warning>

  <CodeGroup>
    ```bash Initial fetch theme={null}
    curl -H "X-TheRundown-Key: $THERUNDOWN_API_KEY" "https://therundown.io/api/v2/delta?last_id=00000000-0000-0000-0000-000000000000&sport_id=4"
    ```

    ```bash Subsequent poll (use delta_last_id from previous response) theme={null}
    curl -H "X-TheRundown-Key: $THERUNDOWN_API_KEY" "https://therundown.io/api/v2/delta?last_id=PREVIOUS_DELTA_LAST_ID&sport_id=4"
    ```

    ```python Python — Delta polling loop theme={null}
    import os
    import requests
    import time

    API_KEY = os.environ["THERUNDOWN_API_KEY"]
    BASE = "https://therundown.io/api/v2"
    last_id = "00000000-0000-0000-0000-000000000000"

    while True:
        resp = requests.get(
            f"{BASE}/delta",
            headers={"X-TheRundown-Key": API_KEY},
            params={"last_id": last_id, "sport_id": 4}
        )
        data = resp.json()

        for delta in data.get("deltas", []):
            print(f"Event changed: {delta['event_id']}")

        last_id = data.get("delta_last_id", last_id)
        time.sleep(5)
    ```

    ```javascript Node.js 22+ (server) theme={null}
    const API_KEY = process.env.THERUNDOWN_API_KEY;
    if (!API_KEY) throw new Error("Set THERUNDOWN_API_KEY in the Node.js server environment");
    let lastId = "00000000-0000-0000-0000-000000000000";
    const resp = await fetch(
      `https://therundown.io/api/v2/delta?last_id=${lastId}&sport_id=4`,
      { headers: { "X-TheRundown-Key": API_KEY } }
    );
    const data = await resp.json();

    data.deltas.forEach((d) => console.log("Changed:", d.event_id));
    lastId = data.meta.delta_last_id;
    ```
  </CodeGroup>

  ### Example Response

  Each delta entry's `data` field is a **serialized JSON string** containing the full event update. Parse it to get the event object.

  ```json theme={null}
  {
    "meta": {
      "delta_last_id": "9e8f7d6c-5b4a-3210-fedc-ba9876543210"
    },
    "deltas": [
      {
        "data": "{\"event_id\":\"401584701-d1f2-43e7-b5a6-9c8d7e6f5a4b\",\"sport_id\":4,\"event_status\":\"STATUS_IN_PROGRESS\",\"score\":{\"score_away\":62,\"score_home\":55,\"game_period\":3},\"teams\":[{\"team_id\":51,\"name\":\"Cleveland Cavaliers\"},{\"team_id\":56,\"name\":\"New York Knicks\"}],\"markets\":[...]}"
      },
      {
        "data": "{\"event_id\":\"401584702-a3b4-56c7-d8e9-0f1a2b3c4d5e\",\"sport_id\":4,\"event_status\":\"STATUS_SCHEDULED\",\"teams\":[{\"team_id\":50,\"name\":\"Golden State Warriors\"},{\"team_id\":55,\"name\":\"Phoenix Suns\"}],\"markets\":[...]}"
      }
    ]
  }
  ```
</Accordion>

***

## Opening & Closing Lines by Sport and Date

In addition to per-event snapshots, you can fetch opening and closing lines for all events in a sport on a date. These routes support `offset`, `event_status`, and `exclude_status` as well as the shared snapshot filters.

<CodeGroup>
  ```bash Opening lines for all NBA games on a date theme={null}
  curl -H "X-TheRundown-Key: $THERUNDOWN_API_KEY" "https://therundown.io/api/v2/sports/4/openers/2026-02-26?market_ids=1,2,3&offset=300"
  ```

  ```bash Closing lines for all NBA games on a date theme={null}
  curl -H "X-TheRundown-Key: $THERUNDOWN_API_KEY" "https://therundown.io/api/v2/sports/4/closing/2026-02-26?market_ids=1,2,3&offset=300"
  ```
</CodeGroup>

See the [opening sport/date reference](/api-reference/generated/v2-events/get-opening-lines-for-a-sport-and-date), [closing sport/date reference](/api-reference/generated/v2-events/get-closing-lines-for-a-sport-and-date), [event opening reference](/api-reference/generated/v2-events/get-opening-prices-for-an-event), and [event closing reference](/api-reference/generated/v2-events/get-closing-prices-for-an-event).

***

## Live Game State & Play-by-Play

<Note>
  Live game state and play-by-play require an **Ultra plan or higher**. Keys on lower tiers do not receive the `live_game_state` field, and requests to the plays endpoint return a `403`.
</Note>

For entitled keys, live event payloads embed a `live_game_state` snapshot with the current period, the last play, and sport-specific detail:

* **MLB** — balls, strikes, outs, base runners, current batter and pitcher
* **NFL / NCAAF** — possession, down & distance, yard line, red-zone flag, timeouts
* **NBA / WNBA / NCAAB** — possession, timeouts, bonus status
* **NHL** — possession, skater strength, power-play team, shots on goal, goalie-pulled flags
* **Soccer** — period, half indicator, and last play

```json theme={null}
"live_game_state": {
  "event_id": "816efd1e5767d7133b5bc70c77173a18",
  "sport_id": 3,
  "sport": "mlb",
  "period": 6,
  "half_indicator": "bottom",
  "updated_at": "2026-07-04T01:12:50Z",
  "mlb": {
    "balls": 1,
    "strikes": 2,
    "outs": 1,
    "on_first": { "player_id": 41123, "name": "Bobby Witt Jr.", "team_id": 20 },
    "current_pitcher": { "player_id": 38854, "name": "Tarik Skubal", "team_id": 18 }
  },
  "last_play": {
    "sequence": 214,
    "type": "single",
    "description": "Bobby Witt Jr. singles on a line drive to center field."
  }
}
```

The full play timeline is available at [`GET /api/v2/events/{eventID}/plays`](/api-reference/generated/v2-events/get-play-by-play-for-an-event) — one entry per play with description, period, game clock, running score, and (as attribution rolls out) the players involved. Responses return up to `500` plays per request; page backwards through long games with `before_sequence`. For streaming delivery, subscribe to the `plays` channel on the [V2 WebSocket](/api-reference/v2/websocket#multiplexed-websocket-channels).

Coverage spans MLB, NBA (including Summer League), WNBA, NCAAB, NFL, NCAAF, NHL, and soccer, with per-play player attribution rolling out progressively by sport.

***

## Off-the-Board Sentinel

<Warning>
  A price value of **0.0001** means the line is "off the board" -- the sportsbook has temporarily removed pricing (e.g., pending injury news). This is not an error. Display it as "OTB" or "N/A" in your UI.
</Warning>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.