Skip to main content

WebSocketClient Setup

The WebSocketClient connects to the Limitless Exchange WebSocket server for real-time market data, position updates, and transaction notifications.
import { WebSocketClient } from '@limitless-exchange/sdk';

const ws = new WebSocketClient({
  url: 'wss://ws.limitless.exchange',
  autoReconnect: true,
});

ws.connect();

Constructor Options

OptionTypeDefaultDescription
urlstringWebSocket server URL
autoReconnectbooleantrueAutomatically reconnect on disconnection
apiKeystringRequired for authenticated subscriptions (positions, transactions)
Public subscriptions (market prices) do not require an API key. Authenticated subscriptions (positions, transactions) require the apiKey option to be set.

Public Subscriptions

Market Prices

Subscribe to real-time price updates for one or more markets. No authentication required.
const ws = new WebSocketClient({
  url: 'wss://ws.limitless.exchange',
});

ws.connect();

ws.subscribe('subscribe_market_prices', {
  marketSlugs: ['btc-100k-weekly', 'eth-5k-daily'],
  marketAddresses: ['0x1234...'], // For AMM markets
});
Subscriptions replace previous ones. To listen to both CLOB (by slug) and AMM (by address) markets, include both marketSlugs and marketAddresses in a single subscribe_market_prices call.

Authenticated Subscriptions

These subscriptions require an API key passed to the constructor.
const ws = new WebSocketClient({
  url: 'wss://ws.limitless.exchange',
  apiKey: process.env.LIMITLESS_API_KEY,
});

ws.connect();

Positions

Subscribe to real-time updates when your positions change:
ws.subscribe('subscribe_positions');

ws.on('positions', (data) => {
  console.log('Position update:', data);
});

Transactions

Subscribe to transaction confirmations:
ws.subscribe('subscribe_transactions');

ws.on('tx', (data) => {
  console.log('Transaction:', data.hash, data.status);
});

Events

orderbookUpdate (CLOB markets)

Fired when a CLOB market orderbook changes. Contains the full updated orderbook.
ws.on('orderbookUpdate', (data: OrderbookUpdate) => {
  console.log('Market:', data.marketSlug);
  console.log('Bids:', data.orderbook.bids.length);
  console.log('Asks:', data.orderbook.asks.length);

  if (data.orderbook.bids.length > 0 && data.orderbook.asks.length > 0) {
    const spread = data.orderbook.asks[0].price - data.orderbook.bids[0].price;
    console.log('Spread:', spread.toFixed(4));
  }
});

newPriceData (AMM markets)

Fired when AMM market prices update.
ws.on('newPriceData', (data: NewPriceData) => {
  console.log('Market:', data.marketAddress);
  console.log('YES:', data.updatedPrices.yes);
  console.log('NO:', data.updatedPrices.no);
});

positions

Fired when any of your positions change (fill, cancel, resolution).
ws.on('positions', (data: PositionEvent) => {
  console.log('Updated positions:', data);
});

tx

Fired on transaction events related to your account.
ws.on('tx', (data: TransactionEvent) => {
  console.log('Tx hash:', data.hash);
  console.log('Status:', data.status);
});

Type Definitions

interface OrderbookUpdate {
  marketSlug: string;
  orderbook: {
    bids: { price: number; size: number }[];
    asks: { price: number; size: number }[];
  };
}

interface NewPriceData {
  marketAddress: string;
  updatedPrices: {
    yes: string;
    no: string;
  };
}

interface PositionEvent {
  clob: Array<{
    market: { slug: string };
    positions: {
      yes: { size: number; collateral: number };
      no: { size: number; collateral: number };
    };
  }>;
}

interface TransactionEvent {
  hash: string;
  status: 'pending' | 'confirmed' | 'failed';
  type: string;
}

Connection Management

Disconnect handling

Listen for disconnections and clean up resources:
ws.on('disconnect', (reason: string) => {
  console.log('Disconnected:', reason);
});

ws.on('reconnect', () => {
  console.log('Reconnected — resubscribing...');

  ws.subscribe('subscribe_market_prices', {
    marketSlugs: ['btc-100k-weekly'],
  });
});
When autoReconnect is enabled, the client automatically attempts to reconnect. However, you must re-send your subscriptions after reconnection. Listen for the reconnect event to resubscribe.

Graceful shutdown

Clean up the WebSocket connection on process exit:
process.on('SIGINT', () => {
  console.log('Shutting down...');
  ws.disconnect();
  process.exit(0);
});

Debugging

Log all raw events to inspect the data the server sends:
ws.onAny((eventName: string, ...args: unknown[]) => {
  console.log(`[WS] ${eventName}:`, JSON.stringify(args, null, 2));
});
Use raw event logging during development to discover event shapes and debug subscription issues. Remove it before deploying to production.

Full Example

A complete script that subscribes to market prices and positions:
import { WebSocketClient } from '@limitless-exchange/sdk';

const ws = new WebSocketClient({
  url: 'wss://ws.limitless.exchange',
  apiKey: process.env.LIMITLESS_API_KEY,
  autoReconnect: true,
});

ws.connect();

ws.subscribe('subscribe_market_prices', {
  marketSlugs: ['btc-100k-weekly'],
});

ws.subscribe('subscribe_positions');
ws.subscribe('subscribe_transactions');

ws.on('orderbookUpdate', (data) => {
  const best_bid = data.orderbook.bids[0];
  const best_ask = data.orderbook.asks[0];
  console.log(`[${data.marketSlug}] Bid: ${best_bid?.price ?? '-'} | Ask: ${best_ask?.price ?? '-'}`);
});

ws.on('positions', (data) => {
  console.log('[Positions]', JSON.stringify(data));
});

ws.on('tx', (data) => {
  console.log(`[Tx] ${data.hash}${data.status}`);
});

ws.on('disconnect', (reason) => {
  console.log('[Disconnected]', reason);
});

ws.on('reconnect', () => {
  ws.subscribe('subscribe_market_prices', {
    marketSlugs: ['btc-100k-weekly'],
  });
  ws.subscribe('subscribe_positions');
  ws.subscribe('subscribe_transactions');
});

process.on('SIGINT', () => {
  ws.disconnect();
  process.exit(0);
});

console.log('Listening for events... (Ctrl+C to stop)');