Orders
Order behavior, time-in-force, execution controls, and rejection rules
Order Types
Limit
Executes at the specified price or better. Unfilled quantity rests on the order book when using GTC or GTT. Supports all time-in-force options and post_only.
Market
Executes immediately against available liquidity.
priceis required and acts as a slippage cap: a buy will not match makers priced above it; a sell will not match makers priced below it- Only
FOKorIOCtime-in-force is accepted post_onlyis not permitted
Market orders may experience slippage in low-liquidity conditions.
Stop
A conditional order that sits in an untriggered state until a price condition is met, then enters the matching engine as a limit or market order.
Required fields:
stop_price— the trigger level (must match market price accuracy)order_stop_type—profit(take-profit) orloss(stop-loss)stop_price_option—last_priceormark_price(defaults tolast_priceif omitted)
Allowed time-in-force: GTC, FOK, IOC (GTT is not permitted).
Margin is not reserved while the order is untriggered. It is reserved only after the trigger fires and the order enters the matching engine.
Trigger conditions by position side and stop type:
| Position | Stop type | Side | Triggers when price… |
|---|---|---|---|
| Long | Take-profit (profit) | Sell | Rises to or above stop_price |
| Long | Stop-loss (loss) | Sell | Falls to or below stop_price |
| Short | Take-profit (profit) | Buy | Falls to or below stop_price |
| Short | Stop-loss (loss) | Buy | Rises to or above stop_price |
Use mark_price as the trigger source for stronger manipulation resistance.
TWAP
TWAP splits execution of a large order into a series of smaller sub-orders scheduled at fixed intervals, reducing market impact. TWAP batches are submitted via a dedicated endpoint (POST /orders/twap); each sub-order carries its own price, size, nonce, signature, and scheduled timestamp.
TWAP batch validation rules (any violation returns 400):
- All sub-orders must share the same price and size (uniform slicing)
- Nonce values must be strictly increasing across the batch
- Intervals between consecutive
sched_tsvalues must be positive, equal, and divisible by 60 seconds - The first
sched_tsmust be at least 10 seconds in the future - At most 100 sub-orders per batch
Allowed time-in-force: GTC, FOK, IOC (GTT is not permitted).
Unlike stop orders, TWAP orders do reserve margin while untriggered.
Time-in-Force (TIF)
| TIF | Description | Supported order types |
|---|---|---|
GTC | Rest on book until filled or canceled (default) | Limit, Stop, TWAP |
IOC | Fill as much as possible immediately; cancel remainder | Limit, Market, Stop, TWAP |
FOK | Fill fully now or cancel entirely (no partial fills) | Limit, Market, Stop, TWAP |
GTT | Expire at expired_at timestamp | Limit only |
GTT requires expired_at > 0 and at most 30 days in the future; requests with an out-of-range value are rejected. All other order types must have expired_at = 0.
Field Defaults
When optional fields are omitted, the engine applies these defaults:
| Field | Default |
|---|---|
| Order type | LIMIT |
| Time-in-force | GTC |
| STP policy | cancel_taker |
| Stop price source | last_price |
STP is always active — omitting the field does not disable self-trade prevention.
Matching Behavior
The engine uses price-time priority (FIFO within a price level). For each incoming taker order:
- Price bound check — iterates the opposite side of the book. A buy stops matching when maker ask price exceeds taker price; a sell stops when maker bid price is below taker price.
- Post-only check — if the taker has
post_only = trueand would cross the book, the entire order is canceled with reasoncanceled: post-only. - Liquidity check — if both sides of the book are not present, the order is canceled with reason
canceled: insufficient liquidity. - Self-trade prevention — applies the configured STP policy before executing a match.
- Match cap — a single order may produce at most 1,000 matches. If this limit is reached, the entire order is rejected and no fills are booked (
canceled: too many matches).
After matching, post-match margin validation runs. If the resulting portfolio is under-margined (cross or isolated), the order is canceled with reason canceled: insufficient margin.
Partial fills are not a separate order status — filled_sz is updated in place while the order remains open. The order transitions to done only when fully filled or canceled.
Execution Controls
Reduce-only
A reduce_only order can only decrease an existing position.
Pre-match checks:
- Position must exist; rejected if already closed
- Order side must be opposite to the position side
- For non-IOC orders: if order size exceeds position size, the order is rejected
- For IOC orders: if order size exceeds position size, the size is clipped to the remaining position before matching
After matching, any lower-priority resting reduce-only orders that would exceed the remaining position are auto-canceled (canceled: reduce-only auto canceled due to position reduction).
Reduce-only orders do not reserve margin.
Post-only
If set, the order is canceled immediately if it would cross the book at placement time rather than rest as a maker. Not available for market orders. Guarantees maker-fee treatment when the order does rest.
Self-Trade Prevention (STP)
If an incoming order would match your own resting order, STP applies. The default policy is cancel_taker:
| Value | Behavior |
|---|---|
cancel_taker | Cancel the incoming order; keep the resting order |
cancel_maker | Cancel the resting order; continue matching the incoming order |
cancel_both | Cancel both orders |
Client Order ID (cl_oid)
You may attach a client-assigned identifier to any order (max 32 characters; alphanumeric plus -, _, :). This is useful for correlating orders across your own systems without relying solely on the exchange-assigned order ID.
Synchronous Submission (await)
For LIMIT and MARKET orders, setting await: true causes the placement request to block until the matching engine has processed the order before returning. Useful when you need an immediate fill confirmation before taking further action.
Bracket Orders
A bracket order links a parent entry order to one or two conditional exit orders (take-profit and/or stop-loss), submitted together via POST /orders/group. The children remain untriggered until the parent fills, at which point they become active. When one child triggers and fills, the other is automatically canceled.
Bracket validation rules:
| Rule | Constraint |
|---|---|
| Order count | Exactly 2 or 3 (parent + 1–2 children) |
| Parent type | LIMIT, MARKET, or STOP |
Parent reduce_only | Must be false (or omitted) |
| Children type | Must be STOP |
| Children per stop type | At most one take-profit and one stop-loss |
| Children market | Same as parent |
| Children size | Same as parent |
| Children side | Opposite of parent |
Children reduce_only | Must be true |
| Children time-in-force | Must be IOC |
Take-profit stop_price | Above parent price for buy parent; below for sell parent |
Stop-loss stop_price | Below parent price for buy parent; above for sell parent |
Order Statuses
| Status | Description |
|---|---|
pending | Received by the sequencer, awaiting matching engine processing |
open | Resting on the order book |
untriggered | Stop or TWAP order waiting for its trigger condition |
done | Terminal state: filled or canceled |
Status lifecycle:
LIMIT/MARKET:pending→open→doneSTOP/TWAP:untriggered→open→done
Market Mode Restrictions
Order placement is validated against the market's current mode before any other checks. See Market Lifecycle for the full mode reference.
mode | Regular user | Market maker | Cancel |
|---|---|---|---|
trading | All order types | All order types | yes |
post_only | Post-only only | Post-only only | yes |
wind_down | Reduce-only only | Reduce-only + post-only | yes |
halted | Blocked | Blocked | yes |
delisted | Blocked | Blocked | blocked |
In wind_down, market makers may also place post-only orders to provide counterparty liquidity for users closing positions. Cancellations are accepted in all modes except delisted.
Cancellation Reasons
done_reason | Cause |
|---|---|
filled | Order fully executed |
canceled: user | Canceled by the user |
canceled: admin | Canceled by an admin |
canceled: post-only | Post-only order would have crossed the book |
canceled: insufficient liquidity | No matching orders on the opposite side |
canceled: insufficient margin | Portfolio under-margined after matching |
canceled: time in force IOC | Unfilled remainder after IOC matching |
canceled: time in force FOK | Order not fully filled; entire order voided |
canceled: time in force GTT | Order expired at expired_at |
canceled: stp | Self-trade prevention triggered |
canceled: too many matches | Exceeded 1,000 matches per order |
canceled: reduce-only position already closed | No open position at pre-match time |
canceled: reduce-only invalid side (...) | Order side matches position side |
canceled: reduce-only exceeds pos (...) | Order size exceeds position for non-IOC |
canceled: reduce-only auto canceled due to position reduction | Resting reduce-only order excess after position reduced |
canceled: tpsl position closed | Parent position closed before stop order triggered |
canceled: parent order canceled unfilled | Parent order (bracket) canceled before fill |
canceled: liquidation | Canceled by liquidation engine |