Live & In-Play Betting Odds API
A live, in-play betting odds API: real-time pre-match and in-game lines across 85+ books with sub-minute updates and WebSocket streaming, plus live scores to match.
A live odds API delivers betting lines that change in real time, covering both pre-match prices and the in-game numbers that move as a game unfolds, so your product can react the moment a market shifts. SportsGameOdds delivers both at once: pre-match and in-play odds across 85+ books in one schema, the status.started flag to tell live games from upcoming ones, the event's scores.home/scores.away so the live result rides alongside the live price, update frequency down to sub-minute on Pro, and WebSocket streaming on All-Star for push instead of polling.
Why build your live betting product on SportsGameOdds
- Live and pre-match odds share one schema. The same
/eventsmarket shape carries upcoming prices and in-game prices. Readstatus.started(mirrored asstartedon each odd) to know a game is live, and thebyBookmakerprices keep updating against that sameoddID, so there is no separate "live feed" to integrate. - Sub-minute updates on Pro. Update cadence runs from 10 minutes on the free tier down to sub-minute on Pro, so an in-play product re-fetches a fast-moving market and sees the new
odds,spread, oroverUnderreflected on each book'sbyBookmakerentry within the cycle. - WebSocket streaming instead of polling. The
/stream/eventsendpoint pushes changedeventIDs over a Pusher WebSocket on the All-Star plan. Subscribe to theevents:livefeed and react to in-game moves as they happen rather than hammering the REST endpoint on a timer. - The live score ships with the live price. Each event exposes
scores.home/scores.awayplusstatus.started/ended, so the in-game score and the current game state come from the same object. There is no second scores API to reconcile against your odds feed. - One
oddIDacross pre-match and in-play. The normalizedoddID(formatstatID-statEntityID-periodID-betTypeID-sideID) identifies the same market before and during the game, so your line-movement and live-update logic joins cleanly. You never re-map each book mid-event. - Per-event-object pricing that fits a polling loop. One event is one object no matter how many books or markets you pull, so refreshing a live slate every cycle stays predictable instead of multiplying cost per market or per book.
What you can build
A live betting product comes down to three jobs. Know which games are in play, keep their prices current, and show the result next to the price. Here is how each one maps to concrete fields.
A live games feed
Filter to in-play games by reading status.started: events that have started but not ended are live right now. Query a league's slate with leagueID and oddsAvailable=true, then keep the events whose status.started is true to build your live tab, while startsAfter/startsBefore scope upcoming games for the pre-match tab. Both tabs read the same byBookmaker prices, so one fetch feeds both views.
Real-time line tracking
To track an in-game line, poll the event (or stream it) and watch each book's byBookmaker entry, where odds, spread, overUnder, and lastUpdatedAt update as the market moves. On Pro you get sub-minute cadence; pair that with the consensus fairOdds and bookOdds on the market to show how the live number is drifting against the no-vig benchmark as the game develops.
Live odds plus live score
An in-play product is only useful if the price and the game state agree. The event carries scores.home/scores.away for the running score plus status.started/status.ended/status.finalized, while each odd carries started/ended. Render the live score beside the live byBookmaker price so a user sees "Over 224.5 at -110, BOS 102 - LAL 96" in one component, both values sourced from a single event object.
Push updates with streaming
For the lowest-latency path, call /stream/events with feed=events:live (All-Star plan) to receive connection details and an initial snapshot, then subscribe over the Pusher WebSocket. The stream pushes the eventIDs that changed; you re-fetch those with eventIDs and update only what moved. That is far lighter than polling every live game on a fixed interval.
Example request
Fetch a live, in-progress NBA event with its odds attached:
curl "https://api.sportsgameodds.com/v2/events?leagueID=NBA&oddsAvailable=true" \
-H "x-api-key: YOUR_API_KEY"
A trimmed live event shows status.started true, a per-book in-game price, and the score riding alongside it:
{
"eventID": "LAL_at_BOS_2026...",
"status": { "started": true, "ended": false, "finalized": false },
"scores": { "home": 102, "away": 96 },
"odds": {
"points-all-game-ou-over": {
"oddID": "points-all-game-ou-over",
"started": true,
"ended": false,
"fairOdds": "-104",
"bookOdds": "-110",
"byBookmaker": {
"draftkings": {
"odds": "-110",
"overUnder": "224.5",
"available": true,
"lastUpdatedAt": "2026-06-26T02:14:53Z"
},
"fanduel": { "odds": "-108", "overUnder": "224.5", "available": true }
}
}
}
}
Here status.started is true so the game is live, DraftKings prices the total at 224.5 with a fresh lastUpdatedAt, and scores reads 102-96 (a live total of 198). The live result sits next to the live line, ready to render in one in-play component. Re-fetch on a sub-minute Pro cadence to keep that number current, or stream it: on All-Star, /stream/events pushes the eventID the moment it changes instead of you polling. See the docs and the real-time streaming guide for the full WebSocket flow.
SportsGameOdds vs building a live feed yourself
| Capability | SportsGameOdds | Build your own live feed |
|---|---|---|
| Live vs pre-match | status.started / started flags in one schema | Track game state across a separate source |
| In-game price updates | byBookmaker with lastUpdatedAt, sub-minute on Pro | Poll and diff every book yourself |
| Push delivery | /stream/events Pusher WebSocket (All-Star) | Stand up your own socket layer per book |
| Live score with the line | scores.home/scores.away + status flags, no second feed | Source and join a results API to your odds |
| Normalized markets | One oddID pre-match and in-play | Re-map each book's IDs mid-game |
| Books covered | 85+ in one call | One integration and rate limit per book |
| Cost as you refresh | Per event object, predictable on a loop | Per-book scraping and infra to maintain |
Rolling your own is a reasonable choice, and it gives you full control over the polling cadence and socket layer. What it costs you shows up most in live data. You are scraping fast-moving prices from every book, normalizing formats that change without notice, reconciling game state from a separate results source, and keeping a socket layer alive, all while a game is in progress. SportsGameOdds absorbs that work so you can spend your time on the live UX.
Frequently asked questions
Related use cases
- Sports Odds API for Betting Apps: power a full betting app with odds, scores, and settlement.
- Odds Comparison & Line Shopping API: surface the best price across every book.
- Live Scores & Sports Data API: live scores, game status, and box scores to match.
- Odds API for Betting Alert Bots: fire alerts when a live line moves past a threshold.
- Real-time streaming guide: the WebSocket flow for push updates.
- Pricing: per-event-object plans, with sub-minute updates on Pro and streaming on All-Star.
Build your live betting product
Free plan available. Set up in 5 minutes. No credit card required.