Data & Integration
Streaming payloads
Live-state, game, event and quote document fields delivered over WebSocket.
Every update is an event frame with type, id, channel, data, and ts.
The outer ts is the gateway’s send timestamp. Source/observation timestamps
inside data describe data freshness. Optional fields depend on the producer
and the age of the stored record; preserve explicit numeric zero and distinguish
it from missing/null data. Additional source fields can appear.
Keys are recursively converted to snake_case, including nested arrays and
objects. Storage _id becomes id; _prov is removed. This conversion does
not apply the REST endpoint’s projection, joins, source filtering, asset URL
resolution, or live-status normalization. Subscribe to the channels described
in WebSocket Streaming.
Game and match documents
Section titled “Game and match documents”Per-game channels can contain either a canonical game/match document or a shared
live-state document. Identify the payload before updating your state: live-state
documents carry fixture_id and state; canonical game/match documents use
their sport’s fields such as canonical_id/id, home_team_id,
away_team_id, status, and scheduled date/time. Use the sport’s REST reference
for the canonical entity’s field meanings, while accounting for the streaming
projection differences above.
Canonical game/match changes go to the per-entity channel for all statuses.
The broad .games.live/.matches.live channel receives those changes only
when the stored status is live, Live, In Progress, or in_progress.
Shared live-state changes go to the per-game channel for all states, and to
.games.live only for live or intermission. Fetch the per-game REST resource
to confirm a final score; subscribing only to a league’s live channel can miss
the terminal transition.
Shared live-state documents
Section titled “Shared live-state documents”These use the raw source-state vocabulary and clock labels, unlike REST’s
normalized status_code, status_label, and period_label.
| Field | Type and meaning |
|---|---|
id, fixture_id |
Strings identifying the fixture. Use the channel/league context when matching IDs. |
league_id |
League ID. |
state |
State string: scheduled, prematch, live, intermission, finished, postponed, cancelled, delayed, or unknown. |
score |
Object with numeric home and away; optional periods array with period, home, away per period. |
clock |
Object with raw string period, optional integer minute/second, string display, boolean is_running. Fields can be absent. |
sport_extra |
Source/sport-specific object, such as baseball count/base state, basketball team fouls, or soccer match detail. Keys inside it are also snake_case. |
is_overtime |
Boolean indicating overtime/extra play when reported. |
live_progress_ordinal, live_progress_key |
Numeric ordering value and string progress key used for accepted live observations; not replay cursors. |
state_revision |
Integer revision of the accepted fixture state. |
schema_version |
Numeric live-state document schema version. |
selected_source_id, selected_source_tier |
Source selection context for the accepted state. |
fallback_active, is_degraded_source |
Whether fallback or degraded source selection is active. |
source_observed_at, first_observed_at |
Source observation and first persisted observation timestamps. |
last_accepted_at, last_accepted_source_observed_at, updated_at |
Acceptance, accepted-source observation, and record-update timestamps. |
score_signature |
Optional score-change detection string; not an event/replay cursor. |
terminal_status, terminal_reason |
Optional terminal-state classification and supporting reason. |
terminal_first_seen_at, terminal_last_seen_at, terminal_confirmed_at, terminal_reverted_at |
Timestamps tracking terminal evidence, confirmation or reversion. |
terminal_observed_count |
Integer count of terminal observations. |
settled_from, settled_at_utc |
Optional reconciliation origin and timestamp when a live row was settled from canonical data. |
Timestamp fields, when present, are UTC ISO 8601 strings. state_revision is
scoped to a fixture. Do not compare it with the outer event ID or revisions
for another fixture. Raw stream updates do not receive REST’s freshness guard;
use observation timestamps to detect stale feeds.
Current quote documents
Section titled “Current quote documents”The shared current-odds feed emits one selection quote per document, not a
complete market or REST odds snapshot. A fixture-family quote goes to
{league}.odds.live and {league}.games.{fixture_id}.odds. Other market families
go to {league}.props.live and the same per-game odds channel. The shared feed
does not additionally emit a player-specific props channel; those channels
come from legacy per-league prop snapshots.
| Field | Type and meaning |
|---|---|
id, quote_key |
Stable quote-row identity. Use this for upserts rather than treating every event as a new quote. |
fixture_id, league_id, sport_id |
Fixture, league and sport context. |
bookmaker_id |
Bookmaker that owns the price. Plan visibility applies before delivery. |
source_id, selected_source_id, selected_source_tier |
Producer/source-selection identifiers and selected tier. |
fallback_active, is_degraded_source |
Booleans describing fallback/degraded source selection. |
feed_type, is_live |
Feed classification and whether the quote is live/in-play. |
market_family, market_key, period, base_market_key |
Market identity and period. Keep these together when grouping selections. |
participant_type, participant_id |
Participant classification and optional player/team identity for participant markets. |
selection_key, selection_name |
Selection identity and display name. |
line |
Optional numeric handicap/total/prop threshold. |
price_decimal, price_american |
Optional numeric prices in their explicitly named formats. There is no WebSocket format option. |
status, is_suspended |
Quote status string and suspension boolean. A missing event does not imply an available quote. |
withdrawn_at, withdrawal_reason |
Optional withdrawal timestamp and reason on withdrawn quotes; active updates can remove them. |
first_observed_at, last_observed_at |
First and most recent accepted observations of this quote. |
last_changed_at |
Most recent quote-content change; repeated observations can advance last_observed_at without advancing this value. |
source_observed_at, ingested_at, normalized_at, updated_at |
Source, ingestion, normalization and persistence timestamps. |
quote_hash, raw_snapshot_id |
Quote-content hash and originating raw-snapshot identifier, when provided. |
parser_version, schema_version |
Parser identifier and numeric document schema version. |
mapping_confidence, mapping_method |
Numeric mapping confidence and method string for the fixture/market mapping. |
{ "type": "event", "id": "evt_CONNECTION_42", "channel": "mlb.games.gam_example.odds", "data": { "quote_key": "quote_example", "fixture_id": "gam_example", "league_id": "mlb", "bookmaker_id": "bet365", "market_family": "fixture", "market_key": "moneyline", "selection_key": "home", "price_decimal": 1.91, "price_american": -110, "is_suspended": false, "last_observed_at": "2026-10-13T00:00:00Z" }, "ts": "2026-10-13T00:00:00Z"}This illustrates selected fields, not a complete market or mandatory-field list. A consumer combining quotes should key by quote identity and preserve bookmaker, period, participant and line distinctions. Refetch the REST odds resource when recovering from missed events.
Legacy snapshots and soccer events
Section titled “Legacy snapshots and soccer events”Per-league fixture-odds and prop snapshots carry their stored snapshot fields,
converted to snake_case. They can therefore have a different shape from the
shared selection-quote document above. Player-specific prop channels are fed
by legacy snapshots carrying player_id; do not expect all shared prop quotes
to reach them.
Watched soccer .events.{match_id} channels carry the changed match-event
document, including match_id and available event/player/team/clock fields.
They carry neither the full REST event list nor an entire game’s play-by-play
response. Match-event fields depend on the source; use the soccer event
reference for their meanings and refresh the REST event list during recovery.