Skip to main content

Documentation Index

Fetch the complete documentation index at: https://limitless-docs-ws-settlement-events.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

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:
FieldTypeDescription
marketAddressesstring[]Contract addresses for AMM markets
marketSlugsstring[]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 Order Events

Subscribe to the full lifecycle of your CLOB orders by emitting subscribe_order_events. Requires authentication via the X-API-Key header. The subscription takes no payload — it is a per-user channel that delivers events for every order you are party to. Two distinct event shapes arrive on the same Socket.IO event name orderEvent. Distinguish by the source field:
  • OME — off-chain matching engine state changes: PLACEMENT, UPDATE, CANCELLATION.
  • SETTLEMENT — on-chain settlement results for CLOB trades: MINED, FAILED.
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', () => {
  socket.emit('subscribe_order_events');
});

socket.on('system', (msg) => {
  // { message: 'Successfully subscribed to order event updates' }
  console.log(msg);
});

socket.on('orderEvent', (data) => {
  if (data.source === 'OME') {
    console.log(`[OME ${data.type}] order=${data.orderId} clientOrder=${data.clientOrderId ?? '(none)'}`);
  } else {
    console.log(
      `[SETTLEMENT ${data.type}] order=${data.orderId} clientOrder=${data.clientOrderId ?? '(none)'} tx=${data.txHash ?? '(none)'}`,
    );
  }
});
One subscription per connection. Sending subscribe_order_events a second time re-binds; the previous subscription is cancelled. There is no payload.
Channel is per-user, not per-market. You receive events for every order you are party to (as taker or maker) — the subscription cannot be narrowed by market. Filter client-side on marketId / marketSlug if needed.
Ordering is not guaranteed across sources. OME and SETTLEMENT events for the same order can arrive in either order within a few seconds — settlement can land before the corresponding UPDATE, or vice versa. Treat them as independent streams that both reference orderId / takerOrderId.
Resubscribe on reconnect. Subscriptions are not persisted server-side across disconnects — your connect handler must re-emit subscribe_order_events.
Server-side deduplication. Repeated emissions within a 60-second sliding window are dropped, so retries and replays will not double-deliver. Client-side dedup is only required if you persist events across reconnects yourself.
Auth failures surface on the exception channel. If the X-API-Key header is missing, invalid, or revoked, the guard emits a WsException to the client’s exception event and no orderEvent frames arrive. Subscribe to socket.on('exception', ...) if you want to detect auth failures rather than silently miss the stream.

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

EventDirectionAuth RequiredDescription
connectServer → ClientNoConnection established
disconnectServer → ClientNoConnection lost
subscribe_market_pricesClient → ServerNoSubscribe to price/orderbook updates
subscribe_positionsClient → ServerYesSubscribe to position updates
subscribe_order_eventsClient → ServerYesSubscribe to OME and settlement events for your CLOB orders
subscribe_market_lifecycleClient → ServerNoSubscribe to market creation/resolution events
unsubscribe_market_lifecycleClient → ServerNoUnsubscribe from market lifecycle events
newPriceDataServer → ClientNoAMM market price update
orderbookUpdateServer → ClientNoCLOB orderbook update
marketCreatedServer → ClientNoNew market created and visible
marketResolvedServer → ClientNoMarket resolved with winning outcome
positionsServer → ClientYesPosition balance update
orderEventServer → ClientYesOME or settlement update for one of your CLOB orders
systemServer → ClientNoSystem notifications
authenticatedServer → ClientYesAuthentication confirmation
exceptionServer → ClientNoError 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"
}
FieldTypeDescription
slugstringMarket slug identifier
titlestringMarket title
type'AMM' | 'CLOB'Market type
groupSlugstring?Parent group slug (for NegRisk submarkets)
categoryIdsnumber[]?Category IDs the market belongs to
createdAtstringISO-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"
}
FieldTypeDescription
slugstringMarket slug identifier
type'AMM' | 'CLOB'Market type
winningOutcome'YES' | 'NO'The winning outcome
winningIndex0 | 1Index of the winning outcome (0 = YES, 1 = NO)
resolutionDatestringISO-8601 resolution timestamp

orderEvent

Emitted for both OME state changes and on-chain settlement results. Distinguish the two shapes by the source field.

OME event (source: "OME")

