Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.55-tech.com/llms.txt

Use this file to discover all available pages before exploring further.

Endpoint

wss://mmapi.55-tech.com/ws/subscribe

Connection flow

1. Connect

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

2. Subscribe

Send a subscribe message within 30 seconds of connecting:
{
  "type": "subscribe",
  "apiKey": "your-uuid-api-key",
  "channels": ["orders", "bets", "accounts", "scores", "emergency"]
}

3. Confirmation

On success, the server responds with:
{
  "type": "subscribed",
  "subscriptionId": 1,
  "channels": ["orders", "bets", "accounts", "scores", "emergency"]
}

4. Receive broadcasts

Data updates arrive as broadcast messages with both current and previous state:
{
  "type": "broadcast",
  "channel": "orders",
  "event": "UPDATE",
  "payload": {
    "orderId": 123,
    "orderStatus": "FILLED",
    "matchedStake": 100.0,
    "matchedAt": "2026-02-15T10:30:05Z"
  },
  "old": {
    "orderStatus": "PLACED",
    "matchedStake": 0
  }
}
The old field contains the previous state, making it easy to detect what changed.

5. Keep alive

Send a ping to keep the connection alive:
{"type": "ping"}
Server responds with:
{"type": "pong"}
The server also sends heartbeats every 60 seconds:
{"type": "heartbeat"}

6. Unsubscribe

To stop receiving updates and clean up your subscription:
{"type": "unsubscribe"}

Channels

Client-filtered channels

These channels only deliver data belonging to your client:
ChannelEventsDescription
ordersINSERT, UPDATEExchange order placement, status changes, fills
betsINSERT, UPDATEHedge bet placement, confirmation, settlement
accountsUPDATEAccount balance and status changes

Global channels

All subscribers receive these:
ChannelEventsDescription
scoresUPDATELive score updates (goals, sets, periods)
emergencyUPDATEEmergency mode activation/deactivation

Payload examples

Order fill

When an exchange order gets matched:
{
  "type": "broadcast",
  "channel": "orders",
  "event": "UPDATE",
  "payload": {
    "orderId": 123,
    "fixtureId": "id1000000861624412",
    "outcomeId": 161,
    "exchange": "polymarket",
    "exchangeOrderId": "0x1a2b3c...",
    "orderStatus": "FILLED",
    "matchedStatus": "FULLY_MATCHED",
    "orderCents": 0.45,
    "orderStake": 100.0,
    "matchedStake": 100.0,
    "matchedAt": "2026-02-15T10:30:05Z"
  },
  "old": {
    "orderStatus": "PLACED",
    "matchedStatus": "NOT_MATCHED",
    "matchedStake": 0
  }
}

Hedge bet placed

After an order fills, the system automatically places a hedge bet:
{
  "type": "broadcast",
  "channel": "bets",
  "event": "INSERT",
  "payload": {
    "betId": 456,
    "orderId": 123,
    "client": "your-client",
    "bookmaker": "vertex",
    "placedPrice": 1.808,
    "placedStake": 100.0,
    "betStatus": "placed",
    "sentData": {
      "requestId": "a1b2c3d4",
      "eventId": 98765,
      "price": 1.808,
      "amount": 100.0,
      "side": "1"
    },
    "receivedData": {
      "betId": "789",
      "status": "U"
    },
    "placedAt": "2026-02-15T10:30:08Z"
  }
}

Live score update

{
  "type": "broadcast",
  "channel": "scores",
  "event": "UPDATE",
  "payload": {
    "fixtureId": "id1000000861624412",
    "live": true,
    "statusId": 1,
    "currentPeriod": "2nd Half",
    "currentMinute": 67,
    "scores": {
      "home": 2,
      "away": 1,
      "period1Home": 1,
      "period1Away": 0
    }
  }
}

Emergency status

{
  "type": "broadcast",
  "channel": "emergency",
  "event": "UPDATE",
  "payload": {
    "emergency": true,
    "reason": "Manual trigger",
    "triggeredAt": "2026-02-15T10:30:00Z"
  }
}

Connection limits

SettingValue
Max connections per API key5
Auth timeout30 seconds
Server heartbeat interval60 seconds
Client ping interval30 seconds (recommended)

Error messages

ErrorDescription
apiKey requiredMissing apiKey field in subscribe message
Invalid apiKey formatAPI key must be a valid UUID
Invalid API keyAPI key not found or client is inactive
Connection limit exceededAlready have 5 active connections for this API key

Example: Python client

import asyncio
import json
import websockets

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

        # Wait for confirmation
        sub_resp = json.loads(await ws.recv())
        print(f"Subscribed (id={sub_resp.get('subscriptionId')})")

        # Keep-alive task
        async def keep_alive():
            while True:
                await asyncio.sleep(30)
                await ws.send(json.dumps({"type": "ping"}))

        asyncio.create_task(keep_alive())

        # Listen for updates
        async for message in ws:
            data = json.loads(message)
            if data["type"] == "broadcast":
                channel = data["channel"]
                event = data["event"]
                print(f"[{channel}:{event}] {data['payload']}")
                if "old" in data:
                    print(f"  Changed from: {data['old']}")

asyncio.run(connect())

Example: JavaScript client

const WebSocket = require('ws');

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

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

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

  if (msg.type === 'subscribed') {
    console.log(`Subscribed (id=${msg.subscriptionId})`);
  }

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

// Keep alive
setInterval(() => {
  if (ws.readyState === WebSocket.OPEN) {
    ws.send(JSON.stringify({ type: 'ping' }));
  }
}, 30000);