Skip to content

REST API

匹配数据流、实时套利视图、配对详情,以及目录与反馈相关端点。每个请求都需要以 Bearer 令牌的形式携带你的 API 密钥。

REST API 提供跨平台匹配数据流、基于其上的套利视图,以及配对详情。它适用于所有套餐,包括 Free。基础 URL 为 https://api.dino.markets

身份验证

每个请求都需要以 Bearer 令牌的形式携带你的 API 密钥。在控制台中创建密钥;密钥只会显示一次。

Authorization: Bearer sk_live_...

速率限制

请求按套餐、按分钟计量上限:Free 60 次,Basic 300 次,Pro 1200 次。超过上限的请求会返回 429。流不采用这种计量方式,而是受连接数上限约束。

GET /v2/markets

规范的市场列表。不加筛选条件时,这是身份目录:每场已匹配比赛对应一行,包含平台代码和覆盖标记,价格字段留空为 null。添加 signal=arb 可获取同一批行基于实时机会快照定价的结果,且只返回已确认的套利。添加 signal=candidates 可获取基于 candidates 频道历史定价的待审核行。

参数位置类型说明
sport查询参数string限定为单个运动大类,例如 baseball。省略则包含所有运动。
league查询参数string在某个运动大类内进一步限定到某个联赛,不区分大小写,例如 MLB。当 signal=arb 时该参数会被忽略。
status查询参数string逗号分隔:openliveclosedsettled。默认 open,live
signal查询参数stringspread(默认目录视图)、arb(已定价,仅返回已确认的套利行)或 candidates(待审核行)。
sort查询参数stringstart_time(默认)或 -spread_pts,后者会将跨平台价差最大的行排在最前。
include查询参数string逗号分隔的可选数据块:idsdepthsettlement。参见附加数据说明
limit查询参数integer1 到 1000。默认 500。

有效的运动键为 baseballbasketballfootballhockeysoccertenniscricketloldota2valorantcs2r6owmma。每一行还包含 league 字段,当该平台的系列赛未命名联赛时,该字段可能为 null。调用 /v2/leagues 可查看当前处于赛季中的运动与联赛。

curl -s "https://api.dino.markets/v2/markets?sport=baseball&league=MLB" \
  -H "Authorization: Bearer sk_live_..."
{
  "count": 1,
  "sport": "baseball",
  "has_more": false,
  "markets": [
    {
      "id": "dino_8f3a1c92-47e8-4c3f-b9d2-f1a8e6c4d5f2",
      "slug": null,
      "sport": "baseball",
      "league": "MLB",
      "title": "Nyy vs Bos",
      "home": null,
      "away": null,
      "start_time": "2026-07-01T23:05:00+00:00",
      "status": "open",
      "match": "high_confidence",
      "signal": "spread",
      "spread_pts": null,
      "potential_arb_pct": null,
      "coverage": { "kalshi": false, "polymarket": false },
      "outcomes": [],
      "result": null,
      "updated_at": "2026-07-01T22:55:00+00:00",
      "priced_at": "2026-07-01T22:55:00+00:00",
      "links": { "kalshi": "https://kalshi.com/markets/KXMLBGAME-26JUL01NYYBOS", "polymarket": null }
    }
  ]
}

未筛选的视图不带任何价格。outcomes 为空,signal 始终为 spread,coverage 在两个平台上都读作 false。这是预期行为:这是身份目录。此视图中的 priced_at 是该行的 updated_at(该配对本身最后一次变化的时间),而不是实时的定价时刻——目前每一行还没有单独存储的定价时间戳。如需同一批行的实时价格,请请求 signal=arb(仅返回已确认的套利),或在 /v2/pairs/{market_id} 上针对单个市场添加 include=depth

套利视图:GET /v2/markets?signal=arb

同一个端点,基于实时机会快照定价,并筛选出匹配引擎已确认为套利的行:结算一致性已确认、没有阻断性结算风险,且每个结果在两个平台上都已定价。它取代了旧版专用的机会数据流。v2 中不存在单独的套利端点,这只是市场目录之上的一个视图。支撑它的快照是尽力而为型的,无论哪个套餐都大约有两分钟的延迟。

