> For the complete documentation index, see [llms.txt](https://docs.hello.trade/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hello.trade/developer-tools/websocket-api/account-summary.md).

# Account Summary Stream

The account summary stream pushes a fresh snapshot of your account — withdrawable balance, margin usage, and open positions — **whenever your position, margin, or balance state changes**: fills, trade busts, liquidations, funding payments, leverage changes, and deposit/withdraw settlements. The payload is the full account summary, identical in shape to the REST [`GET /api/account_summary`](/developer-tools/rest-api/public-endpoints.md) endpoint.

It does **not** push on working-order margin — placing, cancelling, or replacing an order, or reserving margin for a liquidation-auction claim — nor on mark-price ticks. Poll `GET /api/account_summary` when you need withdrawable/margin figures that reflect those. See [What triggers a push](#what-triggers-a-push) below.

This channel is **independent** of `subscribeTrading` — a connection can subscribe to account summaries without execution reports, or to both. A market maker will typically want **both**: `subscribeAccountSummary` for position snapshots and `subscribeTrading` for order/fill and account events.

***

## Subscribing

Send `subscribeAccountSummary` (requires an authenticated connection). The gateway replies with an immediate `accountSummary` snapshot, then pushes a fresh summary on every subsequent change.

**Request:**

```json
{
  "type": "subscribeAccountSummary"
}
```

The first `accountSummary` message is the initial snapshot; there is no separate success acknowledgement.

To stop receiving updates:

```json
{
  "type": "unsubscribeAccountSummary"
}
```

***

## Account Summary Message

The summary is **combined**: the wallet's cross and isolated margin in one payload, positions tagged with `marginMode`.

```json
{
  "type": "accountSummary",
  "assetPositions": [
    {
      "instrument": "NVDA",
      "marginMode": "Cross",
      "entryPx": "500.00",
      "leverage": 10,
      "liquidationPx": "450.00",
      "marginUsed": "100.00",
      "maxLeverage": 20,
      "positionValue": "1000.00",
      "returnOnEquity": "0.05",
      "szi": "2",
      "unrealizedPnl": "50.00"
    },
    {
      "instrument": "BTC",
      "marginMode": "Isolated",
      "entryPx": "65000.00",
      "leverage": 10,
      "liquidationPx": "59240.50",
      "marginUsed": "650.00",
      "maxLeverage": 40,
      "positionValue": "6500.00",
      "returnOnEquity": "0",
      "szi": "0.1",
      "unrealizedPnl": "0",
      "transferable": "0.00"
    }
  ],
  "crossMaintenanceMarginUsed": "25.00",
  "crossMarginSummary": {
    "accountValue": "10000.00",
    "totalMarginUsed": "100.00",
    "totalNtlPos": "1000.00",
    "totalRawUsd": "9950.00"
  },
  "maintenanceMarginUsed": "106.25",
  "marginSummary": {
    "accountValue": "10650.00",
    "totalMarginUsed": "750.00",
    "totalNtlPos": "7500.00",
    "totalRawUsd": "10600.00"
  },
  "time": 1705600000000,
  "withdrawable": "9900.00"
}
```

The payload is identical to the REST `GET /api/account_summary` response with a `"type": "accountSummary"` discriminator added. See [Account Summary (REST)](/developer-tools/rest-api/public-endpoints.md#get-apiaccount_summary) for the complete field reference.

| Field                        | Type   | Description                                |
| ---------------------------- | ------ | ------------------------------------------ |
| `type`                       | string | Always `"accountSummary"`                  |
| `assetPositions`             | Array  | Cross and isolated positions               |
| `crossMaintenanceMarginUsed` | string | Maintenance margin used (cross only)       |
| `crossMarginSummary`         | Object | Margin summary (cross only)                |
| `maintenanceMarginUsed`      | string | Maintenance margin used (cross + isolated) |
| `marginSummary`              | Object | Combined margin summary (cross + isolated) |
| `time`                       | i64    | Snapshot timestamp (milliseconds)          |
| `withdrawable`               | string | Cross collateral available for withdrawal  |

***

## What triggers a push

A push is emitted whenever your position, margin, or balance state changes:

* **Fills** — a position opened, increased, reduced, closed, or flipped.
* **Trade busts** — a previously reported fill reversed.
* **Liquidations** — manual-liquidation and ADL executions.
* **Funding payments** — settled funding changes your balance (and therefore `liquidationPx` / `withdrawable`).
* **Leverage changes** — a successful leverage update changes the position's `leverage`, `marginUsed`, and `liquidationPx`.
* **Deposit / withdraw settlements** — a settled collateral change moves your balance (and `liquidationPx` / `withdrawable`).
* **Margin transfers** — a settled cross ↔ isolated transfer reallocates your collateral (combined totals unchanged; cross figures and `withdrawable` shift).

The following do **not** trigger a push:

* **Order placement, cancel, and replace** — reserving/releasing working-order margin changes `withdrawable`, but not your position or realized balance. Order events arrive on the [Execution Reports](/developer-tools/websocket-api/execution-reports.md) stream; poll `GET /api/account_summary` for the resulting `withdrawable`.
* **Liquidation-auction claim reservations** — reserved claim margin, likewise pollable.
* **Mark-price ticks** — fields derived from the mark price (`unrealizedPnl`, `withdrawable`, `transferable`, `liquidationPx`, `returnOnEquity`, `accountValue`) reflect the mark price at the moment of the last push and are **not** refreshed when the mark price alone moves. Recompute these locally from your own price feed and current positions if you need them between events.

***

## Delivery

* **Snapshot on subscribe**, then a push on each position / margin / balance change.
* **Coalesced**: multiple changes within a short window batch into a single push carrying the net resulting state, rather than one message per event.
* Each message is a **complete snapshot** (not a delta). **Always treat the message with the largest `time` as the current state** — do not assume arrival order. In particular, a change that occurs while you are subscribing can produce a push that arrives *around or before* the initial snapshot; keying on `time` (last-write-wins) resolves this correctly since every message carries the full account state as of its `time`.
* Per-order acknowledgements, fills, and account events arrive separately and immediately on the [Execution Reports](/developer-tools/websocket-api/execution-reports.md) stream (`subscribeTrading`); the account summary stream is the aggregate position/margin view.

***
