Connection
Authentication
Pass your API key via:- Query string (recommended for browser clients):
?x-api-key=YOUR_API_KEY - Header:
x-api-key: YOUR_API_KEY
Sport Selection
Optionally set thex-sport header during connection to scope live-scores to a specific sport (default: football).
Supported values: football, basketball, ice-hockey, tennis, rugby, handball, volleyball, baseball, american-football, cricket, futsal, mma, motorsport, darts, snooker, badminton, table-tennis, beach-volley, cycling, esports, bandy, aussie-rules, floorball, minifootball, waterpolo.
Message Format
All messages are JSON. Send actions to subscribe/unsubscribe from channels:Available Channels
Delivery Modes
- NATS push — Data is pushed directly from the real-time feed with no delay
- NATS-triggered fetch — When any match update is detected, detailed data is fetched instantly (no waiting for poll cycle)
- Polling — Data is fetched at regular intervals (used for lineups which rarely change)
No updates received?
If the connection opens and thewelcome / subscribed frames arrive but no update
frames follow, work through this list before assuming an outage:
- Confirm the match is actually in progress with
GET /v2/{sport}/live. This is the authoritative liveness source. The schedule endpoint lists a whole day of fixtures with a status snapshot, so a fixture you read there may already have finished — a finished match emits nothing onmatch:{matchId}or onlive-scores. - Check the
sportin thewelcomeframe.live-scoresis scoped to it. Connecting on/v2/{sport}/wssets the scope automatically; thesubscribedframe confirms it aslive-scores:{sport}. - Expect quiet gaps. Frames are emitted on change only. Between deliveries, at a wicket
break, at half-time or during a rain delay, a genuinely live match can be silent for a
minute or more. Test against a sport-wide
live-scoressubscription rather than one fixture. - Check
natsConnectedin thewelcomeframe. If it isfalse, push channels fall back to their safety-net poll cadence. - De-duplicate on
changes.changeTimestamp. A single change can arrive two to three times onmatch:{matchId}, plus once more onlive-scores— that is expected, not a bug.
What’s delivered on :incidents
The match:{matchId}:incidents channel covers every discrete event the live feed emits:
Response Types
welcome
Sent immediately on connection:
subscribed
Confirms a channel subscription:
snapshot
Last known data sent immediately upon subscribing (if available):
update
New data pushed in real-time:
pong
Response to a ping (for keep-alive):
Quick Start Examples
Best Practices
Subscribe only to channels you need
Subscribe only to channels you need
Each subscription consumes server resources. Only subscribe to channels your application actively uses.
Use incidents for real-time match events
Use incidents for real-time match events
Use
match:{id}:incidents for real-time match events rather than polling the REST endpoint.Handle snapshot messages
Handle snapshot messages
When you subscribe, you immediately get the last known state so your UI is never blank.
Send periodic pings
Send periodic pings
Send
{"action":"ping","channel":"live-scores"} every 30s to keep the connection alive.Reconnect with backoff
Reconnect with backoff
If disconnected, reconnect with exponential backoff (1s, 2s, 4s, 8s…).
Unsubscribe when done
Unsubscribe when done
Unsubscribe from match channels when the user navigates away.