参数位置类型说明
sport查询参数string限定为单个运动大类,例如 baseball
include查询参数string逗号分隔的可选数据块:idsdepthsettlement
limit查询参数integer1 到 1000。默认 500。

上文的目录参数同样适用于该视图:statussortinclude 的作用方式相同(唯一的例外是 league 过滤器,在此视图中会被忽略)。

curl -s "https://api.dino.markets/v2/markets?signal=arb&sport=baseball" \
  -H "Authorization: Bearer sk_live_..."
{
  "count": 1,
  "sport": "baseball",
  "has_more": false,
  "markets": [
    {
      "id": "dino_8f3a1c92-47e8-4c3f-b9d2-f1a8e6c4d5f2",
      "slug": null,
      "sport": "baseball",
      "league": "MLB",
      "title": "Nyy vs Bos",
      "home": null,
      "away": null,
      "start_time": "2026-07-01T23:05:00+00:00",
      "status": "open",
      "match": "high_confidence",
      "signal": "arb",
      "spread_pts": 2.0,
      "potential_arb_pct": 1.83,
      "coverage": { "kalshi": true, "polymarket": true },
      "outcomes": [
        { "key": "NYY", "name": "NYY", "kalshi": 0.52, "polymarket": 0.54, "cheaper": "kalshi" },
        { "key": "BOS", "name": "BOS", "kalshi": 0.50, "polymarket": 0.46, "cheaper": "polymarket" }
      ],
      "result": null,
      "updated_at": "2026-07-01T22:55:00+00:00",
      "priced_at": "2026-07-01T22:55:00+00:00",
      "links": { "kalshi": "https://kalshi.com/markets/KXMLBGAME-26JUL01NYYBOS", "polymarket": null }
    }
  ]
}

markets 为空数组、count0,是套利之间的正常静默状态。potential_arb_pct 是以卖价对卖价计算的毛收益率,尚未扣除平台手续费。它是对快照的一次观测,尽力而为,可能来自缓存,存在延迟。outcomes[].kalshi.polymarket 是各平台对该结果的卖价,取值 01;cheaper 标明该结果在哪个平台的卖价更低。在 REST 上,priced_at 反映的是 updated_at(该配对的最后一次写入),而非实时快照的瞬间时刻;WebSocket 数据流则会在每一次价格变动中携带真实的订单簿读取时间戳。

Candidates:GET /v2/markets?signal=candidates

待审核行:匹配引擎已经形成、但尚未确认的匹配。基于同一份为 candidates:{sport} WebSocket 频道(Pro)提供数据的频道历史,尽力而为地定价。处于待审核状态的市场,无论携带什么价格,都始终会归结为 spread;该视图永远不会返回 signal: "arb" 的行。

参数位置类型说明
sport查询参数string限定为单个运动大类。
league查询参数string在某个运动大类内进一步限定到某个联赛。
include查询参数string逗号分隔的可选数据块:idsdepthsettlement
limit查询参数integer1 到 1000。默认 500。
curl -s "https://api.dino.markets/v2/markets?signal=candidates&sport=baseball" \
  -H "Authorization: Bearer sk_live_..."

上文的目录参数同样适用于该视图:statussortinclude 的作用方式相同。

返回的行采用与目录视图相同的规范结构。当某个候选项已经有定价匹配时,outcomescoverage 的填充方式与套利视图相同;当价格尚不可用时,价格字段会保留为 null

Includes

include 会为每个市场对象附加可选启用的数据块。未指定的数据块表示该键完全不存在,而不是值为 null。请只请求你需要的内容。

附加内容说明
idsvenuesconfidence平台标识(kalshi.event_tickerpolymarket.condition_id)以及匹配引擎的实体/结算置信度,取值 0 到 1。
depthoutcomes[].kalshi_bookoutcomes[].polymarket_book按结果划分的订单簿详情(卖价、深度、平台代码或 token id),与标量卖价字段并列存在。这是同级字段,不会替代 outcomes[].kalshi.polymarket
settlementsettlementparity(布尔值)、risks[]、平台披露文本,以及结算后才有的 verdict

