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

# Subscriptions

> Real-time WebSocket channels: subscribe to a list of channel names and receive server-pushed notification frames.

Subscriptions deliver real-time updates over WebSocket. You call `subscribe` with a
list of channel names, and the server streams an update frame each time the
underlying data changes.

<Note>
  Subscriptions are **WebSocket-only**. The `subscribe` / `unsubscribe` methods
  and the notification frames they produce are not available over HTTP POST. See
  [Endpoints](/getting-started/introduction#endpoints) for the WebSocket endpoints.
</Note>

## Notification model

A subscription update is a JSON-RPC-style **notification frame**: it has a `method` of
`"subscription"` and **no `id`** (it is server-pushed, not a reply to any request). The
payload carries the `channel` that produced it and the `data`:

```json theme={null}
{
  "method": "subscription",
  "params": {
    "channel": "trades.ETH-PERP",
    "data": {}
  }
}
```

The shape of `data` depends on the channel. For the exact per-channel payload schema,
see the generated **Subscriptions reference** under the API Reference tab.

## Subscribing

Send a `subscribe` request with a `channels` array. The response reports a per-channel
`status` and the connection's full `current_subscriptions` set.

<CodeGroup>
  ```typescript TypeScript (SDK) theme={null}
  import { channel, DeriveClient } from '@derivexyz/derive-ts';

  const client = new DeriveClient({ network: 'mainnet' });
  // Subscriptions live on the websocket; connect() must come first.
  await client.connect();

  // channel() builds the concrete channel name from its template and
  // carries the payload type, so each handler below is fully typed.
  const trades = channel('trades.{instrument_name}', {
  instrument_name: 'ETH-PERP',
  });
  const book = channel('orderbook.{instrument_name}.{group}.{depth}', {
  instrument_name: 'ETH-PERP',
  group: '10',
  depth: '20',
  });

  const tradesSub = await client.subscriptions.subscribe(trades, (batch) => {
  for (const trade of batch) {
  console.log(
  `trade: ${trade.direction} ${trade.trade_amount} @ ${trade.trade_price}`
  );
  }
  });

  const bookSub = await client.subscriptions.subscribe(book, (snapshot) => {
  console.log(
  `book #${snapshot.publish_id}: ${snapshot.bids.length} bids / ${snapshot.asks.length} asks`
  );
  });

  // Later, drop the subscriptions (the last handler on a channel sends unsubscribe):
  await tradesSub.unsubscribe();
  await bookSub.unsubscribe();

  ```

  ```python Python (SDK) theme={null}
  # Coming soon.
  ```

  ```rust Rust (SDK) theme={null}
  // Coming soon.
  ```

  ```json Request theme={null}
  {
    "id": 1,
    "method": "subscribe",
    "params": {
      "channels": ["trades.ETH-PERP", "orderbook.ETH-PERP.10.20"]
    }
  }
  ```

  ```json Response theme={null}
  {
    "id": 1,
    "result": {
      "status": {
        "trades.ETH-PERP": "ok",
        "orderbook.ETH-PERP.10.20": "ok"
      },
      "current_subscriptions": ["trades.ETH-PERP", "orderbook.ETH-PERP.10.20"]
    }
  }
  ```
</CodeGroup>

Each `status` entry is `"ok"`, `"already subscribed"`, or an error string for that
channel. If **every** requested channel is invalid, the whole call fails with
[error code 13000 — Invalid channels](/error-codes).

Private channels require an authenticated connection whose session key is authorized
for the target subaccount. See [Authentication](/authentication/session-login) for session login.

## Unsubscribing

Send `unsubscribe` with a `channels` array to drop specific channels. Omit `channels`
(or pass `null`) to unsubscribe from **all** channels on the connection. The response
returns the per-channel `status` and the `remaining_subscriptions` set.

```json theme={null}
{
  "id": 2,
  "method": "unsubscribe",
  "params": { "channels": ["trades.ETH-PERP"] }
}
```

## Channel-name template glossary

Channel names are dot-delimited. Segments in `{braces}` are parameters you fill in.

| Parameter           | Meaning                                     | Values                                                                                                    |
| ------------------- | ------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| `{instrument_name}` | An instrument identifier (e.g. `ETH-PERP`)  | See [Instrument names](/trading/instrument-names)                                                         |
| `{instrument_type}` | Instrument class                            | `erc20`, `option`, `perp`                                                                                 |
| `{currency}`        | Settlement/collateral currency (e.g. `ETH`) | See [`public/get_all_currencies`](/trading/managers-and-risk-universes#reading-public-get-all-currencies) |
| `{group}`           | Orderbook price grouping                    | `1`, `10`, `100`                                                                                          |
| `{depth}`           | Orderbook levels per side                   | `1`, `10`, `20`, `100`                                                                                    |
| `{interval}`        | Slim-ticker publish interval (ms)           | `100`, `1000`                                                                                             |
| `{tx_status}`       | Settlement status filter                    | `settled`, `reverted`, `timed_out`                                                                        |
| `{subaccount_id}`   | Numeric subaccount id                       | Your authenticated subaccount                                                                             |
| `{wallet}`          | Wallet address                              | Your authenticated wallet                                                                                 |

<Note>
  The legacy `ticker.{instrument_name}.{interval}` channel is deprecated —
  subscribing to it is rejected. Use `ticker_slim.*` instead.
</Note>

## Public channels

No authentication required.

| Channel                              | Address template                                  |
| ------------------------------------ | ------------------------------------------------- |
| Orderbook                            | `orderbook.{instrument_name}.{group}.{depth}`     |
| Slim ticker                          | `ticker_slim.{instrument_name}.{interval}`        |
| Spot feed                            | `spot_feed.{currency}`                            |
| Trades (by instrument)               | `trades.{instrument_name}`                        |
| Trades (by type + currency)          | `trades.{instrument_type}.{currency}`             |
| Trades (by type + currency + status) | `trades.{instrument_type}.{currency}.{tx_status}` |
| Auctions                             | `auctions.watch`                                  |
| Margin                               | `margin.watch`                                    |

<Warning>
  `margin.watch` is an all-users firehose of margin and mark-to-market state. It
  is intended for administrative/monitoring use, not per-account data.
</Warning>

### Slim ticker payload

Both the `ticker_slim.*` channel and `public/get_ticker` return the same compact snapshot, keyed by single
letters to keep the feed small:

| Key              | Meaning                                                                         |
| ---------------- | ------------------------------------------------------------------------------- |
| `t`              | Snapshot timestamp (ms since epoch)                                             |
| `a` / `A`        | Best ask price / amount available at the best ask                               |
| `b` / `B`        | Best bid price / amount available at the best bid                               |
| `M`              | Mark price                                                                      |
| `I`              | Index price                                                                     |
| `f`              | Current hourly funding rate (perps; `null` otherwise)                           |
| `minp` / `maxp`  | Min / max matchable price (the order price band)                                |
| `stats`          | 24h trading statistics (`c` change, `v` volume, `oi` open interest, …)          |
| `option_pricing` | Greeks and implied vols for options (`d` delta, `g` gamma, `v` vega, `i` IV, …) |

The `public/get_ticker` response schema in the **API Reference** tab carries every field's full
description.

## Private channels

Require an [authenticated](/authentication/session-login) connection. `{subaccount_id}` channels
stream data for one of your subaccounts; `{wallet}` channels stream data for your wallet.

| Channel                   | Address template                     |
| ------------------------- | ------------------------------------ |
| Balance updates           | `{subaccount_id}.balances`           |
| Order updates             | `{subaccount_id}.orders`             |
| Trade updates             | `{subaccount_id}.trades`             |
| Trade updates (by status) | `{subaccount_id}.trades.{tx_status}` |
| Quote updates             | `{subaccount_id}.quotes`             |
| Best-quote updates        | `{subaccount_id}.best.quotes`        |
| RFQ updates               | `{wallet}.rfqs`                      |

<Tip>
  The **Subscriptions reference** in the API Reference tab is generated from the
  AsyncAPI spec and documents the exact `data` payload for every channel above.
</Tip>


## Related topics

- [Error Codes](/error-codes.md)
- [RFQ Trading](/trading/rfq.md)
- [Connecting over WebSocket](/connecting.md)
