Skip to main content

Overview

The Limitless WebSocket API provides real-time market prices, orderbook updates, and position notifications. This guide covers connecting with Python using python-socketio with asyncio.

Prerequisites

1

Install dependencies

Install the required packages:
Use a virtual environment to isolate dependencies. Run python -m venv venv then source venv/bin/activate (Unix) or venv\Scripts\activate (Windows) before installing.

Authentication modes

Connect without authentication to receive public market data only:
  • newPriceData (AMM market prices)
  • orderbookUpdate (CLOB orderbook)
  • system (system notifications)
No API key required. Use this for read-only market monitoring.
Never commit your API token ID or secret to version control or expose them in client-side code. Use environment variables (e.g. LMTS_TOKEN_ID / LMTS_TOKEN_SECRET) and load them at runtime.
Cookie-based session authentication is deprecated. Authenticate the handshake with HMAC-signed headers (lmts-api-key, lmts-timestamp, lmts-signature) — see Authentication.

Connection details

Authenticated connections sign the Socket.IO handshake with HMAC. The signed canonical message uses a fixed path and empty body, and the HMAC key is the base64-decoded secret:
ws_auth.py
See Authentication for how to generate the token ID and secret.

Subscribing to market prices

Emit subscribe_market_prices with market identifiers. Subscriptions replace previous ones, so include all markets you want in a single call.
Subscriptions replace previous ones. If you want both AMM prices and CLOB orderbook, send both marketAddresses and marketSlugs together in a single subscribe_market_prices call.
The server answers every subscribe_market_prices call, first or repeat, with one orderbookUpdate per CLOB slug carrying the full current book, including books with empty bids and asks. You do not need a REST call to seed local state. See Initial snapshot.

Subscribing to positions

Position updates require authentication. Emit subscribe_positions after connecting. Pass the markets you want position updates for (marketSlugs and/or marketAddresses); an empty payload is ignored server-side.

Handling events

Register handlers for each event type. All handlers use namespace="/markets".

Event payloads

newPriceData — AMM market price update. Live updates carry updatedPrices as an array and no top-level marketAddress:
The initial snapshot sent after subscribing carries a top-level marketAddress and an updatedPrices object:
positions — Position balance update (auth required):
system — System notification:

Complete async Python client

Usage examples

Environment variables

Auto-reconnection

The client uses reconnection=True by default. On reconnect, call _resubscribe() in the connect handler to restore market and position subscriptions, since the server does not persist them across disconnects. Authenticated connections pass headers as a function. python-socketio calls it before every connection attempt, so each reconnect carries a new timestamp and signature. A plain dict is sent again unchanged on reconnect. The socket still connects, but the server checks the handshake headers on every subscribe_positions and subscribe_order_events, and a timestamp outside the 30-second window fails that check with Invalid HMAC authentication, so the re-subscription is rejected. Our load balancer closes every connection after 24 hours (see WebSocket overview), so a long-running client always goes through this reconnect path at least once a day.
Store your API token ID and secret securely. Rotate the token if you suspect it has been exposed. Do not log or print the secret.