> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tplus.cx/llms.txt
> Use this file to discover all available pages before exploring further.

# WebSocket streams

> Stream catalog, protocol versions, and resync rules.

## Connecting

Each stream is a separate WebSocket connection at its own path; there is no subscribe/unsubscribe message protocol. Authenticated Trading API streams use the same identity as REST ([details](/api-reference/overview#authentication)): use `Authorization: Bearer <token>` and `User-Id` headers when your client can set them. Browser clients can pass `Bearer-<token>, User-<id>` as `Sec-WebSocket-Protocol` values.

Trading API streams support two message protocols:

* **v0** (default): raw JSON payloads.
* **v1**: include `tplus.ws.v1` in `Sec-WebSocket-Protocol`. Messages arrive in envelopes:

```json theme={null}
{
  "type": "event",
  "channel": "orders",
  "request_id": null,
  "timestamp_ns": null,
  "data": { "...": "..." },
  "error": null
}
```

On **v0** the payload is the bare event object, with no envelope. A trade-events (`/trades/user/events/{user_id}`) message, for example:

```json theme={null}
{
  "asset_id": "200",
  "trade_id": 84213,
  "order_id": "my-order-1",
  "price": "1000.5",
  "quantity": "5",
  "timestamp_ns": 1760000000000000000,
  "is_maker": true,
  "is_buyer": false,
  "status": "Confirmed",
  "rollback_reason": null,
  "is_liquidation": false,
  "sub_account": 1,
  "trading_fee": "0.25"
}
```

That same object is the `data` field under v1.

For authenticated browser clients, `Bearer-<token>`, `User-<id>`, and `tplus.ws.v1` can appear in the `Sec-WebSocket-Protocol` list. The Trading API auth parser reads the bearer token and user from any position in the list, and enables v1 if `tplus.ws.v1` is present. When auth succeeds through that header, the server echoes the first offered value as the selected subprotocol; put `tplus.ws.v1` first when you want the browser connection to report v1 as selected.

Market Data API streams currently use raw v0 frames only: a `WsWelcome` text frame first, then raw payloads. Do not expect v1 envelopes from those services.

After the welcome frame, the listed OMS and MDS streams run through a shared WebSocket stream loop. That loop sends a WebSocket ping every 20 seconds and responds to WebSocket ping frames with pong frames. For one-way stream connections, a text message `{"type":"ping"}` can receive `{"type":"pong"}`. Do not use that text message as the `/control` heartbeat: `/control` parses text frames as order commands, and invalid v1 command envelopes can be rejected before app-level ping handling.

The service code does not define an application-level idle timeout or a per-user/global WebSocket connection cap. Any idle close or connection cap is enforced outside the service, such as at a reverse proxy or load balancer.

## Trading API streams (authenticated)

| Stream                   | Path                                | Content                                                                                                |
| ------------------------ | ----------------------------------- | ------------------------------------------------------------------------------------------------------ |
| Orders                   | `GET /orders`                       | Created / replaced / triggered / canceled / removed events, server-initiated auto-reductions, failures |
| Trade events             | `GET /trades/user/events/{user_id}` | Pending, confirmed, and rolled-back fills with maker/taker flags and rollback reasons                  |
| Positions                | `GET /positions/ws/{user_id}`       | Position updates triggered by clearing-engine inventory changes (fills, deposits, transfers)           |
| Account stats            | `GET /account/stats/{user_id}`      | Account stats updates                                                                                  |
| Account activity         | `GET /account/events/{user_id}`     | Deposits landed, withdrawals completed, position clears, sub-account transfers                         |
| Order control            | `GET /control`                      | Bi-directional channel for order operations                                                            |
| Liquidation risk         | `GET /liquidation/at_risk/ws`       | Global aggregate broadcast of per-asset at-risk quantities and estimated liquidation prices            |
| Pending sync settlements | `GET /sync/pending_settlements`     | Market-maker stream of pending sync-book settlements                                                   |

Settler approval delivery uses a dedicated WebSocket outside the Trading API surface (`/settlement/approvals/{settler_pubkey}`, encrypted to the settler's key); see [Settlement](/funds/settlement#integrator-details).

## Market Data API streams (public)

| Stream        | Path                                    | Content                                                                                    |
| ------------- | --------------------------------------- | ------------------------------------------------------------------------------------------ |
| Market depth  | `GET /marketdepth/diff/{asset_id}`      | Sequence-numbered diffs; fetch `GET /marketdepth/{asset_id}` first, then apply diffs       |
| Klines        | `GET /klines/diff/{asset_id}`           | Candlestick updates for one market                                                         |
| Public trades | `GET /trades`, `GET /trades/{asset_id}` | `WsWelcome` first, then finalized public `Trade` payloads across all markets or one market |
| Ticker        | `GET /ticker/ws/{asset_id}`             | 24h ticker updates for one market, batched into at most one message per second             |
| All tickers   | `GET /tickers/ws`                       | 24h ticker updates for all markets                                                         |

Indicative funding and borrow rates also stream publicly from the interest engine's `/rates` endpoint, a separate service from the two documented APIs; see [Fees & rates](/trading/fees-and-rates#rate-data).

Message schemas are in the live [Trading API](https://oms.tplus.cx/api-reference) and [Market Data API](https://mds.tplus.cx/api-reference) references.

## Lag and resync

Trading API streams close with code `1013` and reason `resync_required` when the client falls behind. On v1, the server sends a `RESYNC_REQUIRED` error before closing. Market Data API streams do not support v1 envelopes; if their broadcast receiver lags, the raw stream handler terminates the connection without a resync message.

| Stream                   | Resync rule                                                                                                                                                                                                                                                       |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Orders                   | Reconnect, then re-fetch `GET /orders/user/{user_id}` and optionally `GET /orders/user/{user_id}/{asset_id}` before consuming new events.                                                                                                                         |
| Trade events             | Reconnect, then re-fetch `GET /trades/user/{user_id}` and optionally `GET /trades/user/{user_id}/{asset_id}`.                                                                                                                                                     |
| Positions                | Reconnect, then re-fetch `GET /positions/{user_id}` or `GET /positions/{user_id}/{asset_id}`.                                                                                                                                                                     |
| Account stats            | Reconnect, then re-fetch the account state you use for decisions, usually margin and inventory via `GET /margin/user/{user_id}` and `GET /inventory/user/{user_id}`.                                                                                              |
| Account activity         | Reconnect, then reconcile against the relevant account state endpoints for the workflow: inventory, positions, withdrawals, settlement signatures, or margin.                                                                                                     |
| Order control            | Treat the control connection as a command channel. After reconnect, use REST order and trade snapshots to decide whether each in-flight request was accepted, filled, canceled, or needs a new signed request.                                                    |
| Liquidation risk         | Reconnect, then re-fetch current margin and position state if you need a local risk view. The stream itself is a global aggregate broadcast, not filtered to the authenticated user.                                                                              |
| Pending sync settlements | Reconnect promptly and resume listening. Missed events are recoverable only while they remain in the stream's 256-deep broadcast buffer; there is no REST snapshot or replay route for this stream.                                                               |
| Market depth             | Fetch `GET /marketdepth/{asset_id}` first, then apply `GET /marketdepth/diff/{asset_id}` updates. A reconnect or `sequence_number` gap invalidates the local book; re-fetch the snapshot and resume from fresh diffs.                                             |
| Klines                   | Reconnect, re-fetch `GET /klines/{asset_id}` for the window you display, then consume `GET /klines/diff/{asset_id}` updates.                                                                                                                                      |
| Public trades            | Reconnect, then re-fetch `GET /trades` or `GET /trades/{asset_id}`. Use pagination to inspect cached history for the disconnected interval before processing live trades; the MDS REST cache is finite, so long gaps may not be fully recoverable from MDS alone. |
| Ticker                   | Reconnect, re-fetch `GET /ticker/{asset_id}`, then consume `GET /ticker/ws/{asset_id}` updates.                                                                                                                                                                   |
| All tickers              | Reconnect, re-fetch `GET /tickers`, then consume `GET /tickers/ws` updates.                                                                                                                                                                                       |
