Skip to main content

WebSocket Guide

This page covers connection lifecycle, heartbeat, reconnection strategy, and best practices that apply to all BTSE WebSocket endpoints (Spot, Futures, OTC).

For product-specific topics and subscription details, see the WebSocket API section in each product's sidebar.


Endpoints​

ProductProductionTestnet
Spot WebSocketwss://ws.btse.com/ws/spotwss://testws.btse.io/ws/spot
Spot OSSwss://ws.btse.com/ws/oss/spotwss://testws.btse.io/ws/oss/spot
Futures WebSocketwss://ws.btse.com/ws/futureswss://testws.btse.io/ws/futures
Futures OSSwss://ws.btse.com/ws/oss/futureswss://testws.btse.io/ws/oss/futures
Otc WebSocketwss://ws.btse.com/ws/otcwss://testws.btse.io/ws/otc
Otc OSSwss://ws.btse.com/ws/oss/otcwss://testws.btse.io/ws/oss/otc

Main vs OSS: The OSS (Order Stream Service) endpoint is a dedicated, high-throughput channel for orderbook data only. Use the main endpoint for everything else (trades, authentication, notifications, fills).


Connection Lifecycle​

Connect β†’ (optional) Authenticate β†’ Subscribe β†’ Receive messages
↑ |
└──────────── ping every 15s to keep alive β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  1. Connect β€” open a WebSocket to the appropriate endpoint
  2. Authenticate (private topics only) β€” send authKeyExpires with HMAC-SHA384 signature
  3. Subscribe β€” send {"op": "subscribe", "args": ["topic1", "topic2"]}
  4. Receive β€” messages arrive as JSON, except pong which is plain text
  5. Keep alive β€” send ping (plain text) at regular intervals

Heartbeat (Ping / Pong)​

Send a plain-text ping message to keep the connection alive. The server responds with pong.

ParameterValue
Recommended intervalEvery 15 seconds
Server timeoutConnections idle for 60 seconds without a ping are dropped
FormatPlain text ping (not JSON)
β†’ ping
← pong

If you miss the pong response, your connection may be stale β€” close and reconnect.


Reconnection Strategy​

Connections can drop due to network issues, server maintenance, or idle timeouts. Your client should handle disconnects gracefully:

  1. Detect disconnect β€” listen for WebSocket close and error events
  2. Wait before reconnecting β€” use exponential backoff:
    • 1st retry: 1 second
    • 2nd retry: 2 seconds
    • 3rd retry: 4 seconds
    • Max: 30 seconds between retries
  3. Re-authenticate β€” authentication does not persist across connections
  4. Re-subscribe β€” subscriptions do not persist across connections
  5. Resync state β€” for orderbook streams, the first message after re-subscribe is always a full snapshot

Orderbook-specific recovery​

If you detect any of these conditions, unsubscribe and re-subscribe to get a fresh snapshot:

  • Sequence gap β€” seqNum != prevSeqNum + 1
  • Crossed orderbook β€” best bid >= best ask
  • Stale data β€” no update received for an extended period

Connection Limits​

LimitValue
Max connections per IP50
Max subscriptions per connection100 topics
Message bufferIf the server's outbound buffer to your client fills up, the connection is closed (error code 1007)

To stay within limits:

  • Share a single connection for multiple topics when possible
  • Unsubscribe from topics you no longer need
  • Use OSS endpoints for orderbook data to keep the main connection lighter

Authentication​

Private topics (notifications, fills, positions) require authenticating the WebSocket session. Authentication is per-connection and does not expire until the connection closes.

Signature: HMAC-SHA384(secret, wsPath + nonce)

Where wsPath is the WebSocket path (e.g. /ws/spot, /ws/futures).

{
"op": "authKeyExpires",
"args": ["<API_KEY>", "<NONCE>", "<SIGNATURE>"]
}

See Quickstart β†’ Step 4 for complete code examples.


Subscription Format​

All topics use the same subscribe/unsubscribe format:

{"op": "subscribe", "args": ["topic1", "topic2"]}
{"op": "unsubscribe", "args": ["topic1"]}

The server acknowledges with:

{"event": "subscribe", "channel": ["topic1", "topic2"]}

Available Topics​

Spot (wss://ws.btse.com/ws/spot)​

TopicAuthDescription
tradeHistoryApi:<symbol>PublicReal-time trade feed
notificationApiV3PrivateOrder status updates
fillsPrivateTrade fill notifications

Spot OSS (wss://ws.btse.com/ws/oss/spot)​

TopicAuthDescription
snapshotL1:<symbol>PublicBest bid/ask (Level 1)
update:<symbol>_<grouping>PublicOrderbook incremental updates (snapshot + delta)

Futures (wss://ws.btse.com/ws/futures)​

TopicAuthDescription
tradeHistoryApiV3:<symbol>PublicReal-time trade feed
notificationApiV4PrivateOrder status updates
fillsV2PrivateTrade fill notifications
allPositionV4PrivateAll positions snapshot
positionsV3PrivatePosition updates

Futures OSS (wss://ws.btse.com/ws/oss/futures)​

TopicAuthDescription
snapshotL1:<symbol>_<grouping>PublicBest bid/ask by grouping
update:<symbol>_<grouping>PublicOrderbook incremental updates

OTC (wss://ws.btse.com/ws/otc)​

TopicAuthDescription
quotePrivateReal-time OTC quote stream

Error Codes (WebSocket)​

CodeMessageAction
1000Market pair not supportedCheck symbol name
1001Operation not supportedCheck op field
1002Invalid requestCheck required fields
1005Topic does not existCheck topic name format
1007Message buffer fullReduce subscription count or consume faster
1008Max failed attempts reachedSession closed β€” reconnect