消息
用户推送将每条更新作为裸 JSON 对象发送(无元组包装)。所有更新共用同一结构;动作由unmatched / matched 哪个被填充以及 origin 决定。
通用结构
messageID 是 streaming-api 在发送前添加的流条目 id。请持久化你已处理的最新一条 — 它就是你的回放游标。参见下方回放错过的消息。
matched 块
只要更新表示一笔成交(matched != null),就会出现该块。除非标明为有条件,下列每个字段都会在每笔成交上发送。所有取值都从你的视角出发 — 作为 taker 你看到自己吃到的方向,作为 maker 你看到自己挂出的方向。
REST 上的相同数量(获取已撮合投注)以保留 2 位小数的字符串而非数字给出,且佣金与舍入顺序略有不同。对账时请允许一分钱的容差,不要要求精确相等。
unmatched 块
只要更新涉及留在(或离开)订单簿的订单 — 下单、取消,以及成交的 maker 一侧 — 就会出现该块。赔率和方向来自 maker 视角,即你挂出的内容,而不是订单簿向他人展示的报价。
如何识别动作
unmatched.filled === 0 && unmatched.offered > 0-> 已下单unmatched.offered === 0-> 已取消matched != null && unmatched == null-> 作为 taker 成交matched != null && unmatched != null-> 作为 maker 成交(若unmatched.remaining > 0则为部分成交)
orderType: "postArb" 下的订单,其更新还会在 matched / unmatched 内带有 isPostArb: true(下单、成交和取消更新均如此);否则省略该字段。
按投注类型区分的 side 与 market 语义
matched / unmatched 内 side 的含义(以及会出现哪些额外字段)取决于 type:
market 仅出现在 moneyline1x2 更新中:它指明该盘口所针对的三项结果(主队、客队或平局),side 则表示对该结果是 yes 还是 no。所有字段都从你的视角出发 — 作为 maker 你看到自己挂出的方向;作为 taker 你看到自己吃到的方向。
动作:已下单
一笔新挂单进入订单簿。unmatched.filled 为 0,unmatched.offered > 0,且 matched 为 null。
动作:已取消
用户(或系统代其)取消了一笔挂单。区分字段是unmatched.offered === 0。
动作:订单成交(taker)
用户吃掉了他人的挂单。unmatched 为 null,matched 携带成交,origin 为 "wager"。
动作:订单成交(maker,部分成交)
有人吃到了用户挂出的报价。matched 和 unmatched 均被填充;unmatched.remaining 显示订单簿上仍剩余的数量。因为设置了 unmatched,origin 为 "offer"。
动作:订单成交(moneyline1x2)
足球三项盘上的成交携带上文所述的market + side 组合,而不是参赛者十六进制 side。此处用户以 +120 吃了主队的 “yes”(投注阿森纳获胜):
market 上 side: "yes"、赔率 +120,maker 看到 side: "no"、赔率 -120。
回放错过的消息
v2 用户推送支持连接中断后的缺口恢复。每条消息都带有messageID(单调递增的流条目 id,例如 "1751552702114-0")。若连接断开,你可以精确拉取错过的消息。
接口
Authorization 请求头、Auth 请求头或 token 查询参数中携带 token。仅返回属于已鉴权用户的消息。
响应:success
你的 afterID 仍在保留历史中,因此返回的列表是完整的缺口填充 — afterID 与 beforeID 之间没有任何丢失:
响应:cache_expired
你的 afterID 已超出保留历史,因此服务器无法证明回放是完整的:
availableMessages 是仍被保留的内容,最旧的在前。超出保留窗口的更早消息无法通过回放恢复 — 请及时重连,而不要依赖过长的回看。