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

# Unrealized PnL

> Subscribe to Unrealized PnL leaderboard invalidation hints and read the unrealizedPnlProjectionChanged payload

This page covers subscribing to Unrealized PnL leaderboard invalidation hints with `subscribe_unrealized_pnl`, and the `unrealizedPnlProjectionChanged` payload that subscription delivers.

## Subscribing to unrealized PnL updates

Subscribe to invalidation hints for the [live Unrealized PnL leaderboards](/api-reference/leaderboard/unrealized-pnl-market) by emitting `subscribe_unrealized_pnl`. No authentication required. Two scopes are available: one leaderboard per open market, and a global biggest-open-positions list.

<Warning>
  This event carries only a hint, not the leaderboard payload. When it arrives, refetch the corresponding REST route — [`GET /leaderboard/pnl/unrealized/markets/{marketId}`](/api-reference/leaderboard/unrealized-pnl-market) or [`GET /leaderboard/pnl/unrealized/biggest-positions`](/api-reference/leaderboard/biggest-positions) — which remains the serving contract.
</Warning>

```typescript theme={null}
// Follow the leaderboard for one market
socket.emit('subscribe_unrealized_pnl', { schemaVersion: 1, scope: 'MARKET', marketId: 7348 });

// Follow the global biggest open positions
socket.emit('subscribe_unrealized_pnl', { schemaVersion: 1, scope: 'BIGGEST_POSITIONS' });

socket.on('unrealizedPnlProjectionChanged', (msg) => {
  // Refetch the matching REST route for `msg.scope` (and `msg.marketId` when scope === 'MARKET').
});
```

To unsubscribe, emit `unsubscribe_unrealized_pnl` with the same payload shape.

<Note>
  **At most 50 `MARKET` scopes per connection.** Additional `subscribe_unrealized_pnl` calls with new `marketId`s beyond the limit are rejected with an `error` frame carrying `code: "UNREALIZED_PNL_SCOPE_LIMIT"`. The `BIGGEST_POSITIONS` scope does not count against the market limit.
</Note>

<Note>
  **`state` on the hint tracks the projection.** `state: "READY"` means the leaderboard you refetch will be current; `BUILDING`, `STALE`, or `DEGRADED` mean the REST route may return an empty or stale snapshot. Retry shortly.
</Note>

## Event payload

### `unrealizedPnlProjectionChanged`

Invalidation hint delivered to `subscribe_unrealized_pnl` subscribers when the underlying projection for their scope changes. It does **not** carry the leaderboard rows. Refetch the matching REST route to get the updated snapshot.

**Market scope:**

```json theme={null}
{
  "schemaVersion": 1,
  "scope": "MARKET",
  "marketId": 7348,
  "state": "READY",
  "projectionVersion": "42",
  "scopeVersion": "17",
  "presentationVersion": "3",
  "asOf": "2026-04-20T10:15:40.000Z"
}
```

**Biggest positions scope:**

```json theme={null}
{
  "schemaVersion": 1,
  "scope": "BIGGEST_POSITIONS",
  "state": "READY",
  "projectionVersion": "42",
  "scopeVersion": "17",
  "presentationVersion": "3",
  "asOf": "2026-04-20T10:15:40.000Z"
}
```

| Field                 | Type                                             | Description                                        |
| --------------------- | ------------------------------------------------ | -------------------------------------------------- |
| `schemaVersion`       | `1`                                              | Message schema version                             |
| `scope`               | `'MARKET' \| 'BIGGEST_POSITIONS'`                | Leaderboard scope this hint applies to             |
| `marketId`            | `number`                                         | Market id — present on `MARKET` scope only         |
| `state`               | `'READY' \| 'STALE' \| 'BUILDING' \| 'DEGRADED'` | Readiness of the projection you'll read on refetch |
| `projectionVersion`   | `string`                                         | Monotonic projection version                       |
| `scopeVersion`        | `string`                                         | Monotonic version for this scope's ranking         |
| `presentationVersion` | `string`                                         | Monotonic version of the presentation layer        |
| `asOf`                | `string`                                         | ISO-8601 timestamp of the new snapshot             |

## Related

* [WebSocket overview](/developers/websocket/overview): connection details, handshake authentication, and the full event reference
