跳转到主要内容

端点

wss://v2.55-tech.com/ws

连接流程

1. 连接

打开WebSocket连接。连接时无需身份验证。

2. 登录

在连接后 30秒 内发送登录消息:
{
  "type": "login",
  "apiKey": "YOUR_API_KEY",
  "channels": []
}
空的 channels 数组订阅所有可用频道。要订阅特定频道:
{
  "type": "login",
  "apiKey": "YOUR_API_KEY",
  "channels": ["orders", "bets", "settlements"]
}
可选启用可靠传递和消息确认:
{
  "type": "login",
  "apiKey": "YOUR_API_KEY",
  "channels": ["orders", "bets"],
  "reliableDelivery": true
}

3. 登录确认

成功后,服务器响应:
{
  "type": "login_ok",
  "clientName": "your-client",
  "channels": ["orders", "bets", "settlements"],
  "subscriptionId": 1,
  "access": {
    "clientFiltered": ["orders", "bets", "settlements", "accounts", "balance", "betslip"],
    "global": ["fixtures", "currencies", "status", "emergency"]
  },
  "reliableDelivery": false,
  "features": {
    "messageOrdering": true,
    "acknowledgments": false,
    "batchAck": false
  }
}

4. 接收更新

数据消息格式如下:
{
  "type": "data",
  "channel": "orders",
  "event": "INSERT",
  "payload": { ... },
  "ts": 1771183909789,
  "seq": 1
}
字段描述
type数据消息始终为 "data"
channel此消息所属频道
event事件类型:INSERTUPDATEDELETESETTLEDSTATUS
payload完整的更新对象(见负载结构
ts服务器时间戳(自纪元以来的毫秒数)
seq每订阅的单调递增序列号
requireAck仅在启用可靠传递时存在且为 true
各频道完整的负载结构见下文负载结构

5. 保持活跃

服务器每 30秒 发送一次 ping:
{"type": "ping"}
120秒 内回复 pong,否则连接将被关闭:
{"type": "pong"}
您也可以从客户端发送 ping — 服务器会回复 pong。

频道

客户端过滤频道

这些频道仅传递属于您 clientName 的数据:
频道事件描述
ordersINSERT, UPDATE, DELETE订单下达、成交、状态变更
betsINSERT, UPDATE, DELETE投注下达、确认和移除
settlementsSETTLED结算状态更新(负载与 bets 相同)
accountsINSERT, UPDATE, DELETE账户创建、更新和删除
balanceUPDATE余额变动通知
betslipUPDATE活跃投注单订阅的实时赔率更新(每次 GET /betslip 调用后 60 秒窗口)

全局频道

所有订阅者都会收到:
频道事件描述
fixturesUPDATE赛事元数据和比分变更
currenciesUPDATE货币汇率更新
statusSTATUS系统状态变更
emergencySTATUS紧急模式激活/停用

可靠投递与确认

默认情况下,消息是「发后即忘」的——快速,但断连期间丢失的消息就此消失。在登录时启用可靠投递,即可获得带确认与重放的至少一次投递:
{ "type": "login", "apiKey": "YOUR_API_KEY", "channels": ["orders", "bets"], "reliableDelivery": true }
启用后,每条 data 消息都携带 requireAck: true,你必须确认它,服务端才能将其从缓冲区释放:
{ "type": "ack", "seq": 42 }
或在一条消息中确认一个范围(推荐,利于吞吐):
{ "type": "ack_batch", "upToSeq": 50 }
工作原理:
  • 服务端为每个订阅缓冲最多 100 条未确认消息,并重发任何 30 秒内未被确认的消息。
  • seq 按订阅且严格递增,因此 seq 出现间隙意味着你漏掉了消息。
  • 要在重连后恢复漏掉的消息,从你处理的最后一个 seq 请求重放:
{ "type": "replay", "fromSeq": 40 }
若你落后超过 100 条消息的缓冲,最旧的未确认消息会被丢弃。请及时确认(或使用 ack_batch),并将任何 replay 无法填补的 seq 间隙视为通过 REST 端点(GET /ordersGET /bets)对账的信号。

变更订阅

无需重连即可变更频道:
{ "type": "update_channels", "channels": ["orders", "bets", "settlements"] }
服务端以 channels_updated 回复。

赔率单订阅

betslip 频道为你关注的选项推送实时赔率。有两种订阅方式:
  1. 通过 REST——调用 GET /betslip 会注册一个 60 秒滑动窗口;每次调用重置计时器并立即通过 WebSocket 广播一份快照。
  2. 通过 WebSocket——发送 subscribe_betslip 消息并附显式 ttl(10–3600 秒)与博彩商列表以获得更精细的控制,用 unsubscribe_betslip 提前取消。
每客户端最多 20 个活跃赔率单订阅(REST + WS 合计)。消息结构与 subscribed_betslip 确认见下文赔率单订阅消息

示例:Python 客户端

import asyncio
import json
import websockets

async def connect():
    uri = "wss://v2.55-tech.com/ws"
    async with websockets.connect(uri) as ws:
        # 登录
        await ws.send(json.dumps({
            "type": "login",
            "apiKey": "YOUR_API_KEY",
            "channels": ["orders", "bets", "settlements"]
        }))

        # 等待登录确认
        login_resp = json.loads(await ws.recv())
        print(f"已登录为 {login_resp.get('clientName')}")

        # 监听更新(自动回复 ping)
        async for message in ws:
            data = json.loads(message)
            if data["type"] == "ping":
                await ws.send(json.dumps({"type": "pong"}))
            elif data["type"] == "data":
                print(f"[{data['channel']}:{data['event']}] {data['payload']}")

asyncio.run(connect())

示例:JavaScript 客户端

const WebSocket = require('ws');

const ws = new WebSocket('wss://v2.55-tech.com/ws');

ws.on('open', () => {
  ws.send(JSON.stringify({
    type: 'login',
    apiKey: 'YOUR_API_KEY',
    channels: ['orders', 'bets', 'settlements']
  }));
});

ws.on('message', (raw) => {
  const msg = JSON.parse(raw);

  if (msg.type === 'login_ok') {
    console.log(`已登录为 ${msg.clientName}`);
  }

  if (msg.type === 'ping') {
    ws.send(JSON.stringify({ type: 'pong' }));
  }

  if (msg.type === 'data') {
    console.log(`[${msg.channel}:${msg.event}]`, msg.payload);
  }
});

消息类型

客户端 → 服务端

类型示例用途
login{"type": "login", "apiKey": "...", "channels": []}鉴权并订阅。可选 reliableDelivery: true
update_channels{"type": "update_channels", "channels": ["orders"]}登录后变更频道订阅。
pong{"type": "pong"}回复服务端的 ping
ping{"type": "ping"}存活检查;服务端以 pong 回复。
ack{"type": "ack", "seq": 42}确认单条消息(可靠投递)。
ack_batch{"type": "ack_batch", "upToSeq": 50}确认直到并包含 upToSeq 的所有消息。
replay{"type": "replay", "fromSeq": 40}请求从 fromSeq 起重发缓冲消息。
subscribe_betslip下文以自定义 TTL 开启赔率单价格订阅。
unsubscribe_betslip下文提前取消赔率单订阅。

服务端 → 客户端

类型用途
login_ok登录成功;回显频道、访问范围与已启用功能。
channels_updated确认一次 update_channels 变更。
data一个频道事件(见负载结构)。
ping服务端保活;以 pong 回复。
subscribed_betslip确认一次 subscribe_betslip,附有效 expiresAt
error客户端消息出错;含指向相关请求的 ref

赔率单订阅消息

在订阅前,betslip 频道必须在你的订阅中(通过 loginupdate_channels 添加)。

subscribe_betslip

{
  "type": "subscribe_betslip",
  "fixtureId": "id1000004461512432",
  "outcomeId": 103,
  "playerId": 0,
  "bookmakers": ["pinnacle", "sharpbet"],
  "ttl": 300
}
  • bookmakers 必须为非空列表。
  • ttl 可选(秒),限制在 10–3600 秒;省略时默认 60 秒
  • 对同一选项重新订阅会刷新 TTL 并更新博彩商集合(幂等)。
服务端确认:
{
  "type": "subscribed_betslip",
  "fixtureId": "id1000004461512432",
  "outcomeId": 103,
  "playerId": 0,
  "bookmakers": ["pinnacle", "sharpbet"],
  "expiresAt": "2026-02-07T17:34:37+00:00"
}
你没有账户的博彩商会从订阅中剔除,并在 skipped 数组中返回。每客户端最多 20 个活跃赔率单订阅(REST + WS 合计)。

unsubscribe_betslip

{
  "type": "unsubscribe_betslip",
  "fixtureId": "id1000004461512432",
  "outcomeId": 103,
  "playerId": 0
}

负载结构

数据消息将频道负载包裹在信封 {type, channel, event, payload, ts, seq} 中。ordersbetssettlements 频道投递完整数据库行row_to_json);balanceemergencybetslip 使用自定义结构。

