> ## Documentation Index
> Fetch the complete documentation index at: https://docs.oddspapi.io/llms.txt
> Use this file to discover all available pages before exploring further.

# 端到端支撑一家体育博彩 —— 赛程、价格、滚球与结算

> 在 OddsPapi 上构建完整博彩产品：发现运动与锦标赛、加载赛程、建模盘口与选项、推送价格与滚球状态，并完成投注结算。

客户在 OddsPapi 上构建的是完整的博彩产品，而不只是价格展示。本指南走完整条流水线 —— 发现、赛程、盘口、价格、滚球、结算 —— 并指明每个阶段对应的接口或频道。

<Note>
  OddsPapi 聚合博彩商价格，并非官方或获授权的联赛数据提供商。结算基于跨源解析后的事实得出，且**期货结算正在推出** —— 接口已存在但暂未返回结果。
</Note>

***

## 流水线

<Steps>
  <Step title="发现目录">
    `GET /sports`、`/tournaments`、`/seasons`、`/participants`、`/players`、`/venues` —— 产品所依赖的静态树。缓存即可，它变化缓慢。
  </Step>

  <Step title="加载赛程">
    快照用 `GET /fixtures`、`/fixtures/today`、`/fixtures/live`，随后用 [`fixtures`](/zh/websocket/channels/fixtures) 频道接收状态与赛程变更。
  </Step>

  <Step title="建模盘口">
    `GET /markets?sportId=…` 给出某运动的全部盘口及其选项 —— 即您可以呈现的产品。
  </Step>

  <Step title="定价">
    用 `GET /fixtures/odds`（或仅主盘的 `/fixtures/odds/main`）初始化，随后用 [`odds`](/zh/websocket/channels/odds) 频道接收实时更新。
  </Step>

  <Step title="运行滚球">
    [`scores`](/zh/websocket/channels/scores) 与 [`clocks`](/zh/websocket/channels/clocks) 提供实时状态，[`bookmakers`](/zh/websocket/channels/bookmakers) 提供暂停与陈旧状态。
  </Step>

  <Step title="结算">
    `GET /fixtures/settlement` 提供逐 outcome 评级、最终比分与净胜分。
  </Step>
</Steps>

***

## 盘口：按坐标寻址，而非按名称

每个选项在每家博彩商、每场赛事上的分解方式都相同：

```
marketType → period → handicap（线值）→ side   [+ 可选球员]
```

该分解已烘焙进 `outcomeId`，这意味着同一个投注始终解析到同一个 `marketId` / `outcomeId`。构建产品时有两条规则尤为重要：

* **每个不同的线值都是独立的 `marketId`。** 单个 `marketId` 内的选项只是该确切线值的各个方向。
* **`marketId` 等于该盘口的第一个 `outcomeId`**，`marketLength` 是方向数量 —— 二者共同构成完整的概率空间，这正是计算利润率与完整性检查所需的。

```json theme={null}
{
  "marketId": 113,
  "marketLength": 3,
  "sportId": 11,
  "playerProp": false,
  "handicap": 0.0,
  "period": "fulltime",
  "marketType": "1x2",
  "marketName": "Regular Time Result",
  "marketNameShort": "1X2",
  "outcomes": [
    { "outcomeId": 113, "outcomeName": "1" },
    { "outcomeId": 114, "outcomeName": "X" },
    { "outcomeId": 115, "outcomeName": "2" }
  ]
}
```

展示用 `marketName` / `marketNameShort`，逻辑用 `marketId` / `outcomeId`。完整说明参见[盘口和选项](/zh/api-reference/concepts#盘口和选项)与[盘口覆盖](/zh/coverage/markets)。

***

## 本地化

所有接口均带语言前缀（`/en/…`、`/de/…`、`/fr/…`），WebSocket 在登录时接受 `lang`。翻译字段 —— `sportName`、`marketName`、`statusName`、参与者名称 —— 跟随前缀；标识符则永远不变。请基于 ID 构建界面，让名称跟随用户语言。

加密货币或多币种展示可使用 [`currencies`](/zh/websocket/channels/currencies) 频道，它推送法币与加密货币对美元的汇率。

***

## 滚球

* **比分按赛段给出**，键为 `result`、`p1`、`p2` …… —— `result` 是权威的当前比分，赛段行用于结算赛段盘口。
* **`statusId` 只向前推进**：`0` 赛前 → `1` 进行中 → `2` 已结束，或任意状态 → `3` 已取消。请基于 ID 而非名称分支。
* **`clocks`** 携带 `currentPeriod`、`currentTime`、`remainingTime` 与 `stopped`，用于实时展示以及在中断期间挂起投注。
* **暂停状态**来自 `bookmakers` 频道（`suspended`、`staleOdds`）以及赔率自身的 `marketActive` / `active`。请把它们全部接入同一个"此刻是否可投注"的判定。

赛段需结合该运动的结构来解读 —— `p1` 在足球中是半场，在 NBA 篮球中是一节，在网球中是一盘。赛事上的 `expectedPeriods` 与 `periodLength` 告诉您是哪一种。该词汇表在所有运动间共享且只增不减，参见[枚举 → period](/zh/api-reference/enumerations#period)。

***

## 结算

`GET /fixtures/settlement` 接受 `fixtureId` 以及可选的 `outcomeId` / `playerId`，返回赛事最终状态与逐 outcome 评级：

| 值                      | 含义                |
| ---------------------- | ----------------- |
| `WIN` / `LOSE`         | 完全赢或完全输           |
| `PUSH`                 | 平局 / 走盘 —— 退还本金   |
| `HALFWIN` / `HALFLOSS` | 亚洲四分之一盘的半注结算      |
| `CANCELLED`            | 盘口作废 —— 退还本金      |
| `UNDECIDED`            | 尚无法评级；附带 `reason` |

请基于**选项**键结算 —— `{fixtureId}:{outcomeId}:{playerId}`，不含博彩商 —— 因为无论由谁报价，一个选项的结果都相同。请把 `UNDECIDED` 与 `CANCELLED` 作为结算队列中的显式状态处理，而不是不断重试直到成功。

***

## 运营要点

* **先快照，再订阅，收到信号再重新快照。** `snapshot_required` 意味着您的游标已离开重放窗口；它是设计好的路径，而非错误。参见[恢复和重放](/zh/websocket/resume-replay)。
* **在登录时过滤。** `sportIds`、`tournamentIds` 和 `bookmakers` 削减消息量的效果远好于客户端过滤。
* **回填使用 `since`** 而非完整重取，并以 `oddsId` 为键存储以实现干净去重。
* **规模化时在 `odds` 上优先使用 `receiveType: "zstd"`**（[压缩](/zh/websocket/compression)）。
* **新枚举值只会追加，绝不改变含义** —— 请忽略无法识别的值，而不是报错失败。

价格历史、收盘线以及对自有账本的事后分析，参见[历史赔率与 CLV](/zh/api-reference/concepts#历史赔率与-clv)。

***

## 您可以依赖的保证

* **盘口是被寻址的，而不是被匹配的。** `marketType → period → handicap → side` 在每一家博彩商上都解析到同一个 `marketId` / `outcomeId`，因此您不必维护一层按博彩商定制的名称字符串匹配逻辑，也不必在每次某家博彩商改名时去修它。
* **线值永不合并。** 每个不同的线值都是独立的 `marketId`，因此「大 2.5」与「大 3.5」不可能坍缩成同一个盘口，从而悄悄让您的账本定价出错。
* **链路是闭合的。** 同一个 `oddsId` 可寻址实时价格、其历史时间线、其收盘线以及其结算结果 —— 从定价到结算只用一个键。
