Skip to main content
本页解释Odds API中使用的核心概念:ID如何构建、实体之间如何关联、时间戳如何使用,以及如何设计可靠的客户端存储。

语言前缀

所有端点都以语言代码为前缀:
  • /zh/... (中文)
  • /en/... (英文)
  • /de/... (德文)
翻译字段(例如名称)在可用时遵循前缀语言。 标识符(sportId、fixtureId等)与语言无关。

体育、锦标赛、赛季

sportId

  • 整数。
  • 嵌入到多个下游ID中的前两位数字。
  • 通过/sports发现。

tournamentId

  • 整数。
  • 属于恰好一项体育运动。
  • 通过/tournaments发现。

seasonId

  • 整数。
  • 属于恰好一个锦标赛。
  • 通过/seasons发现。
完整的运动覆盖表列出了每个 sportId 及其是否以赛事、期货或两者形式提供。

实体层级

API 中的一切都挂在同一棵树上:
锦标赛是周期性存在的事物(“英超联赛”、“美国总统大选”),赛季是它的一届有时间边界的实例(“英超 25/26”、“2028 年美国总统大选”)。赛事和期货都位于某个赛季之内。

赛事如何运作(体育)

**赛事(fixture)**是两个参与者(球队或球员)之间的单场比赛:
  • 赛事对象承载日程与状态:startTime(纪元秒)、statusId、participant1Id / participant2Id、seasonId、场馆 —— 完整结构见 fixtures 频道和 REST 参考。
  • 比分按赛段存储,以 result、p1、p2……为键 —— result 行是权威的最终/当前比分;赛段行用于结算赛段盘口。参见 scores 频道。
  • 赔率通过下方的赔率标识符附加到赛事上 —— 每个价格对应一个 {fixtureId}:{bookmaker}:{outcomeId}:{playerId}。

期货如何运作(预测市场)

**期货(future)**是针对整个赛季或事件(而非单场比赛)的冠军类盘口 —— “谁将赢得英超?” —— 同一模型也覆盖非体育预测市场(“谁将赢得 2028 年美国大选?”、“比特币会涨到 10 万美元吗?”)。 对于体育项目,期货挂在与其赛事完全相同的赛季之下 —— 只有叶子节点不同:
与上文的赛事示例对比:阿森纳 vs 切尔西是赛季 130281 中的一场比赛;Winner 期货则是针对整个赛季的盘口。同一棵树、同一个 seasonId —— 赛事在 90 分钟内出结果,期货在赛季结束时出结果。 非体育预测市场复用完全相同的模型 —— 周期性主题即锦标赛,每一届即赛季:
  • 一个期货 = 一个赛季内的一个冠军类盘口。futureId 末尾的 futureMarketId 表示盘口种类。它按运动分配,因此同一个问题在每项运动中都是不同的盘口:
因此足球的 Winner 盘口是 10001,政治的 Prediction 盘口是 69002。位置 002 在体育项目中是 topscorer,在非体育区间中是 prediction —— 二者永不冲突,因为没有任何一项运动同时拥有两者。
  • 期货赔率以 {futureId}:{bookmaker}:{futureOutcomeId}:{participantId} 为键 —— 参见期货赔率ID。
  • 非体育主题(政治、选举、金融、加密货币、天气……)被建模为 sportId 69+ 的”运动”,且仅以期货形式存在;赛马类(79–81)为赛前(ante-post)期货。确切区间见运动覆盖。

盘口和选项

摘要 —— 每个选项都遵循固定层级:marketType → period → handicap → side,全部编码进 outcomeId —— 因此同一个投注始终解析为相同的 marketId / outcomeId,通过坐标定位而非对博彩公司名称做字符串匹配。唯一不在 outcomeId 中的是球员,由 playerId 承载。同一盘口的所有选项共享其 marketId,即该盘口的首个 outcomeId。
实际承载哪些市场类型、线值、赛段与球员盘,参见盘口覆盖。

