Comparisons
REST polling vs WebSocket vs SSE for sports odds: which one fits your use case

Trade-offs between REST snapshots, SSE drop alerts and a raw WebSocket odds feed: what each carries, what it costs, and a decision table by use case.
PinnRadar delivers Pinnacle prices in three ways: REST snapshots, Server-Sent Events (SSE) drop alerts, and a raw WebSocket feed. They don't compete with each other. Each carries different data, costs different amounts, and puts a different amount of work on your side. This post sets out the trade-offs and ends with a decision table.
A fourth access path, the MCP server, is for AI assistants rather than programs. It's covered at the end.
The short version
- REST answers "what are the prices right now?" whenever you ask. You choose when.
- SSE tells you "this price just fell". It sends alerts only, filtered by size, and the server does the detection.
- WebSocket says "here is everything upstream sent". It's a raw relay, and you keep the order book yourself.
REST: snapshots on request
Endpoints: /kit/v1/markets (live or prematch board), /kit/v1/details, /kit/v1/prematch/fixtures, /kit/v1/prematch/markets, /kit/v1/prematch/lines, plus the /api/drops buffer.
What you get: full, merged event objects with every market and period, in one consistent shape for live and prematch. The REST snapshot already merges each fixture into one canonical row. The raw feed doesn't do this for you, as the WebSocket section explains.
Strengths
- It works on every plan, Free included.
- It is stateless. Any language, any cron job, any serverless function can call it.
- The
sincecursor keeps repeated polls small: send back thelastyou received and only changed events return. - Freshness is explicit.
X-Data-Status(fresh,stale,unknown) andX-Data-Age-Mscome on every response, so an empty board can't be mistaken for a quiet market.
Costs and limits
- A change reaches you at your next poll at the earliest. The data you see can be as old as your polling interval.
- Every call counts against your plan: 20 per minute and 100 per day on Free and Drops, 10 per second on REST and Edge, 30 per second on Scale.
- Removals only show up in a full response, so delta pollers need a periodic full refresh.
Fits: dashboards, scheduled jobs, closing-line capture, research scripts, and on-demand lookups after an alert. The Python guide walks through a polling client.
SSE: drop alerts pushed to you
Endpoints: /odds-drop (in-play) and /odds-drop-prematch.
What you get: a long-lived HTTP response. It opens with a connected frame, then sends JSON arrays of drops. Each drop includes from_price, to_price, nvp (the no-vig fair price), the market section and the event. Live drops also carry a match-state object.
Strengths
- Detection runs on the server. You don't hold a book or diff snapshots.
- Messages arrive as drops are detected, with no polling step in between.
- Pushed messages don't count against your REST request quota.
- Configuration is minimal:
min_drop(default 5%, minimum 1%) per connection, and on prematch,recheck=Nto send only drops that held for N seconds. - SSE is plain HTTP.
curl -Nworks, and browsers haveEventSourcebuilt in.
Costs and limits
- It sends alerts, not prices. Markets that didn't fall never appear, and neither do markets that lengthened.
- There is one connection per account per stream, and a second connection closes the first. Live and prematch are separate slots.
- There is no server-side sport filter. Every sport arrives and your client filters on
sport_id. - There are no freshness headers. Silence is the only warning, so watch
/healthalongside. - Player and team props don't fire the streams. Among the specials, only BTTS and Draw No Bet do.
- It needs Drops, Edge or Scale.
Fits: alerting, triggers that start a REST lookup, and notification bots. The SSE guide has full Python and Node.js clients.
WebSocket: the raw feed
Endpoint: wss://pinnradar.com/ws/feed.
What you get: upstream frames relayed byte for byte inside a thin envelope. There is no drop detection and nothing derived. That includes markets opening, closing and settling. You subscribe to live and/or prematch streams by sport_ids (up to 32 per subscribe) or event_ids (up to 200 per stream).
{ "type": "subscribe", "streams": ["prematch", "live"], "sport_ids": [3], "event_ids": [1632907731] }
Strengths
- It is the most complete view: every update, not only falls.
- Every live price change arrives as a frame, so your book changes as upstream does.
- Prematch support is efficient.
prematch_wsframes carry price changes, andprematch_membershiplists fixturesaddedandremovedeach cycle. Together they mean you never pull the full prematch board.
Costs and work on your side
- You maintain the book.
opisadd,upd(often a subset of markets, so merge by marketkey) ordel. Closed periods close all their markets. - Live updates come on two channels.
ldcarries the current price; build from it.dzis a volatility signal, not a second price. Mixing them makes prices look as if they spike and revert. - One fixture can appear under several matchup ids. Key your book on
rec.idplus marketkey. - Order and deduplicate on
markets[i].version, notrec.version. Upstream often resends unchanged markets. - Answer
pingwithpong(the protocol pong your library sends automatically also counts). Set your client's maximum message size to 8 MB, and read fast enough: at 128 MB of backlog the socket is closed. - There is one connection per account, and a newer connection evicts the older one.
- It is a $99 / 30-day add-on to REST, Edge or Scale ($297 / 90 days, $594 / 180 days when bought with the base plan; prorated if added mid-cycle). It is not available on Free or Drops.
Fits: trading tools, pricing models and anything else that needs a full, continuously updated copy of the book. The WebSocket API page and the docs cover the merge recipe in detail.
Latency, honestly
We don't publish latency figures. What we can say is structural. With REST, staleness is bounded by your polling interval plus the request time. SSE and WebSocket push each message as it happens, with no polling step in between. Your own network distance to the server is usually the largest variable you control, so measure from your own location.
On the WebSocket you can make one tuning choice yourself: per-message compression. Deflate makes live frames about 5x smaller. With context takeover, though, each message waits for the previous one to finish compressing, so bursts queue up. If you have spare bandwidth, turn it off. On a thin or long-distance link, keep it on. Measure both on your own path.
Decision table
| Your need | Transport | Minimum plan |
|---|---|---|
| Explore the data, build a prototype | REST | Free |
| Prices on demand for a page or a job | REST with since | REST ($99) |
| Be told when a price falls by X% | SSE | Drops ($99) |
| Alerts and full prices after each alert | SSE + REST | Edge ($149) |
| Higher REST throughput plus alerts | SSE + REST | Scale ($229) |
| Every update, your own book | WebSocket (+ REST to resync) | REST + WS add-on ($198) |
| Full book plus server-side drop alerts | WebSocket + SSE + REST | Edge + WS add-on ($248) |
| Price falls from the last few hours, on a schedule | REST /api/drops | Free (within limits) |
| Ask questions in a chat | MCP | Free |
Prices are per 30 days. Longer terms cost less per month; see the pricing page and our plan guide.
Common combinations
Alert, then look up. The SSE stream fires on a drop, and your handler calls GET /kit/v1/details?event_id=<id> for the full live market. This is the main reason Edge bundles REST and SSE. It costs $49 less than buying Drops and REST separately.
Book plus resync. Keep the book from the WebSocket. If you reconnect (no state is kept between connections), subscribe again and rebuild from the new snapshot frames. Use REST for one-off lookups and for anything outside your subscriptions.
Polling within a budget. On REST alone, poll each sport with since, do a full refresh every few minutes, and log X-Data-Status. Add the SSE stream later if the polling interval turns out to matter.
Where MCP fits
The MCP server at https://mcp.pinnradar.com/mcp lets Claude, Cursor, VS Code and other assistants call eight read-only tools in plain language. It works by request and response, so it can't stream. Each data call counts as one request on your plan, the same as REST. It suits questions and quick analysis, not production feeds. See building an odds assistant with MCP.
Summary
Start with REST: it works on every plan and the data is complete per call. Add SSE when a price fall should reach you without a poll. Choose the WebSocket only when you need every update and are prepared to maintain the book. Many production setups combine two of the three.
Questions readers ask
Is the SSE stream a full odds feed?
No. SSE sends drop alerts: prices that fell by at least your min_drop threshold. For every price update, use the WebSocket feed. For full snapshots on demand, use REST.
Which plans can use the WebSocket feed?
It is a $99 per 30 days add-on for REST, Edge and Scale ($297 for 90 days or $594 for 180 days when bought with the base plan). It is not available on Free or Drops.
Do streamed messages count against my request limit?
No. SSE and WebSocket messages don't count against the REST request quota. REST calls and MCP tool calls do.
Which transport has the lowest latency?
We don't publish latency figures. Structurally, SSE and WebSocket push each message as it happens, while REST data can be as old as your polling interval. Measure from your own location.
Pull Pinnacle prices into your own code
The PinnRadar odds APIcarries Pinnacle’s live and prematch markets, drop alerts included, over REST, SSE and WebSocket. Compare the plans, or start on a free key: just an email, and no Pinnacle account needed.