Language prefix
All endpoints are prefixed with a language code:/en/.../de/.../fr/...
sportId, fixtureId, etc.) are language-independent.
Sports, tournaments, seasons
sportId
- Integer.
- The first two digits embedded into several downstream IDs.
- Discover via
/sports.
tournamentId
- Integer.
- Belongs to exactly one sport.
- Discover via
/tournaments.
seasonId
- Integer.
- Belongs to exactly one tournament.
- Discover via
/seasons.
See the full Sports Coverage table for every sportId and whether it’s available as fixtures, futures, or both.
Markets and outcomes
TL;DR — Every selection follows a fixed hierarchy:
marketType → period → handicap → side, all baked into the outcomeId — so the same bet always resolves to the same marketId / outcomeId, addressed by coordinates rather than bookmaker name strings. The one part not in outcomeId is the player, carried by playerId. All outcomes of a market share its marketId, which equals the market’s first outcomeId.How markets decompose (the deterministic hierarchy)
EveryoutcomeId comes from a single, deterministic decomposition — OddsPapi splits each market into a fixed hierarchy:
marketId / outcomeId across bookmakers and fixtures.
| Level | Field | Meaning |
|---|---|---|
| 1 | marketType | The kind of market (1x2, totals, spreads, spreads-european, bothteamsscore, drawnobet, oddeven, …). |
| 2 | period | The segment the market applies to (fulltime, p1, p2). |
| 3 | handicap | The line value / specifier (e.g. 2.5, -0.25). Each distinct line value is its own marketId. 0.0 for lineless markets like 1x2. |
| 4 | outcomeName | The side of the market (Over / Under, 1 / X / 2, Yes / No, …). |
Key rule: because every line value gets its ownmarketId, “Over 2.5” and “Over 3.5” are different markets — not two outcomes of one market. Within a singlemarketId, the outcomes are only the sides of that exact line (e.g.Over 2.5+Under 2.5).
Worked example — soccer (sportId 10)
Worked example — soccer (sportId 10)
A representative slice of the real soccer market map. Each
Reading the first row:
marketId equals its first outcomeId, and each line value is its own market:| marketId | marketName | marketType | period | handicap | outcomeId | outcomeName |
|---|---|---|---|---|---|---|
| 101 | Full Time Result | 1x2 | fulltime | 0.0 | 101 | 1 |
| 101 | Full Time Result | 1x2 | fulltime | 0.0 | 102 | X |
| 101 | Full Time Result | 1x2 | fulltime | 0.0 | 103 | 2 |
| 104 | Both Teams To Score | bothteamsscore | fulltime | 0.0 | 104 | Yes |
| 104 | Both Teams To Score | bothteamsscore | fulltime | 0.0 | 105 | No |
| 106 | Over Under Full Time | totals | fulltime | 0.5 | 106 | Over |
| 106 | Over Under Full Time | totals | fulltime | 0.5 | 107 | Under |
| 1010 | Over Under Full Time | totals | fulltime | 2.5 | 1010 | Over |
| 1010 | Over Under Full Time | totals | fulltime | 2.5 | 1011 | Under |
| 1068 | Asian Handicap | spreads | fulltime | -0.5 | 1068 | 1 |
| 1068 | Asian Handicap | spreads | fulltime | -0.5 | 1069 | 2 |
| 10122 | European Handicap | spreads-european | fulltime | 6.0 | 10122 | 1 |
| 10122 | European Handicap | spreads-european | fulltime | 6.0 | 10123 | X |
| 10122 | European Handicap | spreads-european | fulltime | 6.0 | 10124 | 2 |
| 10208 | First Half Result | 1x2 | p1 | 0.0 | 10208 | 1 |
| 10208 | First Half Result | 1x2 | p1 | 0.0 | 10209 | X |
| 10208 | First Half Result | 1x2 | p1 | 0.0 | 10210 | 2 |
| 10214 | Draw No Bet | drawnobet | fulltime | 0.0 | 10214 | 1 |
| 10214 | Draw No Bet | drawnobet | fulltime | 0.0 | 10215 | 2 |
| 10222 | Odd Even Full Time | oddeven | fulltime | 0.0 | 10222 | Odd |
| 10222 | Odd Even Full Time | oddeven | fulltime | 0.0 | 10223 | Even |
| 10224 | Over Under Team 1 | teamtotals-team1 | fulltime | 0.5 | 10224 | Over |
| 10224 | Over Under Team 1 | teamtotals-team1 | fulltime | 0.5 | 10225 | Under |
marketType=1x2, period=fulltime, handicap=0.0, outcomeName=1 — the home side of the full-time match-result market.Relationship between marketId and outcomeId
Markets and outcomes are tightly coupled by design:
- A market represents a complete betting market (for example moneyline, 1x2, totals).
- A market contains multiple outcomes.
- All outcomes that belong to the same market share the same
marketId. - The first
outcomeIdof a market is always equal to themarketId.
ID structure
BothmarketId and outcomeId are integers constructed as:
11xxxx→ basketball market or outcome14xxxx→ American football market or outcome
- Unlimited markets and outcomes per sport
- Fast grouping by sport
- Immediate visibility of market relationships
Why marketId matters (arbitrage & modeling)
All outcomes under a single marketId together represent a complete probability space.
This makes marketId especially useful for:
- Arbitrage detection
- Overround / margin calculations
- Probability normalization
- Market completeness checks
marketId.
Participants and players
participantId
- Integer.
- Represents teams or competitors in fixtures.
- Discover via
/participants.
playerId
- Integer.
- Used for player proposition markets.
playerId = 0typically represents a non-player market.- Discover via
/players.
Fixture IDs
fixtureId structure
fixtureId is a string that encodes multiple pieces of information:
id→ provider identifier / short slug11→ sportId (2 digits)000132→ tournamentId (6 digits)62926199→ provider’s native fixture ID
fixtureId alone you can infer the sport, tournament, and upstream provider — handy for logging and cross-system correlation.
Future IDs
futureId structure
futureId follows a similar principle:
fixtureId.
Odds identifiers
TL;DR — A single price is uniquely keyed by
{fixtureId}:{bookmaker}:{outcomeId}:{playerId} (fixtures) or {futureId}:{bookmaker}:{participantId} (futures). Use these oddsId strings as primary keys in your storage for clean dedup, updates, and reconciliation.Fixture odds keys
For fixtures, a single price is uniquely identified by:bookmaker and you have the selection itself — {fixtureId}:{outcomeId}:{playerId} — the bookmaker-independent key for grading / settlement, since a selection wins or loses the same way everywhere. No marketId is needed; the outcomeId already encodes the market.
Future odds IDs
For futures, odds are uniquely identified by:Timestamps (seconds vs milliseconds)
This API intentionally uses both epoch seconds and epoch milliseconds, depending on context.Epoch seconds (UTC)
Used for scheduled or coarse-grained time values:startTimestartTimeFromstartTimeTo
Epoch milliseconds (UTC)
Used for high-frequency price updates:changedAt- Odds
sincefilters for fixtures - Futures odds
createdAt
Recommendation
- Store timestamps as integers.
- Do not assume milliseconds where seconds are documented (or vice versa).
- Normalize internally only if needed.
Operating tips
Server Location Matters
To achieve the lowest latency for realtime updates:- The fastest delivery regions are Central Europe (recommended) and US East.
- For best performance, deploy your backend in the same datacenters we use, such as:
- If you’re building prediction markets or models sensitive to latency, consider:
- Deploying in Austria (AT) via Netcup, or
- Using AWS eu-west-1 (Ireland)
⚡ Servers colocated near our streaming infrastructure receive updates faster and with fewer hops.
Snapshot + realtime pattern
A reliable integration pattern:Efficient backfills
- Use
sinceparameters where available - Avoid full historical fetches unless required
- Store odds keyed by their odds identifiers for deduplication
Rate limits
See Rate Limits for headers, per-endpoint limits, and 429 backoff handling.Historical odds and CLV
The realtime WebSocketodds and oddsFutures channels deliver latest state — optimized for low-latency trading, they coalesce or drop intermediate updates under load and are not a tick ledger.
Use the live stream to trade, and the REST history endpoints to measure — CLV models, fill auditing, and backtests.When you need the full price movement of an outcome, or its opening vs closing line, use the REST history endpoints. They share the same
oddsId format ({fixtureId}:{bookmaker}:{outcomeId}:{playerId}) as the live odds channel, so you can join realtime fills directly to their historical and closing-line records.
| Purpose | Fixtures | Futures |
|---|---|---|
| Full price timeline | GET /fixtures/odds/historical | GET /futures/odds/historical |
| Opening vs closing line (OLV/CLV) | GET /fixtures/odds/clv | GET /futures/odds/clv |
- CLV modelling — compare your fill price against the closing line to measure edge.
- Fill auditing — reconcile traded prices with the recorded timeline to detect slippage.
- Backtesting — replay the full historical timeline to test strategies against real line movement.
Glossary
Quick definitions of the core terms used throughout the API. Identifiers & data model- sportId — Numeric sport identifier; the first two digits of downstream
marketId,outcomeId, andfixtureId. - fixtureId — String key for a single match/event, encoding provider, sport, tournament, and provider fixture ID.
- futureId — String key for a futures / outright market, encoding provider, sport, season, and market.
- marketType — The kind of market (
1x2,totals,spreads,bothteamsscore, …). - period — The segment a market applies to (
fulltime,p1,p2). - handicap — The line value / specifier of a market; each distinct line value is its own
marketId. - marketId — Integer grouping all outcomes of one market; equals the market’s first
outcomeId. - outcomeId — Integer identifying one fully-decomposed selection:
marketType+period+handicap(line) + side. It encodes everything except the player — that’s whatplayerIdadds. - playerId — Ties an outcome to a player for player markets;
playerId = 0is a non-player market. - participantId — Integer identifying a team or competitor in a fixture.
- oddsId — Composite price key. Fixtures:
{fixtureId}:{bookmaker}:{outcomeId}:{playerId}. Futures:{futureId}:{bookmaker}:{participantId}.
- OLV — Opening line value: the outcome’s first recorded price.
- CLV — Closing line value: the outcome’s last price before settlement; the reference for grading execution.
- staleOdds — Flag indicating a bookmaker’s connectivity is degraded, so its odds may not be current.
- settlement — Post-event endpoints returning per-outcome results (won / lost), final scores, and margins.
- serverEpoch + entryId — The per-channel cursor; a change in
serverEpochmeans the client must re-snapshot. - resume / replay — Reconnect and replay missed messages within
resumeWindowMs(default60000). - snapshot_required — Signal that the cursor is outside the resume window and a fresh REST snapshot is needed.