盘口如何分解(确定性层级)

每一个 outcomeId 都由单一、确定性的分解逻辑生成 —— OddsPapi 将每个盘口拆分为固定层级:
因此”全场总进球大于 2.5”在不同博彩公司和不同赛事中始终落在相同的 marketId / outcomeId 上。
关键规则: 由于每个盘口线都有自己的 marketId,“大于 2.5” 和 “大于 3.5” 是不同的盘口 —— 而非同一盘口的两个选项。在单个 marketId 内,选项仅为该确切盘口线的各个方向(例如 Over 2.5 + Under 2.5)。
真实足球盘口映射的代表性切片。每个 marketId 等于其首个 outcomeId,且每个盘口线都是独立的盘口:读取第一行:marketType=1x2、period=fulltime、handicap=0.0、outcomeName=1 —— 即全场比赛结果盘口的主队方向。

marketId和outcomeId之间的关系

盘口和选项在设计上紧密耦合:
  • 盘口代表一个完整的投注市场(例如独赢、1x2、大小球)。
  • 盘口包含多个选项。
  • 属于同一盘口的所有选项共享相同的marketId。
  • 盘口的第一个outcomeId始终等于marketId。
这使得可以无需额外元数据即可确定哪些选项属于哪个盘口。

marketLength

marketLength 是一个 marketId 下的选项数量 —— 即可供投注的方向数,它们共同构成完整的概率空间(在去除利润率之前,其隐含概率之和约等于 1)。示例:moneyline → 2、1x2 → 3、winningmargin → 所提供的赢球差区间数量。

ID结构

marketId和outcomeId都是整数,构造如下:
示例:
  • 11xxxx → 篮球盘口或选项
  • 14xxxx → 美式橄榄球盘口或选项
这种设计提供:
  • 每项运动无限的盘口和选项
  • 按运动快速分组
  • 立即可见的盘口关系

为什么marketId很重要(套利和建模)

单个marketId下的所有选项共同代表一个完整的概率空间。 这使得marketId特别适用于:
  • 套利检测
  • 超出率/利润率计算
  • 概率归一化
  • 盘口完整性检查
建议: 如果您执行套利或定价逻辑,请始终按marketId对赔率分组。

参与者和球员

participantId

  • 整数。
  • 代表赛事中的球队或参赛者。
  • 通过/participants发现。

playerId

  • 整数。
  • 用于球员投注盘口。
  • playerId = 0通常代表非球员盘口。
  • 通过/players发现。

赛事ID

fixtureId结构

fixtureId是一个编码多条信息的字符串:
概念示例:
其中:
  • id → 内部命名空间前缀 —— 视为不透明值
  • 11 → sportId(2位数字)
  • 000132 → tournamentId(6位数字)
  • 62926199 → 该命名空间内的原生赛事ID
仅从 fixtureId 即可推断出运动和锦标赛 —— 便于日志记录和跨系统关联。 若要与另一套系统的赛事 ID 关联,请使用赛事频道上的 externalProviders 区块或映射端点 —— 参见作为第二数据源运行 OddsPapi。

期货ID

futureId结构

futureId遵循与fixtureId相同的原则:
其中:
  • prefix → 内部命名空间前缀(例如 id、pm、ks)—— 视为不透明值
  • sportId → 2位数字
  • seasonId → 赛季/赛事实例
  • futureMarketId → 该期货所问的冠军盘口(5位数字 —— 见下文)
这编码了运动、赛季与盘口问题 —— 每个(赛季,问题)对应一个期货。 锦标赛是期货上的一个字段,而非 ID 的一个片段。请从 futures 负载的 tournament.tournamentId 读取;将其排除在 ID 之外,正是为了在提供商把某赛季重新挂到另一个锦标赛下时,futureId 仍保持稳定。

期货盘口与选项

