Connection
URL: wss://ws.limitless.exchange
Namespace: /markets
Transport: WebSocket only (no polling fallback)
import { io } from 'socket.io-client';
const socket = io('wss://ws.limitless.exchange/markets', {
transports: ['websocket'],
extraHeaders: { 'X-API-Key': 'lmts_your_key_here' }
});
Subscribing to Market Data
Subscribe to price and orderbook updates by emitting subscribe_market_prices:
// AMM price updates
socket.emit('subscribe_market_prices', {
marketAddresses: ['0x1234...']
});
// CLOB orderbook updates
socket.emit('subscribe_market_prices', {
marketSlugs: ['btc-100k-weekly']
});
// Both at once (recommended to avoid overwriting subscriptions)
socket.emit('subscribe_market_prices', {
marketAddresses: ['0x1234...'],
marketSlugs: ['btc-100k-weekly']
});
Subscriptions replace previous ones. If you want both AMM prices and CLOB orderbook, send both marketAddresses and marketSlugs together in a single call.
Subscribing to Position Updates
Subscribe to real-time position changes by emitting subscribe_positions. This requires authentication via the X-API-Key header.
subscribe_positions accepts the same payload as subscribe_market_prices:
| Field | Type | Description |
|---|
marketAddresses | string[] | Contract addresses for AMM markets |
marketSlugs | string[] | Slugs for CLOB markets |
import { io } from 'socket.io-client';
const socket = io('wss://ws.limitless.exchange/markets', {
transports: ['websocket'],
extraHeaders: { 'X-API-Key': 'lmts_your_key_here' },
});
socket.on('connect', () => {
// Subscribe to position updates for specific markets
socket.emit('subscribe_positions', {
marketAddresses: ['0x1234...'], // AMM markets
marketSlugs: ['btc-100k-weekly'], // CLOB markets
});
});
// Confirmation
socket.on('system', (data) => {
console.log(data);
// { message: 'Successfully subscribed to position updates', markets: { addresses: [...], slugs: [...] } }
});
// Position updates
socket.on('positions', (data) => {
console.log('Position update:', data);
});
Like subscribe_market_prices, calling subscribe_positions again replaces the previous subscription. Include all markets in a single call.
Position updates are pushed automatically when your balances change (e.g. after a trade is mined). You do not need to poll.
Subscribing to Market Lifecycle Events
Subscribe to market creation and resolution events by emitting subscribe_market_lifecycle. No authentication required.
socket.on('connect', () => {
socket.emit('subscribe_market_lifecycle');
});
socket.on('marketCreated', (data) => {
console.log('New market:', data.slug, data.title);
});
socket.on('marketResolved', (data) => {
console.log('Market resolved:', data.slug, data.winningOutcome);
});
marketResolved is also emitted to existing per-market room subscribers automatically (CLOB: market:{slug}, AMM: market:{address}) — you don’t need a separate lifecycle subscription to receive resolution events for markets you’re already watching.
To unsubscribe:
socket.emit('unsubscribe_market_lifecycle');
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_market_lifecycle | Client → Server | No | Subscribe to market creation/resolution events |
unsubscribe_market_lifecycle | Client → Server | No | Unsubscribe from market lifecycle events |
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 |
system | Server → Client | No | System notifications |
authenticated | Server → Client | Yes | Authentication confirmation |
exception | Server → Client | No | Error notifications |
Event Payloads
newPriceData
{
"marketAddress": "0x1234...",
"updatedPrices": {
"yes": "0.65",
"no": "0.35"
},
"blockNumber": 12345678,
"timestamp": "2024-01-01T00:00:00.000Z"
}
orderbookUpdate
{
"marketSlug": "btc-100k-weekly",
"orderbook": { ... },
"timestamp": "2024-01-01T00:00:00.000Z"
}
positions
Position updates have different shapes depending on market type.
AMM markets:
{
"account": "0xabcd...",
"marketAddress": "0x1234...",
"positions": [
{
"tokenId": "123456",
"balance": "1000000",
"outcomeIndex": 0,
"collateralOutOnSell": "950000"
}
],
"type": "AMM"
}
CLOB markets:
{
"account": "0xabcd...",
"marketSlug": "btc-100k-weekly",
"positions": [
{
"tokenId": "19633204485790...",
"ctfBalance": "10000000",
"averageFillPrice": "0.65",
"costBasis": "6500000",
"marketValue": "7000000",
"marketId": 7348
}
],
"tokenIds": ["19633204485790..."],
"type": "CLOB"
}
marketCreated
Emitted when a new market is funded and visible. Hidden markets are excluded.
{
"slug": "btc-above-110k-apr-2026",
"title": "$BTC above $110,000 on Apr 5, 2026?",
"type": "CLOB",
"groupSlug": "btc-price-markets",
"categoryIds": [1, 5],
"createdAt": "2026-04-02T12:00:00.000Z"
}
| Field | Type | Description |
|---|
slug | string | Market slug identifier |
title | string | Market title |
type | 'AMM' | 'CLOB' | Market type |
groupSlug | string? | Parent group slug (for NegRisk submarkets) |
categoryIds | number[]? | Category IDs the market belongs to |
createdAt | string | ISO-8601 creation timestamp |
marketResolved
Emitted when a market resolves. Sent to both market_lifecycle subscribers and existing market:{slug} room subscribers.
{
"slug": "btc-above-110k-apr-2026",
"type": "CLOB",
"winningOutcome": "YES",
"winningIndex": 0,
"resolutionDate": "2026-04-05T14:00:00.000Z"
}
| Field | Type | Description |
|---|
slug | string | Market slug identifier |
type | 'AMM' | 'CLOB' | Market type |
winningOutcome | 'YES' | 'NO' | The winning outcome |
winningIndex | 0 | 1 | Index of the winning outcome (0 = YES, 1 = NO) |
resolutionDate | string | ISO-8601 resolution timestamp |