WebSocket Connection
Real-time streaming setup and message format
WebSocket Connection
The PRIME WebSocket API provides real-time streaming for market data, order updates, and balance changes.
Connection Details
| Property | Value |
|---|---|
| URL | wss://api.t-dx.com/api/ws/v1/streams |
| Subprotocol | ws.t-dx.com (required) |
| Message Format | JSON |
Connecting
JavaScript Example
const ws = new WebSocket(
'wss://api.t-dx.com/api/ws/v1/streams',
'ws.t-dx.com' // Required subprotocol
);
ws.onopen = () => {
console.log('Connected');
// Subscribe to trades
ws.send(JSON.stringify({
e: 'tdx:subscribe',
t: 'BTC/CHF@trades'
}));
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
console.log('Received:', message);
};
ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
ws.onclose = (event) => {
console.log('Disconnected:', event.code, event.reason);
};Python Example
import websockets
import json
import asyncio
async def connect():
uri = "wss://api.t-dx.com/api/ws/v1/streams"
async with websockets.connect(uri, subprotocols=["ws.t-dx.com"]) as ws:
# Subscribe to trades
await ws.send(json.dumps({
"e": "tdx:subscribe",
"t": "BTC/CHF@trades"
}))
async for message in ws:
data = json.loads(message)
print(f"Received: {data}")
asyncio.run(connect())Important: The subprotocol ws.t-dx.com is required. Connections without it will be rejected.
Message Format
Client Request
{
"e": "tdx:subscribe",
"t": "BTC/CHF@trades",
"d": {},
"a": "jwt_token"
}| Field | Type | Required | Description |
|---|---|---|---|
e | string | Yes | Event type |
t | string | Yes* | Topic (format: {target}@{category}) |
d | object | No | Data payload |
a | string | No | JWT bearer token |
*Topic is required for all events except tdx:cancel_on_disconnect
Server Response
{
"e": "event_type",
"t": "topic",
"d": {}
}Topic Format
Topics follow the format {target}@{category} or {target}@{category}@{parameter}:
| Pattern | Example | Description |
|---|---|---|
{pair}@trades | BTC/CHF@trades | Trade stream for a pair |
{pair}@depth@{speed} | BTC/CHF@depth@1000ms | Order book for a pair (speed: 100ms, 1000ms) |
{subAccountId}@balances | uuid@balances | Balance updates |
{subAccountId}@balance-agg@{quote} | uuid@balance-agg@CHF | Aggregate balance in quote currency |
*@prices@{category} | *@prices@auction | Price feed by category |
See WebSocket Topics Reference for complete topic documentation.
Authentication
Per-Message Authentication
Include the token in each message:
{
"e": "tdx:subscribe",
"t": "uuid@balances",
"a": "eyJhbGciOiJSUzI1NiIs..."
}Connection Header
Pass token during connection via HTTP header:
Authorization: bearer <jwt_token>
Message-level authentication (a field) overrides connection-level authentication.
Anonymous Access
Public data (trades, depth, prices) is available without authentication. Account-specific data (balances, orders) requires authentication.
Event Types
Client Events
| Event | Description |
|---|---|
tdx:subscribe | Subscribe to a topic |
tdx:unsubscribe | Unsubscribe from a topic |
tdx:order_create | Create an order |
tdx:order_cancel | Cancel an order |
tdx:rfq | RFQ operations (start, accept, stop) |
tdx:cancel_on_disconnect | Enable cancel-on-disconnect |
Server Events
| Event | Description |
|---|---|
tdx:subscription_received | Subscription confirmed |
tdx:unsubscription_succeeded | Unsubscription confirmed |
tdx:order_create_received | Order creation acknowledged |
tdx:order_create_submitted | Order submitted to exchange |
tdx:order_cancel_received | Cancel acknowledged |
tdx:order_cancel_submitted | Cancel submitted |
tdx:cancel_on_disconnect_succeeded | Cancel-on-disconnect enabled |
tdx:error | Error notification |
Data Events
| Event | Description |
|---|---|
trade | Trade execution |
orderbook | Full order book snapshot |
update | Partial order book update |
order | Order status update |
balance | Balance change |
balance-agg | Aggregate balance update |
price | Price update |
exposure | Exposure update |
market_schedule | Market schedule change |
Quick Examples
Subscribe to Trades
// Request
{"e": "tdx:subscribe", "t": "BTC/CHF@trades"}
// Confirmation
{"e": "tdx:subscription_received", "t": "BTC/CHF@trades"}
// Trade event
{
"e": "trade",
"t": "BTC/CHF@trades",
"d": {"d": 1705667200000, "p": "45000.50", "q": "1.5", "i": "trade-id", "a": "BUY"}
}Subscribe to Order Book
// Request (speed parameter is required: 100ms or 1000ms)
{"e": "tdx:subscribe", "t": "BTC/CHF@depth@1000ms"}
// Order book snapshot
{
"e": "orderbook",
"t": "BTC/CHF@depth@1000ms",
"d": {
"u": 12345,
"b": [["44999", "1.0"]],
"a": [["45001", "0.5"]]
}
}Subscribe to Balances (Authenticated)
// Request
{"e": "tdx:subscribe", "t": "uuid@balances", "a": "jwt_token"}
// Balance update
{
"e": "balance",
"t": "uuid@balances",
"d": {"i": "btc-id", "a": "2.5", "o": "0.5", "w": "0.1", "c": "0.0"}
}Error Handling
{
"e": "tdx:error",
"t": "invalid@topic",
"d": {"message": "Invalid topic format"}
}| Scenario | Description |
|---|---|
| Invalid topic | Topic doesn't match expected format |
| Authentication required | Token missing for private topic |
| Permission denied | User lacks access to resource |
| Rate limited | Too many requests |
Connection Management
Rate Limiting
| Session Type | Limit |
|---|---|
| Anonymous | 1 message per 500ms |
| Authenticated | No limit for subscriptions |
Debouncing
High-frequency updates (prices, balances) are debounced at 500ms intervals.
Keep-Alive
The server sends periodic ping frames. Most WebSocket libraries handle pong responses automatically.
Cancel on Disconnect
Enable automatic order cancellation when disconnected:
{"e": "tdx:cancel_on_disconnect", "a": "jwt_token"}Only one cancel-on-disconnect session per client account is allowed.
Reconnection Strategy
class WebSocketClient {
constructor(url, token) {
this.url = url;
this.token = token;
this.reconnectDelay = 1000;
this.maxReconnectDelay = 30000;
this.subscriptions = new Set();
}
connect() {
this.ws = new WebSocket(this.url, 'ws.t-dx.com');
this.ws.onopen = () => {
this.reconnectDelay = 1000;
this.resubscribe();
};
this.ws.onclose = () => {
this.scheduleReconnect();
};
}
scheduleReconnect() {
setTimeout(() => this.connect(), this.reconnectDelay);
this.reconnectDelay = Math.min(this.reconnectDelay * 2, this.maxReconnectDelay);
}
resubscribe() {
for (const topic of this.subscriptions) {
this.subscribe(topic);
}
}
subscribe(topic) {
this.subscriptions.add(topic);
this.ws.send(JSON.stringify({
e: 'tdx:subscribe',
t: topic,
a: this.token
}));
}
}Related
- WebSocket Topics Reference - Complete topic documentation with message structures
Updated 5 days ago