期货盘口是一种问题类型 —— “谁赢得英超?""谁是最佳射手?""X 会在 Y 之前发生吗?” —— 而非统计模板。同一个盘口被提出该问题的每个期货复用,并由 futures 负载上的 market.marketId 标识:即 futureId 末尾携带的同一个 5 位 futureMarketId。 盘口有两种形态: 与赛事盘口有两处刻意的差异:
  • handicap 位于选项上,而非盘口上。 对赛事而言每条线值都是独立的 marketId。期货是按(赛季,问题)铸造的,铸造时无从得知某家博彩商会提供哪一档线值梯度,因此一个期货盘口承载多条线值。
  • 没有 period。 期货在其赛季或问题出结果时结算。

赔率标识符

摘要 —— 单个价格由 {fixtureId}:{bookmaker}:{outcomeId}:{playerId}(赛事)或 {futureId}:{bookmaker}:{futureOutcomeId}:{participantId}(期货)唯一标识。请将这些 oddsId 字符串用作存储中的主键,以实现干净的去重、更新与对账。

赛事赔率键

对于赛事,单个价格由以下唯一标识:
示例:
此组合唯一定义一个价格。 去掉 bookmaker,剩下的就是选项本身 —— {fixtureId}:{outcomeId}:{playerId} —— 这是与博彩公司无关的评级 / 结算键,因为一个选项在任何博彩公司处的输赢都相同。无需 marketId;outcomeId 已编码了盘口。 选项键让跨博彩商与跨数据源的比对变得廉价 —— 如何据此接入已有数据源,参见作为第二数据源运行 OddsPapi。

期货赔率ID

期货赔率由四段标识,与赛事赔率键保持一致:
最后两段分担同一项职责,而由哪一段承载「选择项」取决于盘口的形态: 0 是哨兵值,正如非球员赛事赔率的 playerId 取 0 —— 它是一个真实且稳定的键值,而不是空值。两个 ID 空间在构造上永不重叠:futureMarketId 至多 5 位,futureOutcomeId 恒为 6 位(≥ 100001),因此任何取值都不可能被误读为另一类 ID。 请将 oddsId 视为不透明字符串。 可以用它作为存储主键,但请从赔率行的显式字段读取 bookmaker、futureOutcomeId、participantId 等取值,而不要拆分各段。

时间戳(秒与毫秒)

此API有意同时使用纪元秒和纪元毫秒,具体取决于上下文。该规则在赛事和期货中保持一致:

纪元秒(UTC)

所有开始时间均为整数纪元秒:
  • startTime / endTime
  • startTimeFrom
  • startTimeTo

纪元毫秒(UTC)

所有赔率更新时间均为整数纪元毫秒 —— 赛事和期货皆是如此:
  • changedAt / bookmakerChangedAt
  • 赔率 since 过滤器(/fixtures/odds、/fixtures/odds/main、/futures/odds)
  • WebSocket 信封 ts 以及 entryId 的时间戳部分

建议

  • 将时间戳存储为整数。
  • 经验法则:赛程时间为秒,赔率更新时间为毫秒。
  • 仅在需要时进行内部归一化。

运营提示

服务器位置很重要

要实现实时更新的最低延迟:
  • 最快的交付区域是中欧(推荐)和美国东部。
  • 为获得最佳性能,请将后端部署在我们使用的相同数据中心,例如:
  • 如果您正在构建对延迟敏感的预测市场或模型,请考虑:
    • 通过Netcup部署在奥地利(AT),或
    • 使用AWS eu-west-1(爱尔兰)
与我们流媒体基础设施位于同一位置的服务器可以更快地接收更新,跳数更少。

快照 + 实时模式

可靠的集成模式:
1

订阅 WebSocket

连接并以您的过滤器登录,收到 login_ok 后立即开始按行键应用更新。
2

获取 HTTP 快照

通过 REST 拉取当前状态(赛事、赔率或期货)并合并 —— 按键比较,changedAt 较新者胜出。
3

按信号重新获取快照