Emitted for every order state change recorded by the matching engine. price and remainingSize are decimal strings — do not parse them as number for comparisons.
{
  "source": "OME",
  "type": "PLACEMENT",
  "eventId": 1234567,
  "orderId": "550e8400-e29b-41d4-a716-446655440000",
  "clientOrderId": "client-order-001",
  "userId": 42,
  "marketId": "17",
  "token": "87893014956437093847...",
  "side": "BUY",
  "price": "0.53",
  "remainingSize": "100",
  "timestamp": "2026-04-20T10:15:30.000Z"
}
FieldTypeDescription
source'OME'Discriminator for the OME shape
type'PLACEMENT' | 'UPDATE' | 'CANCELLATION'OME state transition
eventIdnumberMonotonic OME event id
orderIdstringUUID of the order
clientOrderIdstring?Client-supplied id from POST /orders, when the order was placed with one. Field is omitted (not null) when the originating order had no client id.
userIdnumberInternal user id of the order owner
marketIdstringNumeric market id (CLOB)
tokenstringCTF token id (decimal string)
side'BUY' | 'SELL'Order side
pricestringLimit price (decimal string)
remainingSizestringSize remaining on the book (decimal string)
timestampstringISO-8601 event timestamp
type transitions:
  • PLACEMENT — order accepted by the OME.
  • UPDATE — remaining size changed (partial fill or amend).
  • CANCELLATION — removed from the book.

Settlement event (source: "SETTLEMENT")

Emitted when a CLOB trade settles on-chain. Each participant receives a settlement event for their own order: one for the taker order and one for each matched maker order. takerAccount and makerMatches[].account are on-chain addresses — for smart-wallet users this is the smart-wallet proxy, for EOA users it is the EOA.
{
  "source": "SETTLEMENT",
  "type": "MINED",
  "eventId": "settlement:1b3a…:550e8400-e29b-41d4-a716-446655440000",
  "tradeEventId": "1b3a…",
  "orderId": "550e8400-e29b-41d4-a716-446655440000",
  "clientOrderId": "client-order-001",
  "takerOrderId": "e4c3…",
  "takerAccount": "0xAbC…123",
  "makerMatches": [
    {
      "account": "0xDeF…456",
      "orderId": "cb12…",
      "matchedSize": "25",
      "price": "0.53"
    }
  ],
  "marketSlug": "will-abc-happen-by-2026",
  "tokenId": "87893014956437093847...",
  "side": "BUY",
  "price": "0.53",
  "amountContracts": "25",
  "amountCollateral": "13.25",
  "configuredFeeRateBps": 0,
  "effectiveFeeBps": 0,
  "feeAmountContracts": "0",
  "txHash": "0xabc…",
  "timestamp": "2026-04-20T10:15:40.000Z"
}
FieldTypeDescription
source'SETTLEMENT'Discriminator for the settlement shape
type'MINED' | 'FAILED'Settlement outcome
eventIdstringStable id in the form settlement:<tradeEventId>:<orderId>
tradeEventIdstringSettlement trade id shared by all participant events for the same match
orderIdstring?UUID of the recipient’s own order for this event
clientOrderIdstring?Client-supplied id of the recipient’s own order (orderId), when the order was placed with one. Field is omitted (not null) when the originating order had no client id. Counterparty (takerOrderId, makerMatches[].orderId) ids are never resolved to client ids.
takerOrderIdstring?UUID of the taker order in the trade
takerAccountstring?On-chain address of the taker (smart-wallet proxy or EOA)
makerMatchesarray?One entry per matched maker (account, orderId, matchedSize, price). A taker event can include multiple maker matches; each maker also receives a separate event for its own order.
marketSlugstring?CLOB market slug
tokenIdstring?CTF token id for the recipient side
side'BUY' | 'SELL'?Recipient order side
pricestring?Execution price as a decimal string
amountContractsstring?Filled contract amount for the recipient order
amountCollateralstring?Collateral amount for the recipient order
configuredFeeRateBpsnumber?Fee rate configured for the order
effectiveFeeBpsnumber?Effective fee rate applied to this trade
feeAmountContractsstring?Fee amount in contracts
txHashstring?Settlement transaction hash, when known
timestampstringISO-8601 event timestamp
Reconciling WS events with POST /orders. Submit an order with a clientOrderId and every orderEvent for that order — PLACEMENT, UPDATE, CANCELLATION, and the MINED / FAILED settlement frame — echoes the same clientOrderId. Match WS events to the originating request by clientOrderId rather than waiting for the POST /orders HTTP response, which only returns once settlement is MINED. If only one side supplied a clientOrderId, only that side’s event includes it.
  • type: "MINED" — on-chain settlement confirmed.
  • type: "FAILED" — settlement failed on-chain; the taker order did not execute and funds were not moved.