# WebSocket API Overview

Use `/ws` to receive strategy signals, completed live fills, strategy position snapshots,
and broker-account orders, positions, balances and settings. Historical queries remain
available through REST.

## Authorization

Pass the API key in `Authorization: Bearer YOUR_API_KEY` during the HTTP upgrade.
Missing or invalid authentication returns HTTP 401 before the upgrade. Changes to API-key
or account access can end a connection or remove a subscription.

## Channels

| Channel | Payload | Delivery and recovery |
|  --- | --- | --- |
| `strategy.signal` | One order/signal object | Ordered stream with `seq_id` and bounded replay |
| `strategy.live_fills` | One `StrategyFillDTO` object | Completed live fills, with a separate cursor and bounded replay |
| `strategy.positions` | Array of positions | Full replacement snapshot initially and when changed. No replay |
| [`account.orders`](/guides/websocket-subscribe#account-orders) | Array of `OrderStatusDTO` rows | Initial working-order snapshot, then changed rows. Default refresh: 1 second |
| [`account.positions`](/guides/websocket-subscribe#account-positions) | Array of `PositionDTO` rows | Initial snapshot, then changed rows and zero-quantity closures. Default refresh: 1 second |
| [`account.balance`](/guides/websocket-subscribe#account-balance) | `AccountBalanceDTO` object | Initial object, then the complete selected object on change. Default refresh: 60 seconds |
| [`account.state`](/guides/websocket-subscribe#account-state) | `AccountStateDTO` object with `strategies` | Initial object, then the complete selected object on change. Default refresh: 60 seconds |


Refresh intervals are configurable and do not promise a message every interval.
Unchanged selected data produces no update. Several changes can collapse into one
observation. An initial snapshot can be empty and is still a successful subscription.
Account channels have no `seq_id` replay or `resume_from` support; reconnect and resubscribe
for fresh snapshots.

On the same connection and account/broker pair, live subscriptions to both account orders
and positions receive the observed partial or final fill order update before its resulting
position update. Position-only subscriptions do not require an order subscription.
Intermediate partial fills may not appear between updates. Initial snapshots are baselines rather than
historical fill events. There is no ordering guarantee across separate sockets.

See [Subscribing](/guides/websocket-subscribe) for JSON examples and complete-row client handling,
and [Recovery](/guides/websocket-gap-fill) for the different recovery rules.

## Limits

Defaults are configurable per deployment. Strategy subscriptions retain their independent
100-per-connection limit. Account subscriptions have a separate default limit of 2,000 per
connection, including pending subscriptions. A channel/account/broker combination counts as
one account subscription. Four channels for one account count as four. The default connection
limit is 10 per API key.

## Message Envelope

Envelope names are explicit, and DTO payloads use their WebSocket names: generally camelCase,
with explicit names such as `strategy_id` on `StrategyFillDTO`. Null values are usually omitted.
See [Balance Fields](/guides/websocket-subscribe#balance-fields) for fields that remain present as
`null` when unavailable. REST schema casing does not determine WebSocket payload casing.

| Field | Type | Meaning |
|  --- | --- | --- |
| `msg_type` | string | Message/channel type |
| `id` | string | Unique server message ID for logging and deduplication. Ignored in client requests |
| `seq_id` | integer | Cursor on replayable strategy signal/fill streams. Absent on account messages |
| `request_id` | string | Optional client correlation ID, at most 50 characters. Echoed on acknowledgements and correlated errors |
| `timestamp` | string | UTC ISO 8601 timestamp. Client timestamps must be within one minute of UTC |
| `v` | integer | Protocol version, currently `4` |
| `account` | string | Exact account name on account data messages |
| `broker_id` | integer | Broker routing identifier on account data messages |
| `is_snapshot` | boolean | `true` for an initial account baseline, `false` for a later account update |
| `payload` | object or array | Message-specific data. Absent for messages such as heartbeats |


`account`, `broker_id` and `is_snapshot` are absent from existing strategy/control messages.
Subscription account fields are inside `payload`; account data also carries routing fields
in the envelope. Array payloads are valid, including `[]`.

Clients may send only `subscription.request` and `heartbeat.ack`. Other message types are
server-only. See [Connecting](/guides/websocket-connect) for a persistent multi-channel client,
heartbeat handling and negotiated compression.