如果 WebSocket 发出 snapshot_required 信号,请以同样的合并规则重新获取 HTTP 快照。
先连接、后快照正是交接无空档的原因:快照请求在途期间的变更已经在套接字上,也不存在(更不需要)从 REST 带到 WebSocket 的游标 —— 每条更新都是该行的完整最新状态。

高效回填

  • 在可用时使用since参数
  • 除非需要,否则避免完整的历史获取
  • 按赔率标识符存储赔率以进行去重

速率限制

有关请求头、各端点限制以及 429 退避处理,请参阅速率限制。

历史赔率与 CLV

实时 WebSocket 的 odds 和 oddsFutures 频道在固定的约 10 毫秒批处理窗口上传输最新状态 —— 窗口内被取代的中间报价会合并为最新值(状态不会丢失),因此并非逐笔账本。参见传输语义。
使用实时数据流进行交易,使用 REST 历史端点进行衡量 —— CLV 模型、成交审计和回测。
当您需要某个结果的完整价格变动,或其开盘价与收盘价时,请使用 REST 历史端点。它们与实时 odds 频道共享相同的 oddsId 格式({fixtureId}:{bookmaker}:{outcomeId}:{playerId}),因此您可以将实时成交直接关联到其历史记录和收盘价记录。 交易用例:
  • CLV 建模 —— 将您的成交价与收盘价进行比较,以衡量优势。
  • 成交审计 —— 将成交价格与已记录的时间线进行核对,以检测滑点。
  • 回测 —— 重放完整的历史时间线,以根据真实的价格变动测试策略。
完整的请求参数、响应结构以及每个端点的交互式演练,请参阅 API → 参考 部分。围绕这些端点的交易流程 —— 投注限额、各博彩商延迟、主盘筛选与评级 —— 参见 sharp 盘口交易与 CLV。

术语表

API 中常用核心术语的快速定义。 标识符与数据模型
  • sportId —— 运动数字标识符;下游 marketId、outcomeId 和 fixtureId 的前两位数字。
  • fixtureId —— 单场比赛/事件的字符串键,编码运动、锦标赛和原生赛事 ID。
  • futureId —— 期货 / 冠军盘口的字符串键,编码运动、锦标赛、赛季和盘口。
  • marketType —— 盘口种类(1x2、totals、spreads、bothteamsscore 等)。
  • period —— 盘口适用的赛段(fulltime、p1、p2)。
  • handicap —— 盘口线 / specifier;每个不同的盘口线都是独立的 marketId。
  • marketId —— 将一个盘口所有选项分组的整数;等于盘口的首个 outcomeId。
  • marketLength —— 一个 marketId 下的选项数量:即可供投注的各个方向,其概率之和约等于 1。
  • outcomeId —— 标识一个完全分解后的选择的整数:marketType + period + handicap(盘口线)+ 方向。它编码了除球员以外的一切 —— 球员由 playerId 补充。
  • playerId —— 在球员盘口中将选项关联到某个球员;playerId = 0 为非球员盘口。
  • participantId —— 标识赛事中球队或参赛者的整数。
  • oddsId —— 价格复合键。赛事:{fixtureId}:{bookmaker}:{outcomeId}:{playerId}。期货:{futureId}:{bookmaker}:{futureOutcomeId}:{participantId}。
价格与交易
  • OLV —— 开盘线价值:选项的首个记录价格。
  • CLV —— 收盘线价值:选项结算前的最后价格;评估执行质量的基准。
  • staleOdds —— 表示某博彩公司连接降级、其赔率可能并非最新的标志。
  • settlement(结算) —— 赛后端点,返回逐结果的结果(赢 / 输)、最终比分和盈亏幅度。
流式传输与交付
  • serverEpoch + entryId —— 每频道游标;serverEpoch 变化表示客户端必须重新获取快照。
  • resume / replay(恢复 / 重放) —— 在 resumeWindowMs(默认 60000)内重连并重放丢失的消息。
  • snapshot_required —— 表示游标已超出恢复窗口、需重新获取 REST 快照的信号。