Real-Time Soccer Odds API: Live, Quarter Lines & Drops

A real time soccer odds API over a pushed feed: live and prematch football markets, quarter lines, specials, and drop detection — Pinnacle-only, self-serve.
Short version: if you need Pinnacle's live and prematch soccer markets pushed to you the instant they move — every quarter line included, with drop detection built in — that is exactly what pinnodds does. Pinnacle-only, over a WebSocket, self-serve from $99/mo. It is not a multi-book grid and it has no historical archive, so if either of those is your product, read the honest-limits section before you sign up.
Soccer is the sport where a real-time feed earns its keep. A goal, a red card, a penalty — the market repriced two seconds ago and a polled endpoint won't tell you until your next tick. This post is about getting football odds as a pushed stream, what the payload actually contains, and where the approach breaks down.
Live and prematch, both pushed
Two pipelines run in parallel and you consume whichever you need.
- Live (in-play). As a match plays, Pinnacle repriced markets flow to you over the raw WebSocket passthrough at
/ws/feed, and odds-drop alerts arrive over Server-Sent Events at/odds-drop. Sub-second, no polling loop to tune. - Prematch (pre-game). Prematch soccer markets are served the same way, with drop alerts at
/odds-drop-prematch. REST for both lives under/kit/v1/...and/api/drops.
The key word is pushed. You are not asking "did the Bayern total move?" every five seconds — the feed tells you the moment it does. For in-play football that is the whole game; a two-second head start on a repriced line is the difference the feed exists to give you. The WebSocket product is documented in full on the WebSocket API page.
Every soccer line, quarter lines included
This is the part people underestimate until they wire up a competitor and find the depth isn't there. pinnodds carries every line Pinnacle prices, on every plan:
- Totals at 1.75, 2.25, 2.75, 3.25 — not just 2.5 and 3.0. The quarter total is where a lot of the closing-line value hides on soccer.
- Quarter-ball Asian handicaps at -0.75, -1.25, -1.75, -2.25 — the split lines, not only the round and half lines.
Line depth does not scale with price. The Pro, Pro + SSE and Scale plans differ in rate limit and push access, not in how many lines you see. A quarter-line total on a Championship match is in the entry-tier payload exactly as it is on Scale. That matters for soccer specifically because Asian totals and handicaps are quoted in quarter increments as standard, and a feed that rounds them to the nearest half line is quietly throwing away signal.
Filtering the feed to soccer
Here is a complete, copy-paste-accurate live consumer that connects to the WebSocket passthrough and keeps only soccer events. Soccer is sport id 1.
import WebSocket from "ws";
const KEY = process.env.PINNODDS_KEY;
const SOCCER = 1; // Pinnacle sport id for soccer/football
const ws = new WebSocket(`wss://pinnodds.com/ws/feed?key=${KEY}`);
ws.on("message", (buf) => {
const msg = JSON.parse(buf.toString());
// /ws/feed is a raw passthrough — one message can carry many events.
const events = Array.isArray(msg) ? msg : [msg];
for (const ev of events) {
if (ev.sport_id !== SOCCER) continue; // keep only football
for (const m of ev.markets ?? []) {
// m.type e.g. "total" / "spread" (handicap), m.points e.g. 2.25 / -1.25
console.log(
`${ev.event_id} ${ev.home}-${ev.away} ${m.type} ${m.points}`,
m.prices
);
}
}
});
ws.on("open", () => console.log("connected — streaming soccer"));
ws.on("close", () => console.log("closed — reconnect with backoff"));
The same one API key authenticates everything: ?key= on the streams, x-api-key: YOUR_KEY on REST. If you'd rather not hand-roll the plumbing, the official SDKs wrap both surfaces — npm install pinnodds and pip install pinnodds, both low or zero dependency.
Drop detection on soccer markets
Drop detection is a first-class product here, not something you assemble from a tick history you're storing yourself. When a soccer market's price falls against its own recent history, you get an alert — live at /odds-drop, prematch at /odds-drop-prematch.
import EventSource from "eventsource";
const es = new EventSource(
`https://pinnodds.com/odds-drop?key=${process.env.PINNODDS_KEY}`
);
es.onmessage = (e) => {
const d = JSON.parse(e.data);
// sect = market, outcome = moving selection,
// nvp = no-vig fair price, limit = Pinnacle max stake
console.log(`${d.id} ${d.sect} ${d.outcome}: ${d.from_price} -> ${d.to_price} (nvp ${d.nvp})`);
};
One shape detail worth stating plainly, because it trips people up: the SSE alert and the REST /api/drops row are two views of one event, not the same object. SSE gives you sect, outcome, from_price, to_price, id, plus limit (Pinnacle's max stake) and nvp (the no-vig fair price) — but no drop percentage. REST /api/drops (mode=live|prematch) is the enriched form: market, designation, from, to, event_id, and a precomputed drop_pct. Stream for speed; reconcile against REST when you want the tidy number. Key both on id / event_id and your pipeline stays honest under load. The full field reference is in the docs.
For soccer this is where the feed pays for itself: a total that steams from 2.05 to 1.88 on a quarter line, minutes before kickoff, is exactly the kind of move you want pushed to you rather than discovered on your next poll.
Specials: props, exact scores and outrights
By default the soccer payload is the core match markets — moneyline, totals, handicaps — because that keeps responses small enough to be useful. Pass include_specials=1 and the surface expands hard: soccer prematch goes from roughly 1,500 events to roughly 12,400.
Each special arrives as its own event row carrying special, special_category, special_markets, and a parent_id pointing back at the parent fixture. So a "player to score" prop, an exact-score market, or a league-winner outright is a distinct row you can join to its match by parent_id. That is a deliberate trade: opt into the firehose only when your model actually consumes props, and keep the default response lean the rest of the time.
Where a soccer-only Pinnacle feed is the wrong tool
Being specific here, because vagueness is how people waste a month.
You cannot arbitrage with pinnodds alone. It is one book. Arbitrage needs a soft book and a sharp book, and we only give you the sharp one. Same for any odds-comparison UI — a single-column grid of one operator isn't a product. If that's your build, pair pinnodds with a multi-book aggregator and use it as the reference price.
There is no historical odds archive. This is a real-time football feed. If you need three seasons of opening-to-closing lines to backtest a model, you either buy that from a historical vendor or start recording /ws/feed into your own store today and wait. Recording it yourself is genuinely fine — a couple hundred lines and cheap object storage — but it's your job, not ours.
Pinnacle's catalogue is the ceiling. No Pinnacle market, no data. If a book prices a soccer prop that Pinnacle doesn't, it isn't in the feed.
Push access is tiered. SSE lives on the $149 Pro + SSE plan and above; the entry Pro plan is REST. If your architecture is stream-first — and for in-play soccer it should be — budget for that from the start rather than discovering it after you've built. See pricing.
Getting started
The honest test costs you nothing and about an hour: grab a free key from the homepage, point a consumer at /ws/feed and /odds-drop, filter to sport id 1, and watch a live match reprice. If the Pinnacle line and the drop signal answer your question, you're done — no card, no sales call. The main product page is here, and the sibling WebSocket feed guide walks the connection details.
The cleanest mental model: a multi-book feed tells you what is being offered across operators; a Pinnacle feed tells you what is true. For soccer, where the sharp price moves first and the quarter lines carry the edge, the truth layer — pushed, with drops built in — is usually the one you actually want streaming.
Frequently asked questions
What is a real-time soccer odds API?
It is a feed that pushes live and prematch football market data to you as it changes, rather than making you poll a REST endpoint on a timer. pinnodds carries Pinnacle's soccer markets over a WebSocket passthrough at /ws/feed and pushes drop alerts over SSE, so your model reacts the instant a line moves.
Does the soccer feed include quarter lines?
Yes, and on every plan. You get every line Pinnacle prices — soccer totals at 1.75 / 2.25 / 2.75 / 3.25 and quarter-ball handicaps at -0.75 / -1.25 / -1.75 / -2.25 — not just the round and half lines. Plans differ by rate limit and push access, not by line depth.
How do I get in-play (live) soccer odds versus prematch?
Both are served. Live in-play soccer streams over /ws/feed and SSE drop alerts arrive at /odds-drop; prematch drop alerts arrive at /odds-drop-prematch. REST is under /kit/v1/... and /api/drops with mode=live or mode=prematch. You filter to soccer client-side by sport id.
How do I get soccer props and outrights?
Specials — player props, exact scores, futures and outrights — are off by default so responses stay small. Pass include_specials=1 and soccer prematch expands from roughly 1,500 events to roughly 12,400. Each special arrives as its own event row with special, special_category, special_markets and a parent_id pointing back at the fixture.
Does pinnodds cover multiple sportsbooks for soccer?
No — pinnodds is Pinnacle only. It is the sharp reference price and drop signal, not an odds-comparison grid. If you need many books normalised for arbitrage or a price-comparison product, use a multi-book aggregator alongside it.
Is there a historical soccer odds archive?
No. pinnodds is a real-time feed with no historical archive. If you need opening-to-closing line history to backtest, record /ws/feed into your own storage from day one, or buy history from a dedicated vendor.
Get real-time Pinnacle odds in your code
The Pinnacle APIby pinnodds: live & prematch markets with instant odds-drop alerts over SSE and WebSocket. See plans and pricing, or get a free key in seconds — no card, no Pinnacle account.
Get your free API key