Skip to main content
The feed covers several sports. A sport is not an address: the consumer reads — the sessions catalog, the WebSocket, the history backfill — are top-level /api endpoints addressed by session id alone, and the server resolves each session’s sport. What a sport determines is how to parse: which event vocabulary and state shape the feed speaks. The catalog row’s sport field names the family: Every sport speaks the same wire shape — the differences are only in the state fields and the event vocabulary. Read this page once for the shared mechanics, then the per-sport page for the specifics.

The snapshot

Every WebSocket frame carries a full state snapshot. On the live feed you never rebuild state from events — each snapshot is complete and already computed, so a dropped frame leaves you only one event behind, and the next frame brings you back in sync. The history backfill is the one exception: it returns events only. If you need state with no live socket (a closed game, offline analysis), replay the events — each sport page specifies every event’s exact effect on state, and applying them in order rebuilds the same snapshot the live feed would have sent. See the History backfill. All field names are camelCase on the wire.

The A/B side model

Teams are always A or B on the wire — never by name. The display names are fixed when the session is created and ride the top-level matchup { a, b } on every frame and on the /api/history and /api/health responses, not the state snapshot. Score and every team-attributed field stay on the abstract A/B sides. See Core Concepts — the A/B side model.

How to read a sport page

Each sport page is self-contained and follows the same shape:
  1. State — the fields in that sport’s snapshot.
  2. Enum values — the closed sets a field can take.
  3. Events — the vocabulary, grouped by topic. Each event lists its type, payload fields, and an example.
Events arrive on the WebSocket as frame.event. The type field is the discriminator; payload carries the event’s fields minus type.

Events shared across every sport

These behave the same in every sport, so they are documented once here. The per-sport pages cover only the events specific to that sport.
Overwrites the derived score. Scoring continues from the new values. Used to correct a drifted score; rare during normal play.
Terminal: the snapshot moves to its final state and no further frames arrive. Close the connection after receiving it. Soccer names this match_end; baseball and basketball name it game_end.No payload fields.
Retracts the most recent scout press. Both the original press and the undo appear in /history as raw events. A client replaying the log resolves the retraction there: each undo cancels the most recent non-undo event. Filter undo rows at the display layer.The scout sends no payload fields. The server stamps retractsSeq — the seq of the press the undo cancelled (null when nothing remained to cancel, or on a log recorded before the stamp existed) — onto the payload it serves, on the live frame and in the /history backfill alike, so a display can strike the retracted row directly without replaying:
Server-originated — not a scout press. Emitted by the liveness monitor when the scout’s status changes. seq is null on these frames, and the full snapshot is still included so no re-sync is needed.
See Core Concepts — Advisories.