All timestamps are UTC.
If a change affects data shape or behavior, it will be marked as Breaking.
2026-05-25
✨ Added
- WebSocket
receiveType: "zstd"— dictless compression. Opt-in zstd egress with no dictionary handling: every data frame is a standalone dictless zstd frame (dictId 0), decoded in one line (zstd.decompress(frame)→ JSON). ~5–6× smaller than JSON onodds— the simplest way to cut bandwidth. See Compression. - WebSocket
receiveType: "zstd-dict"— trained dictionaries. Maximum ratio (~7–9× onodds) using per-channel dictionaries the server pushes asdictcontrol frames at connect.
🔁 Changed
receiveType: "zstd"now means dictless. During the zstd beta,"zstd"previously delivered trained dictionaries; that behavior moved to the new"zstd-dict". If you were decoding dictionary frames under"zstd", switch to"zstd-dict".- Dictionary version cache removed. The
dictslogin field is gone; the server now re-sends the (~32 KB) dictionaries on everyzstd-dictconnection, so clients no longer persist or version dictionaries across reconnects. Adictsfield, if still sent, is ignored.
2026-04-09
✨ Added
- Fixture view:
venuesection — new nested object on all fixture responses withvenueId,venueName, andvenueLocation. Translated per language. - Fixture view:
clocksection — new nested object on all fixture responses withcurrentPeriod,currentTime,remainingTime,remainingTimeInPeriod, andstopped. All keys present withnullvalues until clock data is populated for a fixture. - Fixture view:
participant1ShortName/participant2ShortName— new fields in theparticipantssection of fixture responses, sourced from translated participant data. - Fixture view:
seasonRound— new field in theseasonsection of fixture responses. - Futures view:
marketId— themarketsection in future responses now includes themarketIdfrom the futures table. Name fields (marketName,marketType,playerMarket,participantMarket) remainnullfor now. - Participants endpoint:
participantShortName— theGET /{lang}/participantsresponse now includesparticipantShortNamefor each participant. - New REST endpoint:
GET /{lang}/venues?venueIds=...— returns venue data with translatedvenueNameandvenueLocation. - New WebSocket channel:
clocks— delivers live clock updates per fixture (same routing asscores: filtered byfixtureId, sport, tournament). Supports resume/replay.
⚠️ Breaking
- Fixture response shape changed — all fixture endpoints (REST and WebSocket) now include three new top-level keys:
venue(object),clock(object), and updatedparticipants/seasonsections. Clients parsing fixture responses strictly should update their models.seasonnow includesseasonRound: integer | nullparticipantsnow includesparticipant1ShortName: string | nullandparticipant2ShortName: string | nullvenue: { venueId, venueName, venueLocation }added afterseasonclock: { currentPeriod, currentTime, remainingTime, remainingTimeInPeriod, stopped }added afterscores
- Future response shape changed —
market.marketIdis now populated (integer or null) instead of alwaysnull.
2025-12-12
✨ Added
- WebSocket resume & replay support using
entryIdcursors - New WebSocket channels:
injurieslineupsstats
- AsyncAPI 3.0 reference for WebSocket gateway
🔧 Improved
- Reduced WebSocket latency for
oddsandscores - Better filtering for
sportIds,tournamentIds, andbookmakers
🐛 Fixed
- Fixed an issue where some
oddsupdates were delivered without bookmaker gating - Fixed incorrect
liveflag on some fixtures during transitions
2025-11-28
⚠️ Breaking
odds.payload.oddskeys are now always bookmaker-scoped- Old clients expecting a flat structure must update
✨ Added
- Support for
receiveType: "binary"(MessagePack) - Added
entryIdto all update messages
2025-11-10
✨ Added
- Initial WebSocket gateway
- Channels:
fixturesscoresoddsbookmakers