API documentation

Conventions

Every endpoint of the LEXX API follows the same small set of rules. Read this page once and nothing in the reference will surprise you.

The response envelope

Every successful response is an object with exactly two top-level keys:

{
  "data": { "...": "the payload — object, array, or null" },
  "meta": {
    "requestId": "550e8400-e29b-41d4-a716-446655440000",
    "timestamp": 1743360060000,
    "version": "v2.0"
  }
}

meta fields:

Field Always present? Meaning
requestId Unique ID of this request (UUID). Log it — it is the first thing LEXX support asks for
timestamp Server time of the response, Unix milliseconds
version API version, currently "v2.0"
idempotencyKey on mutating requests Echo of your X-Idempotency-Key header on a successful POST/DELETE — see Idempotency

Errors use a different envelope — same idea, different keys:

{
  "error": { "code": "RATE_LIMITED", "status": 429, "message": "Rate limit exceeded…" },
  "meta":  { "requestId": "550e8400-e29b-41d4-a716-446655440005" }
}

All codes and handling advice: Errors.

🧬 The one legacy exception: GET /ping responds in the v1 envelope { "status": "success", "data": { "message": "pong", "timestamp": … } }. Every other endpoint uses the v2 shapes above.

Money is strings

All monetary values — prices, quantities, balances, PnL — are string-encoded decimals:

{ "asset": "USDT", "free": "10450.50", "locked": "2500.00" }

JSON numbers are IEEE-754 floats; 0.1 + 0.2 !== 0.3 is not a rounding style you want in order quantities. Handle the strings with a decimal type:

// JavaScript — keep as string, do math with a decimal library
import Big from "big.js";                    // or decimal.js / bignumber.js
const free = new Big(balance.free);          // never: parseFloat(balance.free)
# Python
from decimal import Decimal
free = Decimal(balance["free"])              # never: float(balance["free"])

And symmetrically: when sending amounts (quantity, price, amount, …), send strings — "quantity": "0.001", not "quantity": 0.001.

One documented exception:

  • Bot configuration knobs that are not money — percentages, counts, millisecond durations (trailingDelta, timeFrame, filter thresholds, …) — are plain numbers, as defined per-field in the bot guides.

Time is Unix milliseconds

Every timestamp in the API — request header X-LEXX-TIMESTAMP, from/to/startTime/ endTime parameters, orderTime, updateTime, WebSocket ts, bot Fn.Format keys — is Unix time in milliseconds (1743360060000), UTC.

The only two seconds-based values in the whole API are the rate-limit headers: X-RateLimit-Reset (Unix seconds) and Retry-After (seconds to wait). Everything else is milliseconds.

There are no ISO-8601 dates anywhere in requests or responses.

Identifiers

Order IDs are LEXX-generated client order IDs; the exchange’s native numeric ID is never exposed. The format depends on the exchange:

Exchange Order id format
binance-spot x-MTB46TF3-{uid}
binance-futures x-MZ8FjHFm-{uid}
OKX (spot/futures/swap) lexxO{uid} (no dashes)
Bybit lexx-{uid}

Orders created by a bot append the run ID as a final segment: x-MZ8FjHFm-{uid}_{runId}. An order’s ID is stable for its whole lifetime; a split (and any modify-style operation) cancels the original and creates new orders with new IDs.

Bots have an id (stable) and, while running, a runId (new for every start). Both appear in bot endpoints and in the botStatus WebSocket channel.

Pagination

The API pages by time window:

  • GET /orders/tradesstartTime/endTime (Unix ms) + limit (1–500, default 100; out-of-range values are silently clamped — no error). Page by shifting the time window: request the next window starting at the timestamp of the last record you received.
  • GET /orders, GET /bots — intentionally unpaginated (bounded, served from live state).

Remember the query string is part of the request signature.

Request bodies

  • JSON only, with Content-Type: application/json.
  • Serialize compactly (no pretty-printing) — the body string is part of your signature and the signed bytes must equal the sent bytes.
  • Bodies are capped at 100 KB; larger requests are rejected with 413 PAYLOAD_TOO_LARGE.

Response headers

Every response carries the rate-limit trio X-RateLimit-Limit / X-RateLimit-Remaining / X-RateLimit-Reset; 429 adds Retry-After. How to self-throttle with them: Rate limits.

Verified against API spec v2.0.0 · 2026-07-11

Cookie Preferences

Manage your cookie preferences below. Necessary cookies are always active as they are essential for the website to function properly.

Strictly Necessary

Essential for the website to function. These cookies cannot be disabled.

Analytics

Help us understand how visitors interact with our website by collecting and reporting information anonymously.

Marketing

Used to track visitors across websites to display relevant advertisements.

Preferences

Allow the website to remember choices you make, such as language or region.