DRAFT v0.3 / Entity model

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

SPORTLEAGUEEVENTMARKETOUTCOMEQUOTE

Participants attach to events and outcomes. Books own quotes; they do not own the canonical market definition.

OBJECT / PARTICIPANT

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.
OBJECT / EVENT

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.
OBJECT / MARKET

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.
OBJECT / QUOTE

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
CONTINUEReview every payload