GET /v2/pairs/{market_id}

按 id 返回单个规范市场对象,默认应用 include=ids,depth,settlement。这是详情视图。接受 dino_<uuid>(即 /v2/markets 返回的 id 字段)或裸 UUID。

参数位置类型说明
market_id路径string来自 /v2/markets 的市场 id,可以是 dino_<uuid> 或裸 UUID。

示例:MLB 套利(已确认结算一致性)

curl -s "https://api.dino.markets/v2/pairs/dino_8f3a1c92-47e8-4c3f-b9d2-f1a8e6c4d5f2" \
  -H "Authorization: Bearer sk_live_..."
{
  "id": "dino_8f3a1c92-47e8-4c3f-b9d2-f1a8e6c4d5f2",
  "slug": null,
  "sport": "baseball",
  "league": "MLB",
  "title": "Nyy vs Bos",
  "home": null,
  "away": null,
  "start_time": "2026-07-01T23:05:00+00:00",
  "status": "open",
  "match": "high_confidence",
  "signal": "arb",
  "spread_pts": 2.0,
  "potential_arb_pct": 1.83,
  "coverage": { "kalshi": true, "polymarket": true },
  "outcomes": [
    { "key": "NYY", "name": "NYY", "kalshi": 0.52, "polymarket": 0.54, "cheaper": "kalshi",
      "kalshi_book": { "ask": 0.52, "bid": null, "depth": 3100, "ticker": "KXMLBGAME-26JUL01NYYBOS-NYY" },
      "polymarket_book": { "ask": 0.54, "bid": null, "depth": 2900, "token_id": "0x1a2b..." } },
    { "key": "BOS", "name": "BOS", "kalshi": 0.50, "polymarket": 0.46, "cheaper": "polymarket",
      "kalshi_book": { "ask": 0.50, "bid": null, "depth": 2400, "ticker": "KXMLBGAME-26JUL01NYYBOS-BOS" },
      "polymarket_book": { "ask": 0.46, "bid": null, "depth": 3300, "token_id": "0x9f8e..." } }
  ],
  "result": null,
  "updated_at": "2026-07-01T22:55:00+00:00",
  "priced_at": "2026-07-01T22:55:00+00:00",
  "venues": {
    "kalshi": { "event_ticker": "KXMLBGAME-26JUL01NYYBOS" },
    "polymarket": { "condition_id": "0x1a2b...", "slug": null }
  },
  "confidence": { "entity": 1.0, "resolution": 1.0 },
  "settlement": { "parity": true, "risks": [], "kalshi_text": null, "poly_text": null, "verdict": null },
  "links": { "kalshi": "https://kalshi.com/markets/KXMLBGAME-26JUL01NYYBOS", "polymarket": null }
}

示例:KBO 价差(跨平台结算风险)

curl -s "https://api.dino.markets/v2/pairs/dino_5c2b9f7e-d4a1-4e6c-8b3f-a9c2e5f1d8a4" \
  -H "Authorization: Bearer sk_live_..."
{
  "id": "dino_5c2b9f7e-d4a1-4e6c-8b3f-a9c2e5f1d8a4",
  "sport": "baseball",
  "league": "KBO",
  "title": "Kia vs Kiw",
  "start_time": "2026-07-15T10:00:00+00:00",
  "status": "open",
  "signal": "spread",
  "spread_pts": null,
  "potential_arb_pct": null,
  "coverage": { "kalshi": false, "polymarket": false },
  "outcomes": [],
  "settlement": {
    "parity": false,
    "risks": [
      {
        "event": "tie",
        "severity": "high",
        "note": "This league can tie, but one venue's market does not carry an explicit tie->50/50 clause. A held two-leg position may not return $1 on a tie. Verify before trading."
      }
    ],
    "kalshi_text": null,
    "poly_text": null,
    "verdict": null
  },
  "links": { "kalshi": "https://kalshi.com/markets/KXMLBGAME-26JUL15KIWKIA", "polymarket": null }
}

