> This page is for Taurus PRIME.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://taurushq.ferndocs.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://taurushq.ferndocs.com/_mcp/server.

# WebSocket Connection

# 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

```javascript
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

```python
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

```json
{
  "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

```json
{
  "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](/prime/docs/api-webs-topics) for complete topic documentation.

---

## Authentication

### Per-Message Authentication

Include the token in each message:

```json
{
  "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

```json
// 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

```json
// 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)

```json
// 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

```json
{
  "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:

```json
{"e": "tdx:cancel_on_disconnect", "a": "jwt_token"}
```

Only one cancel-on-disconnect session per client account is allowed.

---

## Reconnection Strategy

```javascript
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](/prime/docs/api-webs-topics) - Complete topic documentation with message structures