Overview
TheRundown provides a V2 WebSocket endpoint for streaming real-time data without polling:| Endpoint | Description |
|---|---|
/api/v2/ws/markets | Streams market price changes (odds updates) as they happen |
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.| Parameter | Description |
|---|---|
affiliate_ids | Comma-separated sportsbook IDs (e.g., 19,23) |
sport_ids | Comma-separated sport IDs (e.g., 4,6) |
event_ids | Comma-separated event IDs |
market_ids | Comma-separated market IDs (e.g., 1,2,3) |
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
| Field | Type | Description |
|---|---|---|
type | string | "market_price" for price updates, "heartbeat" for keep-alive |
version | string | API version ("v2") |
timestamp | number | Unix epoch timestamp when the message was sent |
Data Fields
| Field | Type | Description |
|---|---|---|
id | number | Unique price record ID |
event_id | string | Canonical V2 event ID |
affiliate_id | number | Sportsbook ID (see Sportsbook IDs) |
market_id | number | Market type (see Market IDs) |
market_participant_id | number | Sportsbook-specific participant ID for this market entry |
normalized_market_participant_id | number | Canonical participant ID — maps to participant.id in REST API responses |
normalized_market_participant_type | number | Participant type identifier |
line | string | Line value (e.g., "-4.5" for spread, "224.5" for total, "0" for moneyline) |
price | string | Current American odds (e.g., "-117", "+150") |
previous_price | string | Price before this update |
price_delta | number | Numeric change from previous price |
is_main_line | boolean | Whether this is the primary line |
sport_id | number | Sport ID |
updated_at | string | ISO 8601 timestamp of the price change |
Heartbeat
The WebSocket endpoint sends a heartbeat message every 15 seconds to keep the connection alive:Message Queue
Each client has a 256-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 256-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 256-message buffer to fill up and messages to be dropped.