Skip to main content
Every wire change is announced on the changelog, labelled breaking or not. Breaking means an integration that was correct against the previous contract, and follows the tolerance rules below, stops working or starts silently misreading. A breaking change does not always bump contractVersion — the version covers each sport’s event and state schema, so a change to the catalog, history, health, or auth surfaces has no version to move. Read the entry’s label, not the version, to know if you are affected.

What we guarantee, and what we ask of you

Some changes are breaking for a strict parser and harmless for a tolerant one. So that “breaking” means something precise rather than depending on how your client is written, we classify every change against these four assumptions about your integration:
  1. Ignore object fields you don’t recognise. We add fields without warning; a parser that rejects unknown keys will break on an addition we consider safe.
  2. Ignore event type values you don’t recognise — don’t throw on an unmatched branch. New event types appear as a sport’s vocabulary grows.
  3. Treat league and sport as opaque strings. They are open vocabularies; new values appear when we add a league or a sport.
  4. Don’t parse ids. sessionId and gameId are opaque — their format is not a contract, and it has changed before.
Given those, an added field, an added event type, an added endpoint, an added optional query parameter, and a field that becomes more guaranteed (nullable → always present) are not breaking. Removing or renaming a field, changing a field’s type or meaning, a field becoming nullable, removing an event type, changing a value in an open vocabulary, moving an endpoint, changing what a status code means, and rejecting input we previously accepted are.

contractVersion

The WebSocket hello frame and every history response carry a contractVersion string. Each sport’s feed versions independently — basketball, soccer, baseball, and football each carry their own contractVersion — so the schema identity is the pair (sport, contractVersion); compare both. Versions count independently per sport, so “v5” alone is ambiguous — both fields ride beside each other wherever the version appears. It bumps only when that sport’s wire schema does — a field added, removed, renamed, an event type added, or a field’s meaning changed. Logic fixes and additive optional fields that carry a default do not bump it. It is a schema fingerprint, not a breakage signal: it moves for changes that cannot affect you (a contract catching up to bytes you already receive), and stays put for changes that can (a catalog field rename). Use it to detect that the schema you fold against has moved; use each entry’s breaking label to decide whether you must act. Treat a pair you don’t recognise as “read the changelog before trusting this frame”: