> 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.

# Topics Reference

# WebSocket Topics Reference

This document provides complete documentation for all WebSocket topics, including message structures and field descriptions.

## Topic Overview

| Topic                                             | Pattern                      | Auth | Description                                   |
| ------------------------------------------------- | ---------------------------- | ---- | --------------------------------------------- |
| [Trades](#trades)                                 | `{pair}@trades`              | No   | Public trade stream                           |
| [Depth](#depth-order-book)                        | `{pair}@depth@{speed}`       | No   | Order book updates (speed: `100ms`, `1000ms`) |
| [Prices](#prices)                                 | `*@prices@{category}`        | No   | Price feed                                    |
| [Market Schedules](#market-schedules)             | `{pair}@market-schedules`    | No   | Trading hours                                 |
| [Sub-Account Orders](#sub-account-orders)         | `{id}@subaccount-orders`     | Yes  | Order updates                                 |
| [Sub-Account OTC Orders](#sub-account-otc-orders) | `{id}@subaccount-otc-orders` | Yes  | OTC order updates                             |
| [Balances](#balances)                             | `{id}@balances`              | Yes  | Balance updates                               |
| [Balance Aggregate](#balance-aggregate)           | `{id}@balance-agg@{quote}`   | Yes  | Aggregate balance                             |
| [Exposures](#exposures)                           | `{id}@exposures`             | Yes  | Exposure updates                              |
| [OTC Trades](#otc-trades)                         | `{pair}@otc-trades`          | No   | OTC trade stream                              |
| [OTC Depth Snapshots](#otc-depth-snapshots)       | `{pair}@otc-depth-snapshots` | No   | OTC depth                                     |
| [OTC Pair Listings](#otc-listings)                | `{pair}@otc-listings`        | No   | OTC availability                              |

---

## Public Topics

### Trades

Real-time trade stream for a trading pair.

**Topic:** `{pair}@trades`
**Example:** `BTC/CHF@trades`
**Authentication:** Not required

#### Subscribe

```json
{
  "e": "tdx:subscribe",
  "t": "BTC/CHF@trades"
}
```

#### Confirmation

```json
{
  "e": "tdx:subscription_received",
  "t": "BTC/CHF@trades"
}
```

#### Trade Event

```json
{
  "e": "trade",
  "t": "BTC/CHF@trades",
  "d": {
    "d": 1705667200000,
    "p": "45000.50",
    "q": "1.5",
    "i": "trade-uuid",
    "a": "BUY"
  }
}
```

| Field | Type    | Description                     |
| ----- | ------- | ------------------------------- |
| `d`   | integer | Timestamp (Unix milliseconds)   |
| `p`   | string  | Price                           |
| `q`   | string  | Quantity                        |
| `i`   | string  | Trade ID                        |
| `a`   | string  | Aggressor side: `BUY` or `SELL` |

---

### Depth (Order Book)

Order book depth updates for a trading pair.

**Topic:** `{pair}@depth@{speed}`
**Speed Values:** `100ms`, `1000ms`
**Example:** `BTC/CHF@depth@1000ms`
**Authentication:** Not required

> **Note:** The speed parameter is required. It determines how frequently updates are sent (e.g., `100ms` for 10 updates/second, `1000ms` for 1 update/second).

#### Subscribe

```json
{
  "e": "tdx:subscribe",
  "t": "BTC/CHF@depth@1000ms"
}
```

#### Full Snapshot Event

Sent on initial subscription and periodically.

```json
{
  "e": "orderbook",
  "t": "BTC/CHF@depth@1000ms",
  "d": {
    "u": 12345,
    "b": [
      ["44999.00", "1.0"],
      ["44998.00", "2.5"]
    ],
    "a": [
      ["45001.00", "0.5"],
      ["45002.00", "1.2"]
    ]
  }
}
```

| Field | Type    | Description                                                                                          |
| ----- | ------- | ---------------------------------------------------------------------------------------------------- |
| `u`   | integer | Update ID (always present)                                                                           |
| `b`   | array   | Bids (buy orders) as `[[price, quantity], ...]`, sorted by price descending. **Omitted if no bids.** |
| `a`   | array   | Asks (sell orders) as `[[price, quantity], ...]`, sorted by price ascending. **Omitted if no asks.** |

> **Note:** When the orderbook is completely empty, only `u` is present: `{"u": 12345}`

#### Incremental Update Event

Partial updates between snapshots.

```json
{
  "e": "update",
  "t": "BTC/CHF@depth@1000ms",
  "d": {
    "u": 12340,
    "U": 12345,
    "b": [["44999.00", "1.5"]],
    "a": [["45001.00", "0.0"]]
  }
}
```

| Field | Type    | Description                                                             |
| ----- | ------- | ----------------------------------------------------------------------- |
| `u`   | integer | First update ID in this batch                                           |
| `U`   | integer | Last update ID in this batch                                            |
| `b`   | array   | Changed bids as `[[price, quantity], ...]` (quantity `"0.0"` = removed) |
| `a`   | array   | Changed asks as `[[price, quantity], ...]` (quantity `"0.0"` = removed) |

---

### Prices

Real-time price feed. Supports multiple price categories.

**Topic:** `*@prices@{category}`
**Categories:** `platform`, `mid`, `auction`, `market`
**Example:** `*@prices@auction`
**Authentication:** Not required
**Debouncing:** Yes (500ms)

#### Subscribe

```json
{
  "e": "tdx:subscribe",
  "t": "*@prices@auction"
}
```

#### Price Event

```json
{
  "e": "price",
  "t": "BTC/CHF@prices@auction",
  "d": {
    "v": "45000.50",
    "c": "-500.00",
    "C": "-1.10"
  }
}
```

| Field | Type              | Description             |
| ----- | ----------------- | ----------------------- |
| `v`   | string            | Current price value     |
| `c`   | string (optional) | 24h change (absolute)   |
| `C`   | string (optional) | 24h change (percentage) |

**Note:** The topic in the response includes the actual pair symbol, not the wildcard.

---

### Market Schedules

Trading schedule updates for a pair.

**Topic:** `{pair}@market-schedules`
**Example:** `BTC/CHF@market-schedules`
**Authentication:** Not required

#### Subscribe

```json
{
  "e": "tdx:subscribe",
  "t": "BTC/CHF@market-schedules"
}
```

#### Schedule Event

```json
{
  "e": "market_schedule",
  "t": "BTC/CHF@market-schedules",
  "d": {
    "c": {
      "state": "OPEN",
      "start": "2025-01-19T09:00:00Z",
      "end": "2025-01-19T17:00:00Z"
    },
    "n": {
      "state": "CLOSED",
      "start": "2025-01-19T17:00:00Z",
      "end": "2025-01-20T09:00:00Z"
    },
    "t": "2025-01-19T17:00:00Z"
  }
}
```

| Field     | Type                 | Description                                      |
| --------- | -------------------- | ------------------------------------------------ |
| `c`       | object               | Current period                                   |
| `c.state` | string               | Current state: `OPEN`, `CLOSED`, `AUCTION`, etc. |
| `c.start` | timestamp            | Period start time                                |
| `c.end`   | timestamp            | Period end time                                  |
| `n`       | object (optional)    | Next period                                      |
| `t`       | timestamp (optional) | Time of next period change                       |

---

## Authenticated Topics

### Sub-Account Orders

Order updates for a specific sub-account. Used for both subscribing to updates and placing/canceling orders.

**Topic:** `{subAccountId}@subaccount-orders`
**Authentication:** Required

#### Subscribe

```json
{
  "e": "tdx:subscribe",
  "t": "7376524e-6b6b-4137-9719-7e07a7709804@subaccount-orders",
  "a": "jwt_token"
}
```

#### Order Event

Sent when an order status changes.

```json
{
  "e": "order",
  "t": "7376524e-6b6b-4137-9719-7e07a7709804@subaccount-orders",
  "d": {
    "requestId": "req-123",
    "orderId": "order-456",
    "clientOrderId": "client-123",
    "status": "NEW",
    "type": "LIMIT",
    "side": "BUY",
    "quantity": "1.5",
    "cumulativeQuantity": "0.0",
    "price": "45000.50",
    "symbol": "BTC/CHF"
  }
}
```

| Field                | Type   | Description                  |
| -------------------- | ------ | ---------------------------- |
| `requestId`          | string | Request ID (for correlation) |
| `orderId`            | string | Order ID                     |
| `clientOrderId`      | string | Client-provided order ID     |
| `status`             | string | Order status (see below)     |
| `type`               | string | `LIMIT` or `MARKET`          |
| `side`               | string | `BUY` or `SELL`              |
| `quantity`           | string | Order quantity               |
| `cumulativeQuantity` | string | Filled quantity              |
| `price`              | string | Limit price                  |
| `symbol`             | string | Pair symbol                  |

**Order Status Values:** `NEW`, `PARTIALLY_FILLED`, `FILLED`, `CANCELED`, `REJECTED`, `EXPIRED`

#### Order Cancel Rejection Event

Sent when a cancel request fails.

```json
{
  "e": "order_cancel_reject",
  "t": "7376524e-6b6b-4137-9719-7e07a7709804@subaccount-orders",
  "d": {
    "orderId": "order-456",
    "clientOrderId": "client-123",
    "reason": "Order not found",
    "text": "Unable to cancel"
  }
}
```

#### Create Order

```json
{
  "e": "tdx:order_create",
  "t": "7376524e-6b6b-4137-9719-7e07a7709804@subaccount-orders",
  "a": "jwt_token",
  "d": {
    "dry": false,
    "order": {
      "subAccountId": "7376524e-6b6b-4137-9719-7e07a7709804",
      "symbol": "BTC/CHF",
      "side": "BUY",
      "type": "LIMIT",
      "quantity": "1.5",
      "price": "45000.50",
      "timeInForce": "GTC",
      "clientOrderId": "client-123"
    }
  }
}
```

| Field                 | Type    | Required  | Description                         |
| --------------------- | ------- | --------- | ----------------------------------- |
| `dry`                 | boolean | No        | If true, validates without creating |
| `order.subAccountId`  | string  | Yes       | Sub-account ID                      |
| `order.symbol`        | string  | Yes       | Pair symbol                         |
| `order.side`          | string  | Yes       | `BUY` or `SELL`                     |
| `order.type`          | string  | Yes       | `LIMIT` or `MARKET`                 |
| `order.quantity`      | string  | Yes       | Order quantity                      |
| `order.price`         | string  | For LIMIT | Limit price                         |
| `order.timeInForce`   | string  | No        | `GTC`, `IOC`, `FOK`                 |
| `order.clientOrderId` | string  | No        | Client-provided ID                  |
| `order.minQuantity`   | string  | No        | Minimum fill quantity               |

**Response:**

```json
{"e": "tdx:order_create_received", "t": "...@subaccount-orders"}
```

```json
{
  "e": "tdx:order_create_submitted",
  "t": "...@subaccount-orders",
  "d": {"clientOrderId": "client-123", "orderId": "order-789"}
}
```

#### Cancel Order

Order cancellation is **asynchronous**. The server responds in stages:

1. **Acknowledgment** (`tdx:order_cancel_received`) - Request received
2. **Submission** (`tdx:order_cancel_submitted`) - Cancel submitted to exchange
3. **Result** (async) - Either `order` event (status changed) or `order_cancel_reject` if failed

```json
{
  "e": "tdx:order_cancel",
  "t": "7376524e-6b6b-4137-9719-7e07a7709804@subaccount-orders",
  "a": "jwt_token",
  "d": {
    "orderId": "order-789",
    "subAccountId": "7376524e-6b6b-4137-9719-7e07a7709804"
  }
}
```

**Response Flow:**

```json
// Step 1: Acknowledgment (immediate)
{"e": "tdx:order_cancel_received", "t": "...@subaccount-orders"}

// Step 2: Submission
{
  "e": "tdx:order_cancel_submitted",
  "t": "...@subaccount-orders",
  "d": {"requestId": "req-789", "orderId": "order-789"}
}

// Step 3: Result (async - may arrive later)
// Success: order event with updated status
// Failure: order_cancel_reject event
```

> **Note:** The `order_cancel_reject` event arrives asynchronously and may not be immediate. Applications should handle timeouts and check order status separately if confirmation is critical.

---

### Sub-Account OTC Orders

OTC order updates for a specific sub-account.

**Topic:** `{subAccountId}@subaccount-otc-orders`
**Authentication:** Required

#### Subscribe

```json
{
  "e": "tdx:subscribe",
  "t": "7376524e-6b6b-4137-9719-7e07a7709804@subaccount-otc-orders",
  "a": "jwt_token"
}
```

#### OTC Order Update Event

```json
{
  "e": "otc_order_update",
  "t": "7376524e-6b6b-4137-9719-7e07a7709804@subaccount-otc-orders",
  "d": {
    "id": "otc-order-123",
    "subAccountId": "7376524e-6b6b-4137-9719-7e07a7709804",
    "clientOrderId": "client-456",
    "pairId": "pair-789",
    "status": "PENDING",
    "type": "MARKET",
    "side": "BUY",
    "clientAmount": "50000.00",
    "quantity": "1.0",
    "cumulativeQuantity": "0.0",
    "price": "50000.00",
    "timeInForce": "GTC",
    "comment": "optional comment",
    "createdAt": "2025-01-19T10:00:00Z",
    "updatedAt": "2025-01-19T10:00:00Z",
    "triggeredAt": null
  }
}
```

| Field                | Type      | Description                          |
| -------------------- | --------- | ------------------------------------ |
| `id`                 | string    | OTC order ID                         |
| `subAccountId`       | string    | Sub-account ID                       |
| `clientOrderId`      | string    | Client-provided ID                   |
| `pairId`             | string    | Pair ID                              |
| `status`             | string    | Status (see OTC order status values) |
| `type`               | string    | Order type                           |
| `side`               | string    | `BUY` or `SELL`                      |
| `clientAmount`       | string    | Amount charged to client             |
| `quantity`           | string    | Order quantity                       |
| `cumulativeQuantity` | string    | Filled quantity                      |
| `price`              | string    | Execution price                      |
| `timeInForce`        | string    | `GTC`, etc.                          |
| `comment`            | string    | Optional comment                     |
| `createdAt`          | timestamp | Creation time                        |
| `updatedAt`          | timestamp | Last update time                     |
| `triggeredAt`        | timestamp | Trigger time (for scheduled orders)  |

**OTC Order Status Values:** `TENTATIVE`, `PENDING`, `OPEN`, `FILLED`, `CANCELED`, `REJECTED`, `PENDING_CANCEL`

---

### Balances

Balance updates for a sub-account. Updates are debounced by instrument.

**Topic:** `{subAccountId}@balances`
**Authentication:** Required
**Debouncing:** Yes (500ms, by instrument)

#### Subscribe

```json
{
  "e": "tdx:subscribe",
  "t": "7376524e-6b6b-4137-9719-7e07a7709804@balances",
  "a": "jwt_token"
}
```

#### Balance Event

```json
{
  "e": "balance",
  "t": "7376524e-6b6b-4137-9719-7e07a7709804@balances",
  "d": {
    "i": "btc-instrument-uuid",
    "a": "2.50000000",
    "o": "0.50000000",
    "w": "0.10000000",
    "c": "0.00000000"
  }
}
```

| Field | Type   | Description          |
| ----- | ------ | -------------------- |
| `i`   | string | Instrument ID        |
| `a`   | string | Available balance    |
| `o`   | string | Orders reserved      |
| `w`   | string | Withdrawals reserved |
| `c`   | string | Settlement line used |

---

### Balance Aggregate

Aggregate portfolio value in a quote currency. Updates are debounced.

**Topic:** `{subAccountId}@balance-agg@{quoteCurrency}`
**Example:** `7376524e-6b6b-4137-9719-7e07a7709804@balance-agg@CHF`
**Authentication:** Required
**Debouncing:** Yes (500ms, by quote currency)

#### Subscribe

```json
{
  "e": "tdx:subscribe",
  "t": "7376524e-6b6b-4137-9719-7e07a7709804@balance-agg@CHF",
  "a": "jwt_token"
}
```

#### Balance Aggregate Event

```json
{
  "e": "balance-agg",
  "t": "7376524e-6b6b-4137-9719-7e07a7709804@balance-agg@CHF",
  "d": {
    "q": "CHF",
    "v": "500000.00"
  }
}
```

| Field | Type   | Description                   |
| ----- | ------ | ----------------------------- |
| `q`   | string | Quote currency                |
| `v`   | string | Total value in quote currency |

---

### Exposures

Exposure and overdraft updates for a sub-account.

**Topic:** `{subAccountId}@exposures`
**Authentication:** Required

#### Subscribe

```json
{
  "e": "tdx:subscribe",
  "t": "7376524e-6b6b-4137-9719-7e07a7709804@exposures",
  "a": "jwt_token"
}
```

#### Exposure Event

```json
{
  "e": "exposure",
  "t": "7376524e-6b6b-4137-9719-7e07a7709804@exposures",
  "d": {
    "i": "quotation-instrument-uuid",
    "o": "100000.00",
    "u": "50000.00"
  }
}
```

| Field | Type   | Description             |
| ----- | ------ | ----------------------- |
| `i`   | string | Quotation instrument ID |
| `o`   | string | Overdraft amount        |
| `u`   | string | Utilized amount         |

---

## OTC Topics

### OTC Trades

Public OTC trade stream for a pair.

**Topic:** `{pair}@otc-trades`
**Example:** `BTC/USD@otc-trades`
**Authentication:** Not required

#### Subscribe

```json
{
  "e": "tdx:subscribe",
  "t": "BTC/USD@otc-trades"
}
```

#### OTC Trade Event

```json
{
  "e": "otc-trade",
  "t": "BTC/USD@otc-trades",
  "d": {
    "i": "otc-trade-uuid",
    "p": "50000.00",
    "q": "1.0",
    "s": "Buy",
    "d": 1705667200000
  }
}
```

| Field | Type    | Description                   |
| ----- | ------- | ----------------------------- |
| `i`   | string  | Trade ID                      |
| `p`   | string  | Price                         |
| `q`   | string  | Quantity                      |
| `s`   | string  | Side: `Buy` or `Sell`         |
| `d`   | integer | Timestamp (Unix milliseconds) |

---

### OTC Depth Snapshots

OTC liquidity depth snapshots.

**Topic:** `{pair}@otc-depth-snapshots`
**Example:** `BTC/USD@otc-depth-snapshots`
**Authentication:** Not required

#### Subscribe

```json
{
  "e": "tdx:subscribe",
  "t": "BTC/USD@otc-depth-snapshots"
}
```

#### OTC Depth Snapshot Event

```json
{
  "e": "otc-depth-snapshot",
  "t": "BTC/USD@otc-depth-snapshots",
  "d": {
    "symbol": "BTC/USD",
    "bids": [
      {"price": "49999.00", "quantity": "0.5"},
      {"price": "49998.00", "quantity": "1.0"}
    ],
    "asks": [
      {"price": "50001.00", "quantity": "0.5"},
      {"price": "50002.00", "quantity": "1.0"}
    ],
    "timestamp": "2025-01-19T10:00:00Z"
  }
}
```

| Field             | Type      | Description   |
| ----------------- | --------- | ------------- |
| `symbol`          | string    | Pair symbol   |
| `bids`            | array     | Bid levels    |
| `asks`            | array     | Ask levels    |
| `bids[].price`    | string    | Bid price     |
| `bids[].quantity` | string    | Bid quantity  |
| `asks[].price`    | string    | Ask price     |
| `asks[].quantity` | string    | Ask quantity  |
| `timestamp`       | timestamp | Snapshot time |

---

### OTC Pair Listings

OTC pair listing availability updates.

**Topic:** `{pair}@otc-listings`
**Example:** `BTC/USD@otc-listings`
**Authentication:** Not required

#### Subscribe

```json
{
  "e": "tdx:subscribe",
  "t": "BTC/USD@otc-listings"
}
```

#### OTC Listing Update Event

```json
{
  "e": "otc_listing_update",
  "t": "BTC/USD@otc-listings",
  "d": {
    "pairId": "pair-123",
    "symbol": "BTC/USD",
    "live": true,
    "updatedAt": "2025-01-19T10:00:00Z"
  }
}
```

| Field       | Type      | Description                      |
| ----------- | --------- | -------------------------------- |
| `pairId`    | string    | Pair ID                          |
| `symbol`    | string    | Pair symbol                      |
| `live`      | boolean   | Whether OTC trading is available |
| `updatedAt` | timestamp | Last update time                 |

---

## RFQ (Request for Quote)

RFQ is the primary workflow for OTC trading. For complete documentation, see the [RFQ documentation](/prime/docs/api-doma-trad-rfq) in the trading domain.

**Topics:**

* `{subAccountId}@quotes` - Start quoting, receive streaming quotes
* `{subAccountId}@accept` - Accept a quote
* `{subAccountId}@stop` - Cancel an RFQ session

---

## Session Management

### Cancel on Disconnect

Enable automatic cancellation of all orders when the connection drops.

**Topic:** Not required
**Authentication:** Required

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

#### Response

```json
{
  "e": "tdx:cancel_on_disconnect_succeeded"
}
```

**Notes:**

* Only one cancel-on-disconnect session per client account is allowed
* If a second connection attempts to enable this, it will fail
* Orders are canceled when the WebSocket connection closes

---

## Unsubscribe

Unsubscribe from any topic.

```json
{
  "e": "tdx:unsubscribe",
  "t": "BTC/CHF@trades"
}
```

#### Response

```json
{
  "e": "tdx:unsubscription_succeeded",
  "t": "BTC/CHF@trades"
}
```

---

## Error Handling

All errors are returned with the `tdx:error` event:

```json
{
  "e": "tdx:error",
  "t": "invalid@topic",
  "d": {
    "message": "Invalid topic format"
  }
}
```

### Common Error Scenarios

| Error                   | Description                                       |
| ----------------------- | ------------------------------------------------- |
| Invalid topic format    | Topic doesn't match `{target}@{category}` pattern |
| Authentication required | Token missing for authenticated topic             |
| Permission denied       | User lacks access to sub-account                  |
| Rate limit exceeded     | Too many messages (anonymous: 1 per 500ms)        |
| Invalid event type      | Unknown event in `e` field                        |
| Order validation failed | Order parameters invalid                          |
| Subscription conflict   | Cancel-on-disconnect already active for account   |