V1 / Payload catalog

Every message has one job.

These v1 shapes mirror the executable delivery service and machine-readable OpenAPI and AsyncAPI contracts.

Catalog

session.authenticatedFirst-frame authentication succeeded.CONTROL
subscription.acceptedThe snapshot position and effective scope were accepted at sequence 0.CONTROL
state.snapshotComplete canonical REST state with a short-lived stream position.STATE
state.upsertFully replace a canonical reference entity.DELTA
state.removeRemove a reference entity in dependency-safe order.DELTA
odds.upsertCreate or fully replace one quote.DELTA
odds.removeExplicitly remove one quote.DELTA
source.statusReport streaming or degraded source state.CONTROL
coverage.manifestAnnounce release-gate changes before removals.CONTROL
STATE / V1

state.snapshot

The REST endpoint returns a complete graph-safe snapshot. It contains canonical markets only, the effective scope, exact release gates, source status, and the short-lived position the WebSocket subscription must declare.

{
  "schema_version": "1",
  "type": "state.snapshot",
  "sequence": 1,
  "snapshot_position": 1,
  "message_id": "550e8400-e29b-41d4-a716-446655440010",
  "emitted_at": "2026-08-12T15:20:00.120Z",
  "effective_scope": { ... },
  "coverage_manifest": [ ... ],
  "sources": [ ... ],
  "snapshot": {
    "sports": [ ... ], "leagues": [ ... ],
    "participants": [ ... ], "events": [ ... ],
    "markets": [ ... ], "outcomes": [ ... ], "quotes": [ ... ]
  }
}
schema_versionstringAlways 1 on this route.
snapshot_positionintegerMust still be current when creating the matching stream subscription.
message_idUUIDUnique message identifier.
emitted_atRFC 3339OddsLoom publication time.
snapshotobjectComplete canonical graph for the effective scope.
DELTA / V1

state.upsert

Additions and corrections replace a complete canonical entity. Upserts arrive in dependency order: sport, league, participant, event, market, outcome, then quote.

{
  "schema_version": "1", "type": "state.upsert", "sequence": 1,
  "message_id": "550e8400-e29b-41d4-a716-446655440011",
  "emitted_at": "2026-08-12T15:20:00.400Z",
  "entity_type": "event",
  "entity": { ... }
}
DELTA / V1

odds.upsert

Create or replace one quote. A suspension is an upsert with availability: suspended; a correction is a replacement at a higher sequence.

{
  "schema_version": "1", "type": "odds.upsert", "sequence": 3,
  "message_id": "550e8400-e29b-41d4-a716-446655440012",
  "emitted_at": "2026-08-12T15:20:00.438Z",
  "quote": {
    "id": "quote_01...", "eventId": "evt_01...",
    "marketId": "mkt_01...", "outcomeId": "out_01...",
    "bookId": "draftkings", "jurisdiction": "US-IL",
    "availability": "open", "line": 5.5,
    "price": { "american": -105, "decimal": 1.9524 },
    "source": { "eventId": "src_evt_01...", "marketId": "src_mkt_01...", "selectionId": "src_sel_01..." },
    "observedAt": "2026-08-12T15:20:00.432Z"
  }
}
DELTA / V1

Explicit removals

odds.remove removes a quote. state.remove uses entity_type and entity_id. Removals arrive quote-first so references never dangle.

{
  "schema_version": "1", "type": "odds.remove", "sequence": 3,
  "message_id": "550e8400-e29b-41d4-a716-446655440013",
  "emitted_at": "2026-08-12T15:20:01.014Z",
  "quote_id": "quote_01..."
}
SOURCE / V1

source.status

When a released source becomes stale or fails, OddsLoom reports it as degraded and removes its last-known quotes rather than presenting them as current.

{
  "schema_version": "1", "type": "source.status", "sequence": 4,
  "message_id": "550e8400-e29b-41d4-a716-446655440014",
  "emitted_at": "2026-08-12T15:20:15.000Z",
  "sources": [{
    "book_id": "draftkings", "jurisdiction": "US-IL",
    "phase": "live", "status": "degraded",
    "last_success_at": "2026-08-12T15:19:59.000Z"
  }]
}

Publication and observation time

The envelope’s emitted_at is when OddsLoom published the state. A quote’s observedAt is when OddsLoom observed the provider state; source-provided clocks may be absent and are not invented.

CONTINUEUnderstand reliability