# Account Channel


Source: https://docs.stxapp.io/websockets/channels/account/

Topic: `account:{user_id}`

Everything the five per-type channels carry, on one join. The events and payloads
are byte-identical to theirs; this is a subscription convenience, not a different
feed.

```
["1","1","account:<user_id>","phx_join",{}]
```

## What arrives

On join you receive four snapshots:

| Event | Payload | Documented at |
| --- | --- | --- |
| `all_orders` | `{"orders": [...]}` | [Orders](/websockets/channels/orders/) |
| `all_trades` | `{"trades": [...]}` | [Fills](/websockets/channels/fills/) |
| `all_positions` | `{"positions": [...]}` | [Positions](/websockets/channels/positions/) |
| `balances` | the balances object | [Balances](/websockets/channels/balances/) |

There is no settlements snapshot, because
[`settlements`](/websockets/channels/settlements/) does not send one either.

After that, changes arrive under the same event names the per-type channels use, so
nothing needs re-tagging if you migrate to this topic:

| Event | Carries |
| --- | --- |
| `new_open_order` | one order |
| `trade` | one of your executions |
| `updated_positions` | changed positions |
| `new_settlements` | new settlements |
| `update` | the balances object |
| `payment_update` | a payment status change |

`account:` does not accept an `account_id`; it serves the account the socket
resolved at connect. To reach a second account you own, join
[`balances`](/websockets/channels/balances/#naming-an-account) separately for it.

## Filtering by market

It takes the same optional `market_ids` filter as the per-type channels (see
[filtering](/websockets/channels/wire-format/#filtering)), with one deliberate difference:
**balance frames are never filtered out.** `balances`, `update` and `payment_update`
describe the account, not a market, so a `market_ids` filter has nothing to match
them against and lets them through.

```
["1","1","account:<user_id>","phx_join",{"market_ids":["<uuid>"]}]
["1","2","account:<user_id>","select_market_ids",{"market_ids":null}]
```

The filter distinguishes a snapshot from a delta. On join you receive `all_orders`
even when the filter leaves it empty: `[]` tells you there is nothing in those
markets, which is worth knowing. Afterwards, an update the filter empties is simply
not sent, rather than arriving as an empty list.

## Keeping it alive

```
["1","3","account:<user_id>","ping",{}]
```

The `ping` refreshes the session behind the channel. Without it the inactivity timer
reaps that session and every fanned-in feed silently stops, so send it on a timer
even though this topic arms no cancellation.

## Use Cases

| Use case | Message to send |
| --- | --- |
| Join and receive your whole account | `["3","3","account:<user_id>","phx_join",{}]` |
| Join filtered to two markets | `["3","3","account:<user_id>","phx_join",{"market_ids":["<uuid>","<uuid>"]}]` |
| Change the market filter without rejoining | `["3","4","account:<user_id>","select_market_ids",{"market_ids":null}]` |
| Keep the session alive | `["3","5","account:<user_id>","ping",{}]` |

:::caution[Do not also join a per-type channel]
A socket joined to both `account:` and, say, `orders:` receives every order twice.
Pick one.
:::

:::danger[No cancel-on-disconnect]
`account:` does not support `cancel_on_disconnect`. Its `ping` keeps the session
alive but arms no cancellation, so if you rely on resting orders being pulled when
your socket drops, use [`orders`](/websockets/channels/orders/) and the per-type channels
instead, for everything, not alongside `account:`. See
[Risk controls](/risk-controls/) for the join payload and its `ping` contract.
:::

## Choosing between them

`account:` if you want everything on one join; the per-type channels if you want a
subset without a filter, or if you need `cancel_on_disconnect`.
