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

PropertyValue
URLwss://api.t-dx.com/api/ws/v1/streams
Subprotocolws.t-dx.com (required)
Message FormatJSON

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"
}
FieldTypeRequiredDescription
estringYesEvent type
tstringYes*Topic (format: {target}@{category})
dobjectNoData payload
astringNoJWT 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}:

PatternExampleDescription
{pair}@tradesBTC/CHF@tradesTrade stream for a pair
{pair}@depth@{speed}BTC/CHF@depth@1000msOrder book for a pair (speed: 100ms, 1000ms)
{subAccountId}@balancesuuid@balancesBalance updates
{subAccountId}@balance-agg@{quote}uuid@balance-agg@CHFAggregate balance in quote currency
*@prices@{category}*@prices@auctionPrice 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

EventDescription
tdx:subscribeSubscribe to a topic
tdx:unsubscribeUnsubscribe from a topic
tdx:order_createCreate an order
tdx:order_cancelCancel an order
tdx:rfqRFQ operations (start, accept, stop)
tdx:cancel_on_disconnectEnable cancel-on-disconnect

Server Events

EventDescription
tdx:subscription_receivedSubscription confirmed
tdx:unsubscription_succeededUnsubscription confirmed
tdx:order_create_receivedOrder creation acknowledged
tdx:order_create_submittedOrder submitted to exchange
tdx:order_cancel_receivedCancel acknowledged
tdx:order_cancel_submittedCancel submitted
tdx:cancel_on_disconnect_succeededCancel-on-disconnect enabled
tdx:errorError notification

Data Events

EventDescription
tradeTrade execution
orderbookFull order book snapshot
updatePartial order book update
orderOrder status update
balanceBalance change
balance-aggAggregate balance update
pricePrice update
exposureExposure update
market_scheduleMarket 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"}
}
ScenarioDescription
Invalid topicTopic doesn't match expected format
Authentication requiredToken missing for private topic
Permission deniedUser lacks access to resource
Rate limitedToo many requests

Connection Management

Rate Limiting

Session TypeLimit
Anonymous1 message per 500ms
AuthenticatedNo 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




  © 2025 Taurus SA. All rights reserved.