Orders

orders 表的完整行:
{
  "orderId": 327,
  "requestUuid": "eb45b192-317b-42d5-9f65-af497b9fa8c1",
  "client": "demo",
  "clientName": "demo",
  "fixtureId": "id1000004461512432",
  "outcomeId": 103,
  "playerId": 0,
  "orderPrice": 1.95,
  "orderStake": 10.0,
  "filledStake": 10.0,
  "remainingStake": 0.0,
  "orderStatus": "FILLED",
  "statusReason": null,
  "userRef": "bettor1234",
  "testOrder": false,
  "acceptBetterOdds": true,
  "acceptPartialStake": true,
  "orderCurrency": "USD",
  "back": true,
  "allowedBookmakers": "*",
  "oddsInfo": null,
  "meta": {},
  "expiresAt": "2026-02-07T17:29:37+00:00",
  "filledAt": "2026-02-07T17:29:32+00:00",
  "createdAt": "2026-02-07T17:29:32+00:00",
  "updatedAt": "2026-02-07T17:29:32+00:00"
}

Bets / settlements

bets 表的完整行(settlements 频道使用相同结构):
{
  "betId": 73,
  "orderId": 327,
  "bookmaker": "pinnacle",
  "bookmakerBetId": "3332684214",
  "betStatus": "CONFIRMED",
  "settlementStatus": "UNSETTLED",
  "placedStake": 10.0,
  "placedPrice": 1.98,
  "placedCurrency": "USD",
  "account": "pinnacle_main",
  "requestUuid": "eb45b192-317b-42d5-9f65-af497b9fa8c1",
  "userRef": "bettor1234",
  "testBet": false,
  "client": "demo",
  "clientName": "demo",
  "sentData": { "stake": 10.0, "price": 1.95 },
  "receivedData": { "betId": "3332684214", "status": "accepted", "price": 1.98 },
  "settlementAmount": null,
  "settlementReason": null,
  "settledAt": null,
  "declineReason": null,
  "betRequestId": null,
  "oddsInfo": null,
  "meta": {},
  "placedAt": "2026-02-07T17:29:32+00:00",
  "createdAt": "2026-02-07T17:29:32+00:00",
  "updatedAt": "2026-02-07T17:29:32+00:00"
}
同时订阅 betssettlements 会使结算更新被投递两次——每个频道各一次。若想要专门的结算流,请单独使用 settlements

