order action places one or more orders against a contract. A single request can carry up to 10 order objects under one ECDSA signature. Order objects use compact single-letter keys to keep payloads small.
Three order shapes are available, selected by the t field: limit (GTC, IOC, or ALO), market, and trigger (stop-loss, take-profit, or breakout entry). A limit or market entry order can also carry inline take-profit and stop-loss levels, so a position and its exits are established in one signed request.
Endpoint
Request
- Limit Order
- Market Order
- Trigger Order
- Entry with TP/SL
- With Builder Fee
Rests in the order book until filled or cancelled (GTC), or follows the IOC / ALO policy you choose.
p is the resting price.Action fields
string
required
Fixed value:
"order".array
required
Array of order objects. Maximum 10 per request; more returns
BATCH_TOO_LARGE.string
Compatibility field. The server does not validate it and it does not affect placement, but send the conventional value
"na".Order object fields
Each element of theorders array uses compact single-letter keys.
int32
required
asset — The integer contract ID identifying which perpetual to trade.
boolean
required
isBuy —
true to buy/go long; false to sell/go short.string
required
price — Order price as a raw integer string, required for every order type.
- Limit order — the resting price.
- Market order — the execution price you are willing to cross to, computed client-side as
mark price ± slippage allowance. - Trigger order — the resting price after the trigger fires when
isMarketisfalse, or the execution price when it istrue.
tickSize. A missing, zero, or misaligned price is rejected.string
required
size — Order quantity as a raw integer string. Must be positive.
boolean
reduceOnly —
true restricts the order to reducing an existing position. Omitting the field is equivalent to false.object
required
orderType — Selects limit, market, or trigger behavior. See Order types.
string
clientOrderId — An int64 decimal string you assign for your own tracking (for example
"1778572951477"). Use it later with cancelByCloid to cancel without storing the exchange-assigned oid.string
builder — Optional builder-fee recipient address (
"0x" + 40 hex). Omit for no builder. An unregistered address does not reject the order, but builderFee is silently zeroed.int
builderFee — Builder fee rate in basis points. Ignored when
builderAddress is omitted.In a batched request only the first order’s builder fields take effect — the engine uses
orders[0]’s builderAddress / builderFee as the single shared builder for the whole batch, the same one-per-request rule as vaultAddress.You never send a position side. The server derives which position an order acts on from the contract, the direction
b, and r — a reduce-only order closes the position opposite to its own direction.Order types
Trigger orders
A trigger order consumes no book depth while it waits. When the mark price crossestriggerPx, the server places the order described by the remaining fields.
string
required
Trigger price as a raw integer string, greater than zero. Evaluated against the mark price.
boolean
required
true fires a market IOC order; false rests a GTC limit order. Both require a positive top-level p — the resting price when false, the execution price when true.string
required
"tp" or "sl". Sets the direction of the trigger comparison, matching the convention used by tpSl.- Single order only. Trigger orders are valid when
ordershas exactly one element. A batch containing one is rejected with400 BAD_REQUEST. - The trigger price is always evaluated against the mark price; no other price source can be selected.
- A trigger order cannot also carry inline
tp*/sl*fields. - The response differs from an ordinary order — see Trigger order response.
- A resting trigger order appears in
userOrderswithisConditional: true, anorderTypeofTPM/TPL/SM/SL, and itstriggerPrice. On theorderUpdateschannel it carries the compactcond: trueflag. - Cancel it with
cancelConditionalorcancelTpSl; there is no dedicated cancel action.
Inline take-profit and stop-loss
A limit or market entry order can arm its own exits. These fields are part of the signed payload, so include them when you compute the signature. Thesl* fields mirror the tp* fields exactly.
string
Take-profit trigger price.
"0" or omitted means no take-profit.string
Execution price used once the take-profit triggers, greater than zero. With a limit
tpOrderType this is the resting price; with a market tpOrderType it is the price to cross to. A market take-profit still requires this price.string
Quantity to close on trigger.
"0" closes the entire position.int
Price source for the trigger:
0 for mark price, 1 for oracle price. No other value is accepted.int
Order type placed when the take-profit triggers:
1 for limit, 2 for market. Required whenever tpPrice is set and must be omitted or 0 when it is not.string
Stop-loss trigger price. Mirrors
tpPrice.string
Execution price once the stop-loss triggers. Mirrors
tpLimitPrice.string
Quantity to close on trigger. Mirrors
tpSize.int
Price source for the stop-loss trigger. Mirrors
tpTriggerType.int
Order type placed when the stop-loss triggers. Mirrors
tpOrderType.userOrders with isConditional: true and isPositionTpsl: true, with tpslParentOrderId pointing at the entry order. A partial fill does not arm them.
Responses
Order submission returns either HTTP 200 with per-order results, or HTTP 202 acknowledging the batch for asynchronous processing. Clients must handle both — do not assume one or the other.- 202 — Accepted
- 200 — Resting
- 200 — Filled
- 200 — Rejected
The batch was accepted for asynchronous processing. No order IDs or fill results are returned inline.Read each order’s outcome from the
orderUpdates channel, correlating by your c (client order ID). The same shape is used by the cancel actions.Response fields
string
"ok" for a synchronous result, "accepted" when the batch was taken for asynchronous processing. Malformed, unauthenticated, or pre-validation failures instead return a top-level status: "error" with a machine code.int
Present on an acknowledgement. Number of orders accepted for processing.
array
Present on a synchronous result. One entry per submitted order, in request order. Each entry is one of:
resting—{ "oid": <int64> }, the order is in the book.filled—{ "oid": <int64>, "totalSz": "<string>", "avgPx": "<string>" }.error— a string explaining why that order was rejected.
Trigger order response
A trigger order settles through the conditional-order path, so its 200 response uses a different shape. Parse the receipt according to whether the order was a trigger order; do not apply thestatuses[] shape to it.
tpsl: "tp" the new order’s ID is in tpOrderId and slOrderId is 0; with tpsl: "sl" the reverse. A 202 acknowledgement is identical to an ordinary order’s.
Retrieving order state
When you receive a 202, and whenever you need lifecycle transitions, read order state from:userOrders— active orders and their IDs.orderUpdatesanduserFills— pushed as resting, fill, and cancel events occur.orderHistory— orders that have already terminated.
Validation sequence
An order is checked in this order, and the first failure is the one reported. Every check runs on the raw integers you submit, so you can reproduce all of it locally before signing.1
Price present and on tick
p must be greater than zero and an exact multiple of the contract’s tickSize. This applies to market orders too. → invalid price2
Price within the book's tick range
p / tickSize must be below the contract’s maxTicks. → price exceeds tick range (maxTicks x tickSize)3
Size present and on step
s must be greater than zero and an exact multiple of stepSize. → invalid size4
Size within range
s must not exceed 2,147,483,647. → size exceeds Integer.MAX_VALUE5
Notional above the floor
price_raw × size_raw × notionalScaleMultiplier must be at least minTradeNtl. → notional below minTradeNtl6
Notional below the cap
The same notional must not exceed
maxPositionNotional. → notional exceeds maxPositionNotional7
Price band (limit orders only)
For a limit order,
|p − mark| must not exceed mark × priceBandBps / 10000. Skipped when priceBandBps is 0 or no mark price exists. Market orders skip this check entirely. → price exceeds priceBandBps8
Margin pre-check
The account must have sufficient margin. For a market order the reserved amount is charged on the full difference between your submitted price and the mark price, without dividing by leverage.
tickSize, stepSize, notionalScaleMultiplier, minTradeNtl, maxPositionNotional, priceBandBps — come from configs for that specific contract. See Notional, and the limits enforced on it for the arithmetic and a worked example.
A market order is executed as IOC regardless of any
tif you supply.Errors
Messages are fixed strings and do not interpolate your values — read the limit that was breached fromconfigs.
For accounts in PORTFOLIO margin mode, margin is drawn from the shared group pool automatically whenever the contract belongs to a share group. You send no group-related fields — the system resolves it from your
marginShareType and the contract’s group membership.