Why you'd need this
If you're building something that needs to react to odds changes as they happen, a live pricing board, an alert system, a trading bot, hitting a REST endpoint on a timer eventually becomes the bottleneck. You're either polling too slowly and missing moves, or polling too fast and burning through your rate limit for no real benefit. A persistent connection that pushes events the moment they happen solves both problems at once.
This is a short walkthrough of connecting to a live odds feed from Node.js using a WebSocket client, and handling the parts that actually matter in production: reconnects and dropped messages.
Getting a key
You need an API key before any of this works. There's a free tier that's enough to build and test this without a sales call: https://orbistats.com/signup.html
If you want to see what the message payloads actually look like before writing a reconnect handler around them, there's a public sandbox that works without an account: https://orbistats.com/developers/sandbox.html
A basic connection
Using the ws package:
bash
npm install ws
javascript
const WebSocket = require('ws');
const API_KEY = process.env.ORBISTATS_API_KEY;
const WS_URL = wss://api.orbistats.com/v1/stream?token=${API_KEY};
const socket = new WebSocket(WS_URL);
socket.on('open', () => {
console.log('Connected to live feed');
socket.send(JSON.stringify({ action: 'subscribe', channel: 'odds', sport: 'football' }));
});
socket.on('message', (data) => {
const event = JSON.parse(data);
console.log('Odds update:', event);
});
socket.on('close', () => {
console.log('Connection closed');
});
A note before you copy this: the connection URL, the token query parameter, and the subscribe message shape above are written based on the documented pattern for this kind of feed, not a payload I've inspected directly. Verify the actual connection URL, auth method, and subscription message format against the live WebSocket API docs before this goes near production: https://orbistats.com/api/websocket-api.html
The part that actually matters: reconnecting
A WebSocket connection that silently drops and never comes back is worse than not having one at all, because your system keeps behaving as if the data is current when it isn't. A minimal reconnect wrapper:
javascript
function connect() {
const socket = new WebSocket(WS_URL);
socket.on('open', () => {
console.log('Connected');
socket.send(JSON.stringify({ action: 'subscribe', channel: 'odds', sport: 'football' }));
});
socket.on('message', (data) => {
const event = JSON.parse(data);
console.log('Odds update:', event);
});
socket.on('close', () => {
console.log('Connection lost, reconnecting in 2s');
setTimeout(connect, 2000);
});
socket.on('error', (err) => {
console.error('Socket error:', err.message);
});
}
connect();
This is deliberately simple, a real production version would add backoff instead of a fixed delay, and probably a heartbeat to detect a connection that's technically open but silently dead. But the shape of it, always assume the connection can drop and always have a plan for that, is the part people skip in a first draft and then debug at 2am later.
When you don't need a persistent connection
Not everything needs this. If you're pulling fixtures once a day or checking standings after a match ends, a WebSocket connection is unnecessary overhead, a plain REST call covers it fine and is a lot less code to maintain. Webhooks are worth a look too if you want event-driven updates without holding a connection open yourself: general documentation on when to reach for which approach is here: https://orbistats.com/developers/documentation.html
Where to go from here
This covers odds specifically, but the same connection pattern applies to live scores and match events too. The full API reference covers the other endpoints and channels available beyond what fits in one post: https://orbistats.com/developers/api-reference.html
Anyone else running WebSocket connections like this in production Node services, curious what you're using for the backoff and heartbeat logic, hand-rolled or a library handling it for you?

Top comments (0)