# Market channel

`/ws/market` streams the live book and tape. Use
[REST market data](https://docs.troncharts.xyz/docs/trading/market-data/) for the initial snapshot, then
keep it current here. Market data is public: no `Authenticate` frame is
required on this channel.

## What it carries

Six independent streams, each with its own subscribe verb and its own set of
venues. A stream only accepts venues it can actually serve — asking for one it
cannot is rejected as `invalid_frame` rather than accepted and left silent.

| Stream | Subscribe with | Pushes | Venues |
| --- | --- | --- | --- |
| Depth (aggregated levels) | `Subscribe-Depth` | `Depth-Update` | `hyperliquid`, `aster`, `lighter`, `polymarket`, `kalshi`, `massive`, `b3` |
| Order book (per order, L3) | `Subscribe-Depth-L3` | `Order-Book-Update` | `lighter`, `b3` |
| Tape (trade prints) | `Subscribe-Tape` | `Tape-Update` | `hyperliquid`, `aster`, `massive`, `b3` |
| Volume at price | `Subscribe-VAP` | `VAP-Update` | `hyperliquid`, `aster`, `massive`, `b3` |
| Inside quote | `Subscribe-BBO` | `BBO-Update` | `hyperliquid`, `aster`, `lighter`, `polymarket`, `massive`, `b3` |
| Candles | `Subscribe-Candles` | `Candle-Update` | `hyperliquid`, `aster`, `lighter`, `polymarket`, `kalshi`, `massive`, `b3` |

`massive` is the venue key for listed futures; the same key is what
`GET /api/v1/symbols/{venue}` enumerates them under.

Each has a matching `Unsubscribe-*`; `Unsubscribe-All` drops the lot. `Ping`
answers `Pong`, and every subscribe frame answers `Result`.

`venue` and `symbol` are **separate fields** — there is no `venue:symbol`
string on the wire:

```json
{ "type": "Subscribe-Depth", "venue": "hyperliquid", "symbol": "BTC" }
```

`Subscribe-Candles` and `Unsubscribe-Candles` additionally require `interval`,
written as a count plus a unit — `s`, `m`, `h`, `d`, `w`, or `M` (`1m`, `15m`,
`4h`, `1d`, `1w`). Custom resolutions are accepted and folded server-side from
a finer base interval where the venue has no native bar. Each interval is its
own subscription: unsubscribing `5m` leaves `1h` running.

Prices and sizes arrive as decimal strings, and every frame echoes `venue` and
`symbol` so one socket can multiplex the whole set.

## Batching

High-rate venues can print far faster than any UI can render. The tape is
**batched server-side into one frame per flush window**: a single `Tape-Update`
carries a `trades` array holding every print that landed in the window, in wire
order. Iterate it; do not assume one frame equals one trade.

This matters most on futures venues, where an active session can produce
hundreds of prints per second on one symbol.

## Encoding

Like the other channels, `?encoding=msgpack` on the upgrade URL switches
server→client frames to MessagePack. On a busy depth subscription this is the
single cheapest performance win available to a client.

## Seeding correctly

1. Subscribe first.
2. Then fetch the REST snapshot.
3. Apply buffered updates on top.

Doing it the other way round leaves a hole between the snapshot and your first
frame.