Skip to main content

Endpoint

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

Connection flow

1. Connect

Open a WebSocket connection. No authentication is needed at connection time.

2. Login

Send a login message within 30 seconds of connecting:
{
  "type": "login",
  "apiKey": "YOUR_API_KEY",
  "channels": []
}
An empty channels array subscribes to all available channels. To subscribe to specific channels:
{
  "type": "login",
  "apiKey": "YOUR_API_KEY",
  "channels": ["orders", "bets", "settlements"]
}
You can optionally enable reliable delivery with message acknowledgments:
{
  "type": "login",
  "apiKey": "YOUR_API_KEY",
  "channels": ["orders", "bets"],
  "reliableDelivery": true
}

3. Login confirmation

On success, the server responds with:
{
  "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. Receive updates

Data messages follow this format:
{
  "type": "data",
  "channel": "orders",
  "event": "INSERT",
  "payload": { ... },
  "ts": 1771183909789,
  "seq": 1
}
FieldDescription
typeAlways "data" for data messages
channelWhich channel this message belongs to
eventEvent type: INSERT, UPDATE, DELETE, SETTLED, STATUS
payloadThe full updated object (see per-channel payload schemas below)
tsServer timestamp (milliseconds since epoch)
seqPer-subscription monotonically increasing sequence number
requireAckPresent and true only when reliable delivery is enabled

5. Keep alive

The server sends a ping every 30 seconds:
{"type": "ping"}
Respond with pong within 120 seconds or the connection is closed:
{"type": "pong"}
You can also send pings from the client — the server responds with pong.

Channels

Client-filtered channels

These channels only deliver data belonging to your clientName:
ChannelEventsDescription
ordersINSERT, UPDATE, DELETEOrder placement, fills, status changes
betsINSERT, UPDATE, DELETEBet placement, confirmation, and removal
settlementsSETTLEDSettlement status updates (same payload as bets)
accountsINSERT, UPDATE, DELETEAccount creation, updates, and deletion
balanceUPDATEBalance change notifications
betslipUPDATEReal-time odds updates for active betslip subscriptions (60s window after each GET /betslip call)

Global channels

All subscribers receive these:
ChannelEventsDescription
fixturesUPDATEFixture metadata and score changes
currenciesUPDATECurrency exchange rate updates
statusSTATUSSystem status changes
emergencySTATUSEmergency mode activation/deactivation

Payload schemas

Orders payload

Full database row from the orders table:
{
  "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 payload

Full database row from the bets table:
{
  "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"
}

Balance payload

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

Emergency payload

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

Betslip payload

Real-time odds updates pushed while a betslip subscription is active. Calling GET /betslip registers a 60-second sliding window — during this window, price changes are broadcast in the same shape as the betslip REST response. Each poll resets the timer. This applies to both fixture-based and futures-based betslip subscriptions. For futures, the payload includes futureId and participantId instead of (or in addition to) fixtureId. Fixture betslip example:
{
  "fixtureId": "id1000004461512432",
  "outcomeId": 103,
  "playerId": 0,
  "client": "demo",
  "userRef": null,
  "odds": {
    "pinnacle": {
      "odds_12345": {
        "price": 1.98,
        "limit": 500.0,
        "limitMin": 1.0,
        "limitCurrency": "USD",
        "limitUsd": 500.0,
        "limitMinUsd": 1.0,
        "active": true,
        "account": "pinnacle_main"
      }
    }
  }
}
Futures betslip example (coming soon):
{
  "futureId": "fut_123456",
  "outcomeId": 0,
  "playerId": 0,
  "participantId": 5,
  "client": "demo",
  "userRef": null,
  "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"
      }
    }
  }
}
Futures betslip WebSocket broadcasting is not yet enabled. The subscription infrastructure is in place and will be activated in an upcoming release.

Connection limits

SettingValue
Max connections per API key5
Auth timeout30 seconds
Server ping interval30 seconds
Pong timeout (disconnect)120 seconds
Message buffer (reliable delivery)100 messages
Output queue per client2000 messages

Example: Python client

import asyncio
import json
import websockets

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

        # Wait for login confirmation
        login_resp = json.loads(await ws.recv())
        print(f"Logged in as {login_resp.get('clientName')}")

        # Listen for updates (respond to pings automatically)
        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())

Example: JavaScript client

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(`Logged in as ${msg.clientName}`);
  }

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

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