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.

Updated June 2026Built on the live SportsGameOdds feed

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 /events market shape carries upcoming prices and in-game prices. Read status.started (mirrored as started on each odd) to know a game is live, and the byBookmaker prices keep updating against that same oddID, 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, or overUnder reflected on each book's byBookmaker entry within the cycle.
  • WebSocket streaming instead of polling. The /stream/events endpoint pushes changed eventIDs over a Pusher WebSocket on the All-Star plan. Subscribe to the events:live feed 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.away plus status.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 oddID across pre-match and in-play. The normalized oddID (format statID-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

CapabilitySportsGameOddsBuild your own live feed
Live vs pre-matchstatus.started / started flags in one schemaTrack game state across a separate source
In-game price updatesbyBookmaker with lastUpdatedAt, sub-minute on ProPoll 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 linescores.home/scores.away + status flags, no second feedSource and join a results API to your odds
Normalized marketsOne oddID pre-match and in-playRe-map each book's IDs mid-game
Books covered85+ in one callOne integration and rate limit per book
Cost as you refreshPer event object, predictable on a loopPer-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

Build your live betting product

Free plan available. Set up in 5 minutes. No credit card required.