Sub-second updates
Pushed straight from Pinnacle's broker as prices change — no interval to wait on.
Stop polling. Open one WebSocket and receive Pinnacle's live and prematch odds the instant they change — every sport, with built-in dropping-odds alerts. Pinnacle Odds API streams Pinnacle's own broker feed straight to your code.
No card. No Pinnacle account. Your API key is the socket credential.
Module 01 — Transport
Polling a REST endpoint means you only see a price after your next request — and you burn rate limit doing it. A WebSocket keeps one connection open and pushes every change the moment Pinnacle's broker emits it, so fast-moving lines and drops reach you first.
| REST polling | Pinnacle WebSocket API | |
|---|---|---|
| Latency | Up to your poll interval | Sub-second push |
| Rate limits | Every poll counts | One persistent connection |
| Missed moves | Anything between polls | Every frame delivered |
| Drops detection | Diff it yourself | Built in |
Module 02 — Handshake
Connect to wss://pinnodds.com/ws/feed with your API key, subscribe to the sports
you care about, and receive a snapshot of current state followed by a live stream of price
deltas. A heartbeat keeps the socket alive; reconnect and you get a fresh snapshot. Large
baselines (e.g. prematch soccer) arrive as several snapshot frames tagged with
seq/final — merge each frame's events by id, exactly as you do the
deltas that follow. See the WebSocket documentation for the frame schema.
// Node.js — connect, subscribe, receive live Pinnacle odds
import WebSocket from "ws";
// perMessageDeflate: true compresses live frames ~5x — strongly recommended
const ws = new WebSocket("wss://pinnodds.com/ws/feed?key=YOUR_KEY", { perMessageDeflate: true });
ws.on("open", () => {
// subscribe to soccer (1) and basketball (4), live stream
ws.send(JSON.stringify({ type: "subscribe", streams: ["live"], sport_ids: [1, 4] }));
});
ws.on("message", (buf) => {
const msg = JSON.parse(buf);
if (msg.type === "snapshot") console.log("state:", msg.events.length, "events");
if (msg.type === "live") console.log(msg.rec.id, msg.rec.markets); // price update
});
Enable compression. Turn on permessage-deflate on your client —
live frames are compressed roughly 5×. This is essential for high-volume or
geographically distant clients: without it, a burst of updates can exceed a single connection's
throughput and queue up, so frames arrive with a delayed timestamp. Browsers negotiate it
automatically; in Node's ws pass { perMessageDeflate: true }; Python's
websockets and Go's gorilla/websocket support it too. Same URL, same
JSON — your client decompresses transparently.
Full, copy-paste clients in Node, Python, Go and PHP — plus the exact frame schema and auth — are in the WebSocket documentation.
Module 03 — Payload
Pushed straight from Pinnacle's broker as prices change — no interval to wait on.
Every Pinnacle broker frame forwarded byte-identical, for teams that want the wire verbatim.
Line drops detected in real time on live and prematch markets — no diffing required.
Prefer Server-Sent Events? The same feed is available over SSE with one flag.
Soccer, tennis, basketball, MLB, NBA, NHL, MMA and more — live and prematch.
REST and SSE match common Pinnacle client formats, so migrating is mostly a URL change.
Module 04 — Query log
Free 3-day full demo, no card required. Enable the WebSocket add-on and you're live in minutes.