Stream live scores to your backend over WebSocket
Developers building dashboards, apps and services that need scores pushed as they change.
Exchange your API key for a one-hour token on your server, open the socket and subscribe to the event types you need. Messages only arrive when something changes, so a quiet league costs nothing, and one connection can carry every league.
Updated 2026-11-04. Data is aggregated from public sources and is typically 20-30 seconds behind live play (about 1 second after our source). There is no SLA.
Message types
event_score_change, event_live, event_status_change, event_play, event_final and event_odds_change, plus the opt-in event_play_corrected. Subscribe with no filters for every league, sport + league for one league, or eventId for a single game. Every message is JSON with type, timestamp and data.
A score change
{
"type": "event_score_change",
"timestamp": "2026-11-02T18:05:00.000Z",
"data": {
"eventId": "401772982", "sport": "football", "league": "nfl",
"homeTeam": { "id": "...", "name": "Team B", "score": 14 },
"awayTeam": { "id": "...", "name": "Team A", "score": 7 },
"previousScore": { "home": 7, "away": 7 }
}
}A production-ready client
Get the token on your server (the key never reaches a browser), resubscribe after reconnecting, and request a fresh token when the hour is up. The server pings every 15 seconds; if a proxy still drops idle connections, send { "type": "ping" } every minute or two.
Node.js
async function connect() {
const res = await fetch('https://www.realtimesportsapi.com/api/websocket/auth', { method: 'POST', headers: { Authorization: `Bearer ${process.env.RSA_API_KEY}` } });
const { data } = await res.json();
const ws = new WebSocket(`${data.url}?token=${data.token}`);
const ping = setInterval(() => ws.readyState === 1 && ws.send('{"type":"ping"}'), 90_000);
ws.onopen = () => {
ws.send(JSON.stringify({ type: 'subscribe', event: 'event_score_change' })); // every league
ws.send(JSON.stringify({ type: 'subscribe', event: 'event_final' }));
ws.send(JSON.stringify({ type: 'subscribe', event: 'event_status_change',
filters: { sport: 'basketball', league: 'nba' }, frequency: '1m' })); // conflated clock
};
ws.onmessage = (e) => {
const msg = JSON.parse(e.data);
if (msg.type === 'error') console.error(msg.error);
else if (msg.type.startsWith('event_')) handle(msg); // your code
};
ws.onclose = () => { clearInterval(ping); setTimeout(connect, 3000); }; // new token each time
}
connect();Controlling volume
frequency (asap, 30s, 1m, 5m, 10m, 30m) conflates clock-only status updates and odds changes per game; score changes, plays, live, final and real state changes are always sent at once. Each delivered message counts once toward your pool. Connections over your plan's limit (Starter 2, Growth 3, Pro 5, Scale 25) are refused with close code 4008; existing connections are never dropped for it.
Endpoints used
POST /websocket/auth
Full reference: docs · OpenAPI · what each endpoint returns, by league
Plans
| Plan | Price | Calls | Rate | WebSocket | Webhooks |
|---|---|---|---|---|---|
| Free | $0 | 125/mo (1,000 first 30 days) | 1/s | 500 msgs/mo | No |
| Starter | $29/mo ($290/yr) | 10,000/mo | 5/s | Shares monthly pool | Shares monthly pool |
| Growth | $49/mo ($490/yr) | 25,000/mo | 10/s | Shares monthly pool | Shares monthly pool |
| Pro | $99/mo ($990/yr) | 50,000/mo | 20/s | 100,000 msgs/mo | 25,000/mo |
| Business | $179/mo ($1,790/yr) | 150,000/mo | 40/s | 300,000 msgs/mo | 75,000/mo |
| Scale | $299/mo ($2,990/yr) | 500,000/mo | 100/s | 500,000 msgs/mo | 100,000/mo |
Every successful REST call counts as one call. Over the limit you get HTTP 429 with a Retry-After header. No SLA. Full pricing.
FAQ
- Can I try WebSocket on the Free plan?
- Yes. The Free plan includes a 500-message monthly WebSocket preview with 1 connection, so you can test the stream before upgrading.
- Is it sub-second?
- No. Messages go out about a second after our source updates, and the data is typically 20-30 seconds behind live play.
- Should browsers connect directly?
- No. Connect from your server and forward what your users need; otherwise your key or tokens are exposed and each viewer uses a connection.
- WebSocket or webhooks?
- WebSocket suits a long-running service that wants every change in-process. Webhooks suit serverless or request-based backends: we POST each event to your URL.