> ## 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：通过外部提供商 ID 与映射接口关联赛事，基于稳定的选项键比较价格，并测量哪一路数据更快。

采用 OddsPapi 的交易团队大多已经有一路数据源。并行运行两路是常规做法 —— 一路用于交叉校验，一路用于补足对方缺失的覆盖 —— 而其成本几乎全部落在**实体映射**上：判定您现有提供商的那场比赛与我们的是同一场。

OddsPapi 直接公布这些映射，因此关联是一次查表，而不是一个模糊匹配项目。

***

## 按 ID 关联，而非按名称

[`fixtures`](/zh/websocket/channels/fixtures) 频道在每条赛事上携带 `externalProviders` 对象：

| 字段             | 提供商        |
| -------------- | ---------- |
| `betradarId`   | Betradar   |
| `flashscoreId` | Flashscore |
| `pinnacleId`   | Pinnacle   |
| `sofascoreId`  | Sofascore  |
| `oddinId`      | Oddin      |
| `mollybetId`   | Mollybet   |
| `opticoddsId`  | OpticOdds  |
| `lsportsId`    | LSports    |
| `txoddsId`     | TXOdds     |

如果您当前的数据源是其中之一，关联就是一个字段。每条赛事存一次，两套系统从此共享同一个键。

<Note>
  映射在存在对应关系时填充 —— 请将所有字段视为可空，并对其余部分回退到开赛时间加参与者的匹配方式。
</Note>

***

## 博彩商侧映射

若需与**博彩商**自身的标识符（而非数据提供商的）关联，请使用映射接口：

```bash theme={null}
# OddsPapi 赛事 -> 博彩商赛事 ID
curl 'https://v5.oddspapi.io/en/fixtures/mapping?fixtureIds=id1100013270505136&apiKey=YOUR_KEY'

# 博彩商赛事 ID -> OddsPapi 赛事
curl 'https://v5.oddspapi.io/en/fixtures/mapping?bookmaker=pinnacle&bookmakerFixtureIds=1628488896&apiKey=YOUR_KEY'
```

`GET /futures/mapping` 对冠军盘口做同样的事。在单条价格上，[`odds`](/zh/websocket/channels/odds) 频道还携带 `bookmakerMarketId` 与 `bookmakerOutcomeId`，[`bookmakers`](/zh/websocket/channels/bookmakers) 频道携带 `bookmakerFixtureId` 与 `fixturePath`。

***

## 基于稳定键比较价格

在 OddsPapi 内部，一条价格的键是：

```
{fixtureId}:{bookmaker}:{outcomeId}:{playerId}
```

去掉博彩商即得到**选项（selection）** —— `{fixtureId}:{outcomeId}:{playerId}` —— 这正是跨数据源比较时所需的，因为无论由谁报价，一个选项的输赢结果都相同。

要将某个选项对齐到另一路数据源的盘口模型，请拆解为坐标而非匹配盘口名称字符串：

```
marketType → period → handicap → side   [+ playerId]
```

`marketType`（`1x2`、`totals`、`spreads` 等）、`period`（`fulltime`、`p1` 等）与 `handicap`（线值）在 `GET /markets` 上均为显式字段。每个不同的线值都是独立的 `marketId`，因此"大 2.5"与"大 3.5"永远不会合并为一个盘口。参见[盘口和选项](/zh/api-reference/concepts#盘口和选项)。

<Steps>
  <Step title="映射赛事">
    通过 `externalProviders` 关联，或对博彩商侧 ID 使用 `/fixtures/mapping`。
  </Step>

  <Step title="映射盘口">
    将您现有的模型翻译为 `marketType` + `period` + `handicap`，并从 `/markets` 解析出 `marketId`。
  </Step>

  <Step title="映射方向">
    为该方向选取 `outcomeId`；球员盘口补上 `playerId`（否则为 `0`）。
  </Step>

  <Step title="存储配对">
    持久化 您的键 ↔ `{fixtureId}:{outcomeId}:{playerId}`，使映射只做一次，而不是每次更新都做。
  </Step>
</Steps>

***

## 测量哪一路更快

只有当您能判断哪一路更优时，第二次集成才值得。两项测量，均无需我方额外埋点：

* **观察延迟** —— 每条更新的 `changedAt − bookmakerChangedAt`，与另一路数据源的等价时间戳对比。各博彩商的上限发布在 `GET /bookmakers`（`maxDelayLiveInSec` / `maxDelayPregameInSec` / `maxDelayPregameMainInSec`），代表性 p50 见[延迟与新鲜度](/zh/api-reference/reliability#延迟与新鲜度)。
* **传输跳** —— 信封 `ts` 与您的接收时间对比。这一项取决于您的部署位置，参见[服务器位置](/zh/api-reference/concepts#服务器位置很重要)。

若想要结果层面的结论而非秒表，可用 `GET /fixtures/odds/clv` 将成交价与收盘线对比。它与实时数据流共用 `oddsId` 格式，关联零成本。

***

## 通常的互补之处

覆盖范围很少完全重合，这正是并行两路的意义。实践中 OddsPapi 补足的是 sharp 交易型博彩商、亚洲盘口与四分之一盘结算、交易所与预测市场深度，以及几乎每家 sharp 博彩商都携带的投注限额 —— 同时具备广泛的美国与欧洲零售覆盖。目录形态参见[博彩商覆盖](/zh/coverage/bookmakers)，您的密钥可见范围参见 `GET /bookmakers`。

***

## 切换检查清单

* [ ] 赛事已通过 `externalProviders` 或 `/fixtures/mapping` 关联，并对空值有回退方案
* [ ] 盘口模型已翻译为 `marketType` / `period` / `handicap` 坐标
* [ ] 存储以 `oddsId` 为键，并保留用于跨源比较的选项键
* [ ] `staleOdds` 与 `suspended` 已接入与现有数据源相同的熔断开关
* [ ] 已实现 `snapshot_required` 处理与恢复（[恢复和重放](/zh/websocket/resume-replay)）
* [ ] 在转移任何权重之前，两路数据源上的延迟对比已在运行

***

## 您可以依赖的保证

* **ID 不会在您脚下移动。** 各注册表只追加，已发布的标识符被冻结，因此您在评估期建好的映射表一年后依然正确。新枚举值只会追加而不会被改作他用 —— 请忽略无法识别的值，而不是报错失败。
* **恢复是有界且确定的。** 每频道游标（`serverEpoch` + `entryId`）可在 `resumeWindowMs` 内重放；超出之后，最坏情况也只是一次 REST 快照，而不是到对账时才发现的静默缺口。
* **映射是双向可解的。** `externalProviders` 让您用手上已有的供应商 ID 反查进来，`GET /fixtures/mapping` 则两个方向都能走 —— 因此接第二路数据源是一次查表，而不是一个赛事匹配项目。
