Props

List today's games

Games with player props posted for the given sport, merged across free books. Live games first. This is a schedule/event-discovery feed in its own right: use it to learn what is on the board before asking for props. An empty list is classified (emptyReason) so an off day, a season break and a source outage are told apart, and pollAdvice says what a poller should do next. data.refreshCadenceSeconds is how often the board behind it actually rebuilds; polling faster than that cannot return anything new. When the board identity is pinned the response carries a strong ETag: send it back as If-None-Match and an unchanged board answers 304 with no body. A 304 still authenticates and still counts against your rate limit; what it saves is the transfer.

Poll it like this: keep the ETag, treat 304 as "same board", and wait as long as pollAdvice says. stop_until_coverage_returns (offseason) and wait_for_refresh on no_games_scheduled are expected schedules, not errors; backoff_source means the upstream source is down or stale.

let etag = null;
async function poll() {
  const res = await fetch('https://api.flashodds.live/api/v1/games?sport=cs2', {
    headers: { Authorization: `Bearer ${KEY}`, ...(etag ? { 'If-None-Match': etag } : {}) }
  });
  let wait = 300;
  if (res.status !== 304) {
    etag = res.headers.get('ETag') ?? etag;
    const body = await res.json();
    wait = body.pollAdvice.suggestedSeconds ?? body.data.refreshCadenceSeconds;
    if (body.empty) console.log(body.emptyReason, body.pollAdvice.action);
    else render(body.games);
  }
  setTimeout(poll, wait * 1000);
}
get/api/v1/games

Request

  • Base URL: https://api.flashodds.live
  • URL: https://api.flashodds.live/api/v1/games
  • Auth: HTTP bearer

Query parameters

sport'nba' | 'basketball' | 'mlb' | 'nfl' | 'nhl' | 'ncaab' | 'ncaaf' | 'soccer' | 'tennis' | 'ufc' | 'cs2' | 'valorant' | 'dota2' | 'esports' | 'cod'

Sport id. One of: nba, basketball, mlb, nfl, nhl, ncaab, ncaaf, soccer, tennis, ufc, cs2, valorant, dota2, esports, cod. See GET /sports.

Example:mlb

Headers

if-none-matchstring

An ETag from a previous /games response. Unchanged board answers 304.

Response

Games list

sportstring required
countinteger required
snapshotIdstring nullable required

Logical board identity; matches /sports snapshotId for the same board. Null when consistency is not single.

snapshotConsistency'single' | 'mixed' | 'none' required

single = every row came from one upstream snapshot. mixed = rows span snapshots (treat as partial). none = no source snapshot.

emptyboolean required

True when no games are on the board.

emptyReason'offseason' | 'no_games_scheduled' | 'no_props_posted' | 'no_filter_matches' | 'source_unavailable' | 'source_stale' | 'outside_supported_window' | 'tier_limit' | 'unknown' | 'null' nullable required

Why the result is empty. Null when it is not. A healthy empty slate is distinguishable from a source failure.

messagestring nullable required

Human-readable explanation of an empty result.

Example response

{
  "games": [
    {
      "id": "ud-143111",
      "sport": "mlb",
      "homeTeam": "Detroit Tigers",
      "awayTeam": "Philadelphia Phillies",
      "startTime": "2026-07-11T23:10:00.000Z"
    }
  ]
}

Changes

No recorded changes to this operation across all 1 revision of this API.