---
title: "Player props for one game"
method: GET
path: "/api/v1/games/{eventId}/props"
tags: ["Props"]
---

# Player props for one game

`GET /api/v1/games/{eventId}/props`

## Request

- Base URL: `https://api.flashodds.live`
- URL: `https://api.flashodds.live/api/v1/games/{eventId}/props`
- Auth: HTTP bearer

## Path parameters

- `eventId` string, required: Event id from GET /games.

## Query parameters

- `stats` string: Comma-separated stat filter.
- `sport` string

## Response `200`

Props for the game

- PropsResult
  - `eventId` string, required
  - `sport` string, required
  - `homeTeam` string, required
  - `awayTeam` string, required
  - `startTime` string, required
  - `props` PlayerProp[], required
    - `player` string, required
    - `stat` string, required: Stat key. NBA: points | rebounds | assists | threes | pra. Other sports use descriptive keys (strikeouts, total_bases, passing_yards, goals, ...).
    - `line` number, required: The posted over/under line.
    - `overOdds` number: American odds for the over / higher.
    - `underOdds` number: American odds for the under / lower.
    - `bookCount` integer, required: Number of sources contributing this line (currently 1).
    - `playerId` string: The source's own player id (Underdog today). Not canonical: it changes if the source renumbers.
    - `flashPlayerId` string: Canonical Flash player id: deterministic from sport + normalized name, so spelling variants of one player share it and the same name in two sports does not. Pass it to GET /changes?playerId=.
    - `teamSide` 'home' | 'away': Which side of the event this player is on, as the source assigns it (its team id for this appearance matched to the event's home/away team id). Pair with homeTeam/awayTeam on scan rows. Absent when the source does not say, e.g. head-to-head events. Never inferred.
    - `liveValue` number: Current in-game stat count (live games only).
    - `gameClock` string
    - `gameState` 'pre' | 'live' | 'final'
    - `variant` 'main' | 'alternate' | 'goblin' | 'demon' | 'milestone' | 'other': Which line within the market. main = the standard two-way line. goblin = easier line at a reduced payout. demon = harder line at a boosted payout. Classified from the provider’s own payout multiplier, never guessed from the number.
    - `variantLabel` string
    - `isMainLine` boolean: True for the standard line. Filter with ?mainLinesOnly=true.
    - `alternateLine` boolean
    - `payoutMultiplier` number: Provider payout multiplier. 1.0 is standard.
    - `sourceLineId` string: The provider’s id for this specific line.
    - `market` object: Self-describing market metadata (label, family, scope, unit, projectability) for this row. Always present on API responses; optional only on the internal pre-enrichment shape.
      - `statKey` string, required: Raw normalized stat key on the prop row.
      - `label` string, required: Human display label.
      - `family` string, required: Market family: kills | fantasy | points | total_bases | ...
      - `scopeKind` 'map' | 'maps' | 'full_game' | 'match' | 'season', required: What the scope spans.
      - `scope` string, required: Stable scope filter key: map1 | maps13 | full_game.
      - `scopeLabel` string, required
      - `unit` string, nullable, required: The noun the number counts, or null when ambiguous.
      - `displayOrder` integer, required: Reading order within the sport (lower first).
      - `uiGroup` string, required: Recommended grouping bucket (= family).
      - `projection` MarketProjectionSupport, required
        - `supported` boolean, required: Whether a Flash projection is available for this market.
        - `unsupported` 'not_modeled' | 'fantasy_scoring' | 'scoped_market' | 'no_provider' | 'null', nullable, required: Machine-readable reason a market is not projectable. not_modeled = a real stat the provider does not model yet (makes a board partial); fantasy_scoring, scoped_market and no_provider are structural. Null when supported.
        - `reason` string, nullable, required: Why a projection is unavailable. Never null when supported=false (no silent omission).
      - `contextSupported` boolean, required: /context/player carries recent-form for this market.
      - `lineOnly` boolean, required: No Flash projection for this market today.
      - `alternateLine` boolean, required: Reserved; false until an alternate-line feed exists.
      - `rawStat` string, required: The stat key exactly as the source posted it, before alias resolution. The board posts several spellings for one market (receiving_yds vs receiving_yards), so statKey is normalized for grouping while this preserves the original.
      - `aliased` boolean, required: True when rawStat resolved to a different canonical statKey.
    - `flashProjection` FlashProjection: Flash's own baseline projection, present when the sport's registered provider models this market and its pack covers the player. Absent = no model, never fabricated; see market.projection.reason. Check `basis`: prior_season is not current form.
      - `value` number, required: Flash season-baseline projection, rounded to 0.5.
      - `sampleN` integer, required: Baseline sample size (maps/games), never the smaller recent-form n.
      - `method` string, required: How the baseline was built. Carries the season in parentheses when basis is prior_season.
      - `marketKey` string, required: Key into /context/player's `markets` map for this same prop.
      - `basis` 'current_season' | 'prior_season' | 'mixed_history', required: Which season's play this projection is built from. current_season = the season the prop is for. prior_season = an earlier season, because the prop season has no usable data in the pack. mixed_history = a few current-season games topped up with the most recent prior-season games. A prior_season projection is NOT current form and must never be presented as such; a mixed_history one is only partly current form.
      - `seasonId` string, nullable, required: The season the underlying play came from, when the pack records it. Null when unknown.
      - `basisNote` string, nullable, required: Plain-English provenance caveat. Always set when basis is prior_season or mixed_history; null otherwise.
    - `projectionAvailability` ProjectionAvailability: Whether this row is projected and, when it is not, a stable reasonCode (identity_ambiguous, insufficient_history, unsupported_market, ...). Absent when there is no row-level explanation to give; never guessed.
      - `status` 'projected' | 'line_only', required
      - `reasonCode` 'no_provider' | 'unsupported_market' | 'insufficient_history' | 'identity_unresolved' | 'identity_ambiguous' | 'source_stale' | 'source_unavailable' | 'rights_blocked' | 'model_shadow_only' | 'market_shadow_only' | 'missing_opponent' | 'missing_event' | 'invalid_line' | 'offseason' | 'quality_gate_failed' | 'null', nullable, required: Stable machine-readable reason a row is line-only. Null when status is projected.
      - `reason` string, nullable, required: Plain-English explanation. Null when status is projected.
  - `sources` string[], required
  - `fetchedAt` number, required: Epoch ms when the upstream snapshot was taken.
  - `delayed` boolean, required: Reserved. Always false today: every tier serves the same live snapshot.
  - `snapshotId` string, 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.

## Other responses

- `400`: Invalid request
- `401`: Missing or invalid API key
- `403`: Not permitted on your tier
- `404`: No props for this event
- `429`: Rate limit or daily quota exceeded

---

[API](https://skmtc.dev/flashodds/apis/flash-props-api.md) · [All operations](https://skmtc.dev/flashodds/apis/flash-props-api/llms.txt) · [OpenAPI document](https://skmtc.dev/flashodds/apis/flash-props-api/revisions/044161ffbfd8?raw)
