Skip to main content
The REST API uses the same order books, trading rules, fees, margin checks, and paper execution engine as the trading terminal. Every create request requires an Idempotency-Key header. Standard orders and position closes may also carry a caller-assigned client_order_id for durable reconciliation.

Standard and advanced orders

Send orders to POST /v1/orders. If type is omitted, the request is treated as a market order for compatibility with existing clients. The server resolves provider, symbol, and venue coin from market_id. Do not send those fields. expected_price records what your client observed, but it never controls the execution price, margin calculation, or slippage reference. FX markets are EUR/USD and USD/JPY, both on lighter. Use their current market_id values from GET /v1/markets. The historical fpx provider is retired and has no markets available for new trades. Before placing a market order, request GET /v1/markets/{market_id}/quote?side=buy&size=... to estimate the fill. A size-aware quote returns the projected fill price (the mark price adjusted by the size-based slippage tier), the applied slippage in basis points, notional, fee, and whether the requested size is valid at the market’s precision. The eventual order still executes against newer authoritative market data after the anti-arbitrage delay, so treat the quote as an estimate rather than a reserved price. The fee rate follows the market’s asset category, regardless of its source venue or venue ticker format. The fee and slippage schedules are published in the Trading Guide. For Lighter forex, the projected and eventual market fills use the venue mark plus the published slippage tier. The quote’s bid, ask, and mid fields continue to describe the order book; mid is not the fill reference for these markets. Execution requires a fresh mark from a newer generation than the one observed after the order was committed.

Limit order example

For a GTD limit, set time_in_force to gtd and provide gtd_expires_at as a Unix timestamp in milliseconds. IOC and FOK limits use time_in_force without an expiry.

Manage working orders

Use GET /v1/orders?account_id=...&status=working for the complete bounded set of pending and resting orders. This view is safer for reconciliation than searching recent history. Use GET /v1/orders?client_order_id=... to resolve your caller-assigned order identity when the placement response or server id is unavailable. This lookup survives API key rotation and returns the normal order-page shape with zero or one result. If the server cannot prove the snapshot is complete inside the active-order bound, it returns 503 with Retry-After instead of returning truncated data.
  • PATCH /v1/orders/{order_id} changes price and optionally size.
  • PUT /v1/orders/{order_id}/attached-exits sets or removes TP/SL attached to a resting limit entry. Send null to remove a leg.
  • DELETE /v1/orders/{order_id} cancels a working order or queues cancellation when execution already owns the row.
To cancel the complete ordinary-order snapshot for an account, send POST /v1/accounts/{account_id}/cancel-all-orders with an Idempotency-Key. It includes resting orders and armed trigger orders. An in-flight market order can still settle, and active TWAP, VWAP, or scaled parents must be canceled through their own endpoints. Each request advances at most five source orders, with every source cancellation isolated in its own transaction. A 202 response includes progress and Retry-After; repeat the same request until the operation reports completed. Chase orders cannot be modified. Cancel the chase and place a replacement with new offset or cap settings.

Close and protect positions

POST /v1/positions/{position_id}/close derives the closing side, leverage, margin mode, and reduce-only flag from the current position. It supports market, limit, and external conditional closes. Omit size for a full close. Provide client_order_id to reconcile the resulting close order in the same way as a standard order. To flatten one account, send POST /v1/accounts/{account_id}/close-all-positions with an Idempotency-Key. The server snapshots at most 100 open positions and submits one reduce-only market close per target, paced through the account’s order cooldown. These closes use the trading terminal’s 2.5% maximum-slippage policy. Each request advances one position and never sleeps through the account cooldown inside the HTTP action. A 202 response includes current progress and Retry-After; repeat the same request until the operation reports completed. The final result contains the submitted order or rejection for every snapshotted position. Both account-wide endpoints persist their original target snapshot. A retry with the same idempotency key resumes unfinished targets or returns the completed result, even if the account state has changed. A concurrent retry returns 409 operation_in_progress with Retry-After; wait and retry with the same key. A different account or action cannot reuse that key. Use PUT /v1/positions/{position_id}/exit-orders to atomically place, modify, and cancel multiple TP/SL levels. The request includes the position size and current exit-order snapshot you observed. A concurrent position or order change returns 409, so fetch fresh state and rebuild the operation. New TP and SL operations can reference each other by operation index to form an OCO pair. A fill retires the same quantity from the paired leg; a partial fill shrinks that leg and a full fill cancels it. Manually canceling one leg leaves the other leg active and unlinked. For an isolated position, PUT /v1/positions/{position_id}/isolated-margin sets the desired total extra_margin. Repeating the same target is safe. A reduction uses a fresh authoritative book and rejects when it would create unsafe liquidation risk.

TP/SL batch example

For a long position of size 0.01 with no existing protective exits, this request creates a paired market TP and SL. Replace the prices with valid levels above and below the current market respectively.
Send this body to PUT /v1/positions/{position_id}/exit-orders. For MCP, call replace-position-exit-orders with the same fields plus position_id. If protective exits already exist, populate expected_orders from the current working-order snapshot with each exit’s order_id, execution_type, price, and size. Do not send an empty snapshot for an already-protected position. Use execution_type: "limit" for price-capped protective exits through this batch endpoint; the ordinary create-order endpoint rejects reduce-only stop_limit and take_limit requests.

TWAP and VWAP

Create both strategies with POST /v1/twap-orders. Set strategy to twap or vwap, then provide the duration, slice interval, and optional randomized timing. Optional trigger and termination prices use the same behavior as the terminal. The slice interval must be a whole number from 30 seconds through the smaller of 12 hours or half the selected duration. Every schedule therefore has at least two slices. Read active schedules with GET /v1/twap-orders?account_id=..., inspect one parent with GET /v1/twap-orders/{id}, and stop future slices with DELETE on that resource. An in-flight child may still settle after cancellation begins. Retain the parent ID returned at creation to inspect that schedule directly throughout its lifecycle.

Scaled orders

Create a ladder with POST /v1/scaled-orders. Provide a start price, end price, 2 to 10 rungs, and a flat, ascending, or descending distribution. Every rung is an ordinary limit order and independently follows the platform’s fill and trading rules. GET /v1/scaled-orders/{id} returns every rung’s price, size, child order ID, and placement rejection when applicable. DELETE fences unplaced rungs and cancels every working child.

Reconcile fills and closed positions

GET /v1/fills?account_id=... returns filled orders in settlement order with fees, realized P&L, notional, liquidity role, and partial-fill lineage. Use GET /v1/positions?account_id=...&status=closed for cursor-paginated closed position records. Treat all cursors as opaque. Order and strategy state can continue changing after a response, so reconcile by resource ID until it reaches a terminal status.

Copy groups and scheduled execution

Before submitting a lead order through the API, ensure the credential covers the lead and every follower. The same boundary applies to modifications, cancellations, and protective exits. A scope failure rejects the complete native order operation, preserving the copy group’s behavior rather than silently dropping a follower. See Authentication. Accepted TWAP/VWAP and scaled orders retain the environment and account scope that authorized them. Revoking the key blocks new requests but does not revoke that accepted schedule. Each later slice or rung checks the current copy group against its retained scope. If the group now includes an inaccessible account, TWAP/VWAP stops with completion_reason: "api_account_scope_changed"; scaled orders reject the remaining unplaced rungs with that reject_reason. Previously accepted child orders are not canceled, and filled positions are not closed. Older API schedules created before scope was retained can recover their boundary while the original key still exists. If that key has been deleted, only the schedule’s own account can be established: an enabled copy group causes future slices or rungs to stop rather than assume broader access. Finish or recreate an older copied schedule before deleting its original key.

Reconcile conditional orders and scheduled history

Order responses expose stop_triggered_at once a conditional limit has entered its limit leg. Before that timestamp exists, its trigger remains armed. triggered_at records the latest execution attempt and may change on retry. cancel_requested_at records cancellation intent while execution can still be in flight: reconcile the final status because a fill can win that race. oco_sibling_order_id identifies the paired exit. Fills retire matching size from its sibling; canceling one leg explicitly unlinks the surviving leg. GET /v1/twap-orders?account_id=... continues to return active TWAP and VWAP parents. To discover terminal parents without retaining their IDs, request status=completed or status=canceled. History is ordered by creation time, newest first, within the selected status, and accepts limit (1 to 100, default 50) and cursor. Follow next_cursor while has_more is true, keeping account_id and status unchanged. Query both terminal statuses for a complete history. The strategy field distinguishes TWAP from VWAP; completion_reason explains why a completed schedule stopped. Pagination is not accepted for the active listing.

Live market data

Use market data streaming for live prices, books, trades, and candles. It is public and uses a dedicated WebSocket endpoint. Continue using REST for account balances, positions, order state, and fills; private account streaming is not available.