Single match stream
Subscribe to push updates for one specific match.
URL
wss://api.scorelytics.pro/v1/ws/match/{id}?api_key=sk_live_...
{id} is the match identifier returned by listMatches.
Messages emitted
score_update
Sent whenever any of these change: home_score, away_score, period,
minute, game_clock_secs.
{
"type": "score_update",
"match_id": "abc123",
"data": {
"home": 2,
"away": 1,
"minute": 67
}
}
For basketball matches, data carries game_clock_secs instead of
minute:
{
"type": "score_update",
"match_id": "xyz789",
"data": {
"home": 84,
"away": 81,
"period": 25,
"game_clock_secs": 180
}
}
status_change
Sent when status_code transitions. Both old and new are included so a
client can choose to react only to specific transitions (e.g. 2 → 3 for
final whistle).
{
"type": "status_change",
"match_id": "abc123",
"data": { "from": 2, "to": 3 }
}
Suggested flow
const apiKey = process.env.SCORELYTICS_KEY;
const matchId = 'abc123';
async function start() {
const snap = await fetch(
`https://api.scorelytics.pro/v1/football/matches/${matchId}`,
{ headers: { 'X-API-Key': apiKey } }
).then(r => r.json());
render(snap);
const ws = new WebSocket(
`wss://api.scorelytics.pro/v1/ws/match/${matchId}?api_key=${apiKey}`
);
ws.onmessage = (e) => {
const msg = JSON.parse(e.data);
if (msg.type === 'score_update') {
Object.assign(snap, {
home_score: msg.data.home,
away_score: msg.data.away,
minute: msg.data.minute ?? snap.minute,
});
} else if (msg.type === 'status_change') {
snap.status_code = msg.data.to;
}
render(snap);
};
ws.onclose = () => setTimeout(start, 3_000);
}
start();
When the match ends
After a status_change to 3 (Finished), no further messages will arrive.
Close the connection cleanly:
if (msg.type === 'status_change' && msg.data.to === 3) {
ws.close(1000, 'match finished');
}
Errors
| Status | Meaning |
|---|---|
401 | API key missing or invalid (sent before the WebSocket upgrade). |
404 | Match ID does not exist. |
426 | Request did not include WebSocket upgrade headers. |