Stable objects beneath moving prices.
Provider records are normalized into canonical OddsLoom entities. High-frequency quotes reference these objects by ID instead of repeating descriptive data on every update.
Relationship map
Participants attach to events and outcomes. Books own quotes; they do not own the canonical market definition.
Participant
A participant can represent a team, player, pairing, or field entry. This keeps team sports ergonomic without forcing every sport into a home-versus-away model.
{
"id": "participant_nba_min",
"type": "team",
"name": "Minnesota Timberwolves",
"abbreviation": "MIN",
"sport_id": "sport_basketball",
"league_id": "league_nba"
}idstringStable OddsLoom participant ID.typeenumteam, player, pairing, or field.namestringCanonical display name.abbreviationstring?Common short label when applicable.sport_idstringParent sport reference.league_idstring?Primary league reference when applicable.Event
The scheduled or active contest. Roles belong to the event relationship, not the participant, because the same team can be home in one event and away in another.
{
"id": "event_nba_20260808_min_den",
"sport_id": "sport_basketball",
"league_id": "league_nba",
"name": "Minnesota Timberwolves at Denver Nuggets",
"starts_at": "2026-08-08T00:10:00Z",
"phase": "pregame",
"status": "scheduled",
"participants": [
{ "participant_id": "participant_nba_min", "role": "away" },
{ "participant_id": "participant_nba_den", "role": "home" }
]
}idstringStable OddsLoom event ID.sport_idstringCanonical sport reference.league_idstringCanonical league reference.starts_atRFC 3339Current scheduled start.phaseenumpregame, live, or complete.statusenumscheduled, delayed, active, suspended, final, postponed, or cancelled.participantsarrayParticipant IDs and event-specific roles.Market and outcome
A market defines the proposition being priced. Outcomes define its canonical sides. A sportsbook changing price or line does not create a new event object.
{
"id": "market_evt_min_den_full_game_spread",
"event_id": "event_nba_20260808_min_den",
"type": "spread",
"period": "full_game",
"status": "open",
"outcomes": [
{ "id": "outcome_min", "participant_id": "participant_nba_min" },
{ "id": "outcome_den", "participant_id": "participant_nba_den" }
]
}idstringCanonical market ID.event_idstringEvent being priced.typeenumInitial families include moneyline, spread, and total.periodenumCanonical contest segment such as full_game or first_half.statusenumopen, suspended, or closed.outcomesarrayCanonical sides eligible for quotes.Quote
The quote is the mutable edge: one book’s current offer for one outcome in one jurisdiction. Each upsert carries the full replacement state.
{
"id": "quote_book_a_market_123_outcome_min",
"event_id": "event_nba_20260808_min_den",
"market_id": "market_evt_min_den_full_game_spread",
"outcome_id": "outcome_min",
"book_id": "book_a",
"jurisdiction": "US-IL",
"availability": "open",
"line": 5.5,
"price": { "american": -105, "decimal": 1.9524 },
"source_updated_at": null,
"observed_at": "2026-08-07T05:20:00.432Z"
}idstringIdentity for the book/market/outcome offer.market_idstringCanonical market reference.outcome_idstringCanonical outcome reference.book_idstringBook offering the price.jurisdictionstringRegion from which the offer was observed.availabilityenumopen, suspended, or closed.linenumber?Handicap or total where applicable.priceobjectEquivalent American and decimal forms.source_updated_atRFC 3339?Provider time when supplied.observed_atRFC 3339Time OddsLoom observed the source state.Identity rules still to settle
- Whether postponed events retain IDs after substantial rescheduling
- How participant mergers, renames, and corrections are communicated
- How alternate lines affect market identity versus quote identity
- Whether provider-native IDs are exposed as optional provenance