Skip to main content

What it streams

Realtime odds updates for long-term or season-based markets (“futures”), scoped to a futureId. Each update contains one or more prices per outcome, per bookmaker. Odds are grouped by bookmaker and keyed by outcome within each bookmaker.

Routing

  • Entity key: payload.futureId
  • Filters: sportIds, tournamentIds, futureIds, bookmakers
  • Bookmaker-gated: ✅ Yes

Delivery semantics

  • This channel is high throughput
  • Updates are latest state only
  • Intermediate odds may be coalesced or dropped if the client lags
  • Do not rely on tick-by-tick delivery — treat it as a state stream

Payload structure

oddsId:
<futureId>:<bookmaker>:<outcomeId>:<participantId>:<playerId>

outcome object (full schema)

Each entry in the oddsFutures map is an outcome, similar to the one used in the odds channel.
FieldTypeDescription
bookmakerstringBookmaker slug (e.g. "stake", "pinnacle", "polymarket")
outcomeIdintegerID of the outcome
participantIdinteger | nullParticipant (team/player) the odds apply to
playerIdintegerPlayer ID (0 for non-player markets)
pricenumberDecimal odds
activebooleanWhether the outcome is currently available
bookmakerOutcomeIdstring | nullBookmaker-native outcome ID
bookmakerChangedAtinteger | nullBookmaker-provided update timestamp (ms)
priceFractional`string`Fractional odds (e.g. "5/2")
priceAmerican`integer`American odds (e.g. +200, -120)
limitnumber | nullMax allowed stake (if applicable)
betslipstring | nullOptional bookmaker betslip/deeplink info
metaobject | nullBookmaker-specific metadata (e.g. ladders, ticks)
changedAtintegerEpoch milliseconds (UTC) when received by the gateway

Example: traditional bookmaker odds for futures

{
  "channel": "oddsFutures",
  "type": "UPDATE",
  "payload": {
    "futureId": "id11028543137888",
    "oddsFutures": {
      "stake": {
        "id11028543137888:stake:141:5432:0": {
          "bookmaker": "stake",
          "outcomeId": 141,
          "participantId": 5432,
          "playerId": 0,
          "price": 4.25,
          "active": true,
          "priceAmerican": +325,
          "priceFractional": "13/4",
          "limit": 500,
          "changedAt": 1766940100000
        }
      }
    }
  },
  "ts": 1766940100023,
  "entryId": "1766940100023-456"
}

Example: prediction market odds with orderbook metadata

{
  "channel": "oddsFutures",
  "type": "UPDATE",
  "payload": {
    "futureId": "id11028543137888",
    "oddsFutures": {
      "polymarket": {
        "id11028543137888:polymarket:141:5432:0": {
          "bookmaker": "polymarket",
          "outcomeId": 141,
          "participantId": 5432,
          "playerId": 0,
          "price": 3.25,
          "active": true,
          "bookmakerOutcomeId": "abc123xyz",
          "limit": 50,
          "meta": {
            "back": [
              { "price": 3.25, "size": 20 },
              { "price": 3.10, "size": 40 }
            ],
            "lay": [
              { "price": 3.40, "size": 15 }
            ]
          },
          "changedAt": 1766940123456
        }
      }
    }
  },
  "ts": 1766940123458,
  "entryId": "1766940123458-501"
}

Implementation guidance

  • Always use the oddsId as the unique ID for odds
  • Normalize prices as needed (decimal → American, etc.)
  • Join futureId to:
  • Use active=false to pause display or betting logic
  • Preserve all fields in meta even if unused (for forward compatibility)