Skip to main content
The price feed streams market/orderbook updates as JSON messages over a raw WebSocket connection.

Ping/Pong

Both feeds support standard WebSocket ping/pong. You may proactively ping() on an interval and track pong to verify liveness.

Subscriptions

By default a connected client receives every market update across all sports and leagues. To narrow the firehose, send one of the following commands as a JSON text frame after the socket is open. Commands take effect for the lifetime of the connection. A client that never sends a subscribe command stays in broadcast-all mode, so existing integrations keep working without changes.

Subscribe by gameID, league, or sport

Install a filter. gameIDs are 24-character Mongo ObjectID hex strings; leagueIDs are short codes like NBA / MLB / EPL; sportIDs are lowercase tokens like basketball / baseball / soccer.
  • replace: true clears any existing subscriptions on this connection and installs the new lists. Switches the connection into filtered mode.
  • replace: false adds the new keys to whatever the connection is already subscribed to.
You will receive an update if its gameID, parentGameID, league, or sport matches any of your subscriptions.

Unsubscribe

Remove specific keys. The connection stays in its current mode (filtered or subscribe-all).

Subscribe to everything

Explicit catch-all. Useful if you previously narrowed via subscribe and want to re-broaden without reconnecting. Clears any per-key subscriptions on the connection.

Routing semantics

  • A gameID subscription also receives updates for child games whose parentGameID matches (e.g. F5-MLB derivatives reach subscribers of the parent game).
  • League IDs are case-insensitive — mlb and MLB are equivalent.
  • Sport IDs are case-insensitive — baseball and Baseball are equivalent.
  • Empty strings inside the arrays are ignored.
  • subscribe with replace: false and all-empty arrays is a no-op (a buggy client can’t accidentally blackhole itself by sending an empty additive subscribe).
  • subscribe with replace: true and all-empty arrays is the legitimate “clear all my subs” path — the connection enters filtered mode with zero subscriptions and receives nothing until you subscribe again or send subscribeAll.

Messages

Every message on /price-stream arrives as a 2-tuple [type, payload]. Three message types are broadcast.

orderUpdate

Emitted whenever an order in any market changes (new, edited, filled, or cancelled). The payload only includes sideOrders the receiving user is allowed to see (own orders plus matchable counterparties). sideOrders entries for orders placed with orderType: "postArb" include isPostArb: true; the field is omitted otherwise.

orderUpdate for moneyline1x2 markets

For moneyline1x2 (soccer 3-way: home / draw / away), the runner is identified by the market + side pair instead of participantID / OU:
  • market — the outcome the market is about: a participant ObjectID hex (home or away team) or the literal string "draw".
  • side"yes" or "no" on that outcome.
  • OU, total, and spread are absent, and participantID is empty — use market + side.
Both fields appear at the update level (identifying which orderbook side changed) and on every entry in sideOrders.

gameUpdate

Emitted when a game is created or its state changes (markets opening, closing, start time updates). The payload is the full rendered game.
Known messageType values: marketOpen, marketClosed. Treat the field as extensible and ignore unknown values.

matchedVolumeUpdate

Emitted when the total matched volume on a game changes.