一旦该配对存在 highcritical 严重程度的风险,即便价格完全吻合,signal 也会被强制归为 spread;这项检查是决定 signal 的四道关卡之一,会针对该配对完整的内部风险集合运行。返回的 risks[] 永远不包含取消类(cancel_*)事件,这些事件已在服务端被过滤。无论是 arb 还是 spread,行动之前都请先阅读 settlement.risks。如果该 id 无法解析,响应会是 404,并返回 { "error": "pair not found" }

GET /v2/leagues

当前处于赛季中的运动与联赛,来自活跃数据流,并附带每个运动的生命周期计数。

leagues 数组列出该运动下观测到的非空联赛;count 是该运动下已匹配比赛的总数,包括联赛字段为 null 的行。open 目前与 count 相同;livesettled 始终为 0,因为比赛进行中的计数和已撤回行的计数尚未接入此端点。

curl -s "https://api.dino.markets/v2/leagues" \
  -H "Authorization: Bearer sk_live_..."
{
  "sports": [
    { "sport": "baseball", "leagues": ["KBO", "MLB", "NPB"], "count": 54, "open": 54, "live": 0, "settled": 0 },
    { "sport": "soccer", "leagues": ["World Cup"], "count": 15, "open": 15, "live": 0, "settled": 0 },
    { "sport": "tennis", "leagues": ["ITFW"], "count": 165, "open": 165, "live": 0, "settled": 0 }
  ]
}

GET /v2/coverage

平台覆盖普查:列出 Kalshi 上架的每个对战类联赛,无论是否已接入匹配数据流,并附带其聚合状态。匹配引擎每一轮都会重新构建该普查,大约每小时一次。状态取值:aggregated(已实时配对)、pending(已接入,等待对应方或其确认流程完成)、quiet(已接入,但当前没有开放项)、kalshi_only(在该平台上架,但尚未接入配对)、dormant(系列赛存在,但没有开放项)。poly_unpaired 携带该运动级别的 Polymarket 侧盈余,即该轮匹配中未找到 Kalshi 对应配对的已解析赛事。

curl -s "https://api.dino.markets/v2/coverage" \
  -H "Authorization: Bearer sk_live_..."
{
  "as_of": "2026-07-04T03:30:21+00:00",
  "counts": { "aggregated": 20, "pending": 7, "quiet": 43, "kalshi_only": 13, "dormant": 139 },
  "series": [
    { "series_ticker": "KXFIBAGAME", "league": "FIBA", "sport": "basketball", "wired": true,
      "status": "aggregated", "kalshi_open_events": 49, "paired": 46, "sport_poly_fixtures": 88,
      "last_pass_at": "2026-07-04T03:30:21+00:00" }
  ],
  "poly_unpaired": [ { "sport": "soccer", "fixtures": 258, "paired": 7, "unpaired": 251 } ]
}

该普查仅通过 API 提供;内部的覆盖视图使用的是同一份数据。

POST /v1/stream/token

为实时流生成一张短期有效的票据。该端点没有迁移到 /v2,仍然保留在 /v1/stream/token。它需要 Basic 或 Pro 套餐;Free 密钥会收到 402。完整的连接流程见 WebSocket 流页面。

{
  "ticket": "eyJhbGciOi...",
  "ws_url": "wss://stream.dino.markets/connection/websocket",
  "expires_in": 120,
  "allowed": { "channels": ["markets:all", "status"], "max_conns": 3 }
}

POST /v2/report-bad-arb

举报一个看起来有问题的机会。系统会为我们的审核队列生成一条记录。请至少填写以下字段之一。对于 opp_id,请传入该市场在 /v2/markets 中的 id 值。

字段类型说明
opp_idstring该市场的 id 值(dino_<uuid>)。
reasonstring简短的原因或备注。
sportstring没有 opp_id 时填写运动项目。
marketstring市场或比赛。
detailstring任何其他详情。
curl -s -X POST "https://api.dino.markets/v2/report-bad-arb" \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "opp_id": "dino_8f3a1c92-47e8-4c3f-b9d2-f1a8e6c4d5f2", "reason": "legs do not settle the same way" }'

举报成功会返回 202 以及 { "status": "received" }。请至少发送 opp_idreasonsportmarketdetail 中的一项;空请求体会返回 400