> ## 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.

# WebSocket Overview

> Connection details, handshake authentication, and the event reference for the Limitless WebSocket API

This page covers how to connect to the Limitless WebSocket API, how to sign the handshake for authenticated channels, and the full list of client and server events. Each subscription has its own page pairing the subscribe call with the payloads it delivers.

## Connection

**URL:** `wss://ws.limitless.exchange`
**Namespace:** `/markets`
**Transport:** WebSocket only (no polling fallback)

<Note>
  **No client PING required.** The server runs the Socket.IO heartbeat (server-initiated `ping` / client `pong`) automatically. Every official Socket.IO client (JavaScript, Python `python-socketio`, Go, Rust) responds to it out of the box. Do not send your own PING frames. Keep the connection open and rely on the built-in heartbeat and the auto-reconnect flow in [WebSocket quick start](/developers/quickstart/websocket#auto-reconnection).
</Note>

Authenticated channels (positions, order events) require an HMAC-signed handshake. Sign a fixed canonical message — `{ISO-8601 timestamp}\nGET\n/socket.io/?EIO=4&transport=websocket\n` — with the base64-decoded `secret` and pass three headers as `extraHeaders`:

```typescript theme={null}
import { createHmac } from 'crypto';
import { io } from 'socket.io-client';

function wsAuthHeaders(tokenId: string, secret: string) {
  const timestamp = new Date().toISOString();
  const message = `${timestamp}\nGET\n/socket.io/?EIO=4&transport=websocket\n`;
  const signature = createHmac('sha256', Buffer.from(secret, 'base64'))
    .update(message)
    .digest('base64');
  return { 'lmts-api-key': tokenId, 'lmts-timestamp': timestamp, 'lmts-signature': signature };
}

const socket = io('wss://ws.limitless.exchange/markets', {
  transports: ['websocket'],
  extraHeaders: wsAuthHeaders(TOKEN_ID, SECRET),
});
```

See [Authentication](/developers/authentication) for how to generate `TOKEN_ID` and `SECRET`. If you use an official SDK, prefer its WebSocket client, which signs the handshake automatically from `hmacCredentials` (TypeScript) / `hmac_credentials` (Python) / `WithHMACCredentials` (Go).

## Event reference

| Event                            | Direction       | Auth required | Description                                                                       |
| -------------------------------- | --------------- | ------------- | --------------------------------------------------------------------------------- |
| `connect`                        | Server → Client | No            | Connection established                                                            |
| `disconnect`                     | Server → Client | No            | Connection lost                                                                   |
| `subscribe_market_prices`        | Client → Server | No            | Subscribe to price/orderbook updates                                              |
| `subscribe_positions`            | Client → Server | Yes           | Subscribe to position updates                                                     |
| `subscribe_order_events`         | Client → Server | Yes           | Subscribe to OME and settlement events for your CLOB orders                       |
| `subscribe_market_lifecycle`     | Client → Server | No            | Subscribe to market creation/resolution events                                    |
| `unsubscribe_market_lifecycle`   | Client → Server | No            | Unsubscribe from market lifecycle events                                          |
| `subscribe_unrealized_pnl`       | Client → Server | No            | Subscribe to Unrealized PnL leaderboard invalidation hints                        |
| `unsubscribe_unrealized_pnl`     | Client → Server | No            | Unsubscribe from Unrealized PnL invalidation hints                                |
| `unrealizedPnlProjectionChanged` | Server → Client | No            | Hint that a subscribed Unrealized PnL leaderboard changed; refetch the REST route |
| `newPriceData`                   | Server → Client | No            | AMM market price update                                                           |
| `orderbookUpdate`                | Server → Client | No            | CLOB orderbook update                                                             |
| `marketCreated`                  | Server → Client | No            | New market created and visible                                                    |
| `marketResolved`                 | Server → Client | No            | Market resolved with winning outcome                                              |
| `positions`                      | Server → Client | Yes           | Position balance update                                                           |
| `orderEvent`                     | Server → Client | Yes           | OME lifecycle, FAK/FOK execution, and settlement updates for your CLOB orders     |
| `system`                         | Server → Client | No            | System notifications                                                              |
| `authenticated`                  | Server → Client | Yes           | Authentication confirmation                                                       |
| `exception`                      | Server → Client | No            | Error notifications                                                               |

## Unsubscribing

There is no generic `unsubscribe` event. Only two channels have an explicit unsubscribe: `unsubscribe_market_lifecycle` and `unsubscribe_unrealized_pnl`.

`subscribe_market_prices`, `subscribe_positions`, and `subscribe_order_events` have none. Each of those **replaces** its previous subscription on the same connection when you emit it again, so to drop a market you re-emit the subscribe with the smaller set. To stop everything, disconnect. An unsubscribe event name that the server does not register never gets an acknowledgement, so a client waiting on one times out.

## Related

Each subscription has its own page pairing the subscribe call with the payloads it delivers:

* [Market data](/developers/websocket/market-data): `subscribe_market_prices`, `newPriceData`, `orderbookUpdate`
* [Positions](/developers/websocket/positions): `subscribe_positions`, `positions`
* [Order events](/developers/websocket/order-events): `subscribe_order_events`, `orderEvent`
* [Market lifecycle](/developers/websocket/market-lifecycle): `subscribe_market_lifecycle`, `unsubscribe_market_lifecycle`, `marketCreated`, `marketResolved`
* [Unrealized PnL](/developers/websocket/unrealized-pnl): `subscribe_unrealized_pnl`, `unsubscribe_unrealized_pnl`, `unrealizedPnlProjectionChanged`
