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

# WebSocket User Account

> Subscribe to userAccount for a full account snapshot every few seconds — equity, collateral, positions, and margin availability without polling the REST API.

The `userAccount` channel pushes the **complete account view** for one account within one market deployer — collateral, positions, and margin — on a timer. The payload is identical to the REST [`userAccount`](/info/user-account) response. A first frame arrives immediately on subscribe, then a fresh frame **every 3 seconds**.

Use it to keep equity, available margin, position size, and unrealized PnL current without polling.

## Subscribing

```json theme={null}
{
  "method": "subscribe",
  "subscription": {"type": "userAccount", "user": "0xabc...123", "marketDeployerId": 1}
}
```

<ParamField body="user" type="string" required>
  The account's wallet address, not the numeric account ID. The server resolves it to an account; an unregistered address receives no frames.
</ParamField>

<ParamField body="marketDeployerId" type="integer" required>
  The market deployer to report on. The account view differs per deployer, so subscribe once per deployer you care about. This carries the same meaning as `marketDeployerId` in the REST query.
</ParamField>

Unsubscribe with the same `subscription` object and `"method": "unsubscribe"`.

## Push message format

```json theme={null}
{
  "msg": "UserAccount",
  "channel": "userAccount.0xabc...123",
  "data": {
    "type": "userAccount",
    "accountId": "1",
    "marketDeployerId": 1,
    "crossEquity": "1000000000000",
    "marginAvailable": "1000000000000",
    "totalPositionIM": "643246",
    "crossPositionMM": "0",
    "crossCollaterals": [{"coinId": 1, "amount": "1000000000000"}],
    "positions": [
      {"contractId": 1, "size": "5", "leverage": "10", "unrealizedPnl": "0", "mm": "0"}
    ]
  },
  "ts": 1782279307885
}
```

The sample above is abbreviated. `data` carries the full REST response body.

## Field reference

<ResponseField name="msg" type="string">
  Always `"UserAccount"` for this channel.
</ResponseField>

<ResponseField name="channel" type="string">
  The channel this frame belongs to, keyed by the subscribed address.
</ResponseField>

<ResponseField name="data" type="object">
  The account view. Every margin, collateral, position, and account-level field is defined exactly as in the REST [`userAccount`](/info/user-account) response — see that page for the complete field reference.
</ResponseField>

<ResponseField name="ts" type="int64">
  Frame send time in Unix milliseconds, from the server clock.
</ResponseField>

## Maintaining local state

<Steps>
  <Step title="Subscribe and take the first frame">
    The first frame arrives immediately and is a complete snapshot. Use it as your starting state.
  </Step>

  <Step title="Replace state on every frame">
    Each frame is a **full snapshot, not a delta**. Overwrite your local account state wholesale — there are no patches to apply.
  </Step>

  <Step title="Convert raw values for display">
    Prices and quantities are raw integers. Convert with the contract's `priceScale` and `qtyScale` from [`configs`](/info/configs).
  </Step>
</Steps>

<Note>
  `positions[].unrealizedPnl` is computed against the mark price and is recalculated on every frame, so it moves even when your position does not.
</Note>