Balance

{
  "clientName": "demo",
  "bookmaker": "pinnacle",
  "username": "pinnacle_main",
  "balance": 4990.0,
  "currency": "USD",
  "ts": 1771183910123
}

Emergency

{
  "active": true,
  "reason": "Upstream provider maintenance",
  "ts": 1771183910123
}

Betslip

在赔率单订阅活跃期间推送。对于期货,负载携带 futureIdparticipantId 而非 fixtureId 赛事:
{
  "clientName": "demo",
  "fixtureId": "id1000004461512432",
  "outcomeId": 103,
  "playerId": 0,
  "odds": {
    "pinnacle": {
      "id1000004461512432:pinnacle:103:0": {
        "price": 1.98,
        "limit": 500.0,
        "limitMin": 1.0,
        "limitCurrency": "USD",
        "limitUsd": 500.0,
        "limitMinUsd": 1.0,
        "active": true,
        "account": "pinnacle_main",
        "currencyInfo": { "currency": "USD", "currencyValue": 1, "updatedAt": "2026-02-07T17:29:32+00:00" }
      }
    }
  }
}
期货(即将推出):
{
  "clientName": "demo",
  "futureId": "fut_123456",
  "outcomeId": 0,
  "playerId": 0,
  "participantId": 5,
  "odds": {
    "pinnacle": {
      "fut_123456:pinnacle:0:0:5": {
        "price": 3.50,
        "limit": 1000.0,
        "limitMin": 5.0,
        "limitCurrency": "USD",
        "limitUsd": 1000.0,
        "limitMinUsd": 5.0,
        "active": true,
        "account": "pinnacle_main",
        "currencyInfo": { "currency": "USD", "currencyValue": 1, "updatedAt": "2026-02-07T17:29:32+00:00" }
      }
    }
  }
}
期货赔率单的 WebSocket 广播尚未启用。订阅基础设施已就位,将在后续版本中激活。

连接限制

设置取值
每个 API key 最大连接数5
鉴权超时30 秒
服务端 ping 间隔30 秒
Pong 超时(断开)120 秒
消息缓冲(可靠投递)100 条消息
每客户端输出队列2000 条消息
每客户端最大赔率单订阅数20

后续步骤

币种与额度

各币种下数值如何计价与换算。

错误处理

处理错误响应与被拒原因。