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

# Stream protocol

> The market-maker WebSocket: channels, frames and limits.

```
wss://api.zeustrade.io/mm/stream?key=<key>
```

Send the key as `?key=` or in `x-api-key` where your client can set headers. A wrong key gets 401 on the upgrade and a sixth connection of one key gets 429.

## Client frames

```json theme={null}
{ "op": "subscribe", "channel": "fills", "accounts": ["0x…"] }
{ "op": "subscribe", "channel": "prices", "symbols": ["BTC", "ETH"] }
{ "op": "subscribe", "channel": "exposure" }
{ "op": "unsubscribe", "channel": "keeper" }
```

A new subscribe to a channel replaces the previous one.

## Server frames

Every frame is `{ "channel": "...", "data": ..., "ts": <ms> }`.

| Channel | Data |
| - | - |
| `subscribed`, `unsubscribed` | The subscription |
| `fills` | One fill: account, request key, status, market, side, size, fill price, fees, keeper transaction, time gap, block |
| `exposure` | `/mm/exposure` merged with `/mm/hedge-recommendation`, on subscribe and every 5 seconds |
| `keeper` | `{ medianMs, p95Ms, queueLength }`, on subscribe and every 5 seconds |
| `prices` | `[{ symbol, price, publishTime }]`, publish time in Unix seconds |
| `error` | `{ code, message }` with `BAD_REQUEST`, `TOO_MANY_ACCOUNTS`, `PRICES_DISABLED` or `SOURCE_UNAVAILABLE` |

## Limits

* 5 connections per key and 200 accounts per `fills` subscription.
* The server pings every 15 seconds and closes a connection that misses two pings.
* A connection with more than 1 MB unsent stops receiving everything except `fills` until it catches up.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.