Skip to main content

Live Events

GET /events/live returns all currently in-play events, optionally filtered by sport:
Each event includes live scores and, where available, a clock object with the current match clock. The same clock field also appears on live events returned by GET /events?status=live and GET /events/{id}.

The Clock Object

Live events carry an optional clock field:
A few things to know:
  • clock is omitted entirely when no clock data is available for an event. Treat it as optional.
  • minute and playedSeconds are extrapolated server-side from the live feed, so they stay accurate even when the response is served from cache.
  • The clock only advances while running is true. During half-time and other breaks it freezes at the last played second.
  • Within a period, backward feed corrections freeze the served clock at its last value with running: false until the feed catches up. The hold does not expire into a backward jump. A change of period resets the floor immediately.
  • For a per-second ticker in your UI, extrapolate client-side from playedSeconds at the moment you received the response, while running is true.
  • On WebSocket, the clock rides on live score/status messages, but those fire only on real events. Seed the initial clock with one GET /events/live on connect, then let the WebSocket re-anchor it.
  • Some events have no played clock at all, for example ice hockey games with basic coverage. Their clock carries period and statusDetail only, plus periodStartedAt when the feed reports when the period began. That is wall time, not game time: a hockey clock stops at every whistle, so the time since periodStartedAt is longer than the time played. Show it as elapsed wall time (for example “P1, started 12m ago”), never as playedSeconds. It is omitted when missing, in the future, or more than 3 hours old, and it also appears in WebSocket clock snapshots.

Period Scores

Every event’s scores object has the headline home/away plus a periods map. The keys are the same for every sport and every source, on /events, /historical, /settlements and WebSocket score and status messages: The headline score never includes a penalty shootout. It is the result after overtime when there was overtime, otherwise the result after regulation. To get one part on its own:
  • overtime or extra time alone: ot minus ft
  • the shootout alone: ap minus ot (or minus ft when there was no extra time). In ice hockey the provider usually counts the shootout as one deciding goal for the winner, so this reads 1-0 or 0-1.
ft, ot and ap are written once that phase is over, and only when the source reports them, so treat every key as optional. A football cup tie that went to extra time and penalties:
The match was 3-3 after 90 minutes and after extra time, and the away side won the shootout 4-3. A basketball game decided in overtime:
Some events also carry older spellings next to these keys: period1 to period5, overtime and penalties (and fulltime on some older historical events). Read the keys above instead. The older spellings stop on 12 November 2026, 09:00 UTC. See the changelog.

Cricket Scores

Cricket has no match clock, so live cricket events carry no clock object. The per-innings detail lives in scores.periods instead, keyed inning1, inning2 and so on:
A few things to know:
  • wickets and overs are cricket only. They are omitted for every other sport, so existing period scores keep exactly their home/away shape.
  • Both are omitted when the source does not publish them, so treat them as optional even on cricket.
  • A side that has not yet batted reads 0, not a missing key.
  • Coverage varies by competition. Major internationals and the larger franchise leagues carry full innings detail; smaller domestic competitions may return a match-level score with no periods at all.

statusDetail values

statusDetail is the live feed’s phase description passed through as-is. The exact strings vary by sport; treat it as display text rather than an enum, and use period + running for any betting logic. Values you can expect:

Rendering a football clock the conventional way

minute is cumulative elapsed play, so first-half stoppage time reads 46, 47, 48… To render the conventional 45+X / 90+X style, cap the minute at the period boundary:
injuryTime carries the announced stoppage minutes when the fourth official raises the board, so 45+2 with injuryTime: 4 tells you about two more minutes of the half remain.

Participant Logos

GET /participants/{id}/logo returns the team or player crest as a PNG, served directly from the Odds-API domain:
Use the homeId / awayId fields from event responses as the participant id, or look ids up via GET /participants.
  • Responses include Cache-Control: public, max-age=86400, so browsers and CDNs cache them for a day. You can hotlink the URL in an <img> tag.
  • Returns 404 when no logo exists for the participant. Misses are cached server-side, so repeated lookups for logo-less participants stay fast.
  • Logos are served from our infrastructure; no third-party provider URLs are exposed to your users.
  • Esports teams are covered as well as traditional sports.

Esports Events

Esports events carry an extra esports object on /events, /events/live, /events/search and /events/{id}. It is absent for every other sport.

Esports teams

GET /participants?sport=esports adds two fields to each team: game, the slug of the game the team plays, and shortCode when one is known.
An organisation that fields teams in several games has one participant per game, so a name like G2 Esports appears more than once. Use game to tell them apart, and always take the id from the event’s homeId / awayId when you need the team that is actually playing.

Next Steps

  • Stream live scores and match status over WebSocket instead of polling, see the WebSocket guide
  • Fetch odds for live events with Fetching Odds