Overview
TheRundown provides a V2 WebSocket endpoint for streaming real-time data without polling:
WebSocket connections do not count against your REST API rate limit — but each plan has a hard cap on concurrent connections (and on subscriptions per connection on the multiplexed endpoint). Opening a connection beyond the cap is rejected at upgrade time with a
429 (WebSocket connection limit reached).
Connection
Connect using a standard WebSocket client. Authentication is via thekey query parameter:
Markets WebSocket
GET /api/v2/ws/markets
Streams V2 market price changes in real time. Every time a sportsbook updates a price on any tracked market, you receive a message.
Filter Parameters
All filters are optional. If none are specified, you receive all messages across all sports and markets.Example Connection URLs
Message Format
Each message is a JSON object with two top-level fields:meta (message metadata) and data (the update payload). Unlike the REST API’s nested structure, WebSocket messages deliver one price update per message in a flat format — each message represents a single price change for one participant, one market, and one sportsbook.
Example: Market Price Update
Meta Fields
Data Fields
Play-by-Play Channel (Multiplexed WebSocket)
The multiplexed endpoint at/api/v2/ws carries multiple logical channels over a single connection. Instead of query-parameter filters, you send JSON subscribe messages after connecting:
The
plays and live channels require the live game state entitlement (Ultra plan or higher) — the same entitlement as the REST plays endpoint. The markets and scores channels are available to any WebSocket-entitled key.Subscribing
Send a subscribe action with a client-chosenid, the channel, and optional filters:
Filters supported in
params: sport_ids, event_ids (plus market_ids and affiliate_ids on the markets channel).
Snapshots
Add"snapshot": true to params to receive the current state before live deltas begin. The server sends the subscribed ack, one or more snapshot frames, then snapshot_complete; deltas start after that. Each snapshot covers your subscription scope only — markets snapshots use the same filters and market defaults as the REST events endpoints (each frame carries scope.requested_market_ids / scope.returned_market_ids), live snapshots include the current score/status and live game state, and plays snapshots return up to 500 current plays with a cursor holding the oldest/newest play sequence. Snapshot requests need a bounded scope: event_ids, or sport_ids plus date (play snapshots require event_ids). An existing subscription can request a fresh snapshot at any time without reconnecting:
Play messages
Each play arrives wrapped in a delta envelope tagged with your subscriptionid:
{"action": "unsubscribe", "id": "p1"}.
Error codes
Errors are returned as{"type": "error", "id": "...", "code": "...", "message": "..."}:
Heartbeat
The WebSocket endpoint sends a heartbeat message every 15 seconds to keep the connection alive:Message Queue
Each client has a 1024-message buffer. If your client cannot consume messages fast enough, the server drops messages rather than blocking. This means:- If your processing is slow, you may miss updates
- Design your client to process messages quickly and offload heavy work asynchronously
- For high-volume feeds, consider filtering to specific sports or events to reduce message volume
Client Examples
If WebSocket is not an option for your architecture, use the REST delta endpoints to poll for changes efficiently. For the full list of market types you can filter on, see Market IDs.
Best Practices
Filter to reduce volume
Filter to reduce volume
The unfiltered market feed can be very high volume. Always apply
sport_ids, market_ids, or event_ids filters to receive only the data you need. This keeps your 1024-message buffer from overflowing.Implement automatic reconnection
Implement automatic reconnection
WebSocket connections can drop due to network issues, server deployments, or idle timeouts. Always implement reconnection logic with exponential backoff (e.g., 1s, 2s, 4s, 8s, max 30s).
Use heartbeats for health monitoring
Use heartbeats for health monitoring
If you have not received any message (including heartbeats) for 30+ seconds, assume the connection is dead and reconnect. Do not wait for the WebSocket
close event, as it may not fire reliably in all network conditions.Process messages asynchronously
Process messages asynchronously
Keep your message handler fast. Parse the JSON and push work to a queue or separate processing thread. A slow message handler causes the 1024-message buffer to fill up and messages to be dropped.