Skip to main content
The 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.
Every order requires a price. p is mandatory for market orders as well as limit orders — the matching price is the price you submit. The server does not compute a marketable price for you. A missing p returns 400 INVALID_PARAM with errors[0].reason MISSING_PARAM.

Endpoint

Request

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

Set the envelope field sync (outside action, not signed) to choose the response form; see Response.
boolean
sync — Envelope-level, beside action. true returns HTTP 200 with a result per order; false returns HTTP 202 and the results arrive on orderUpdates. When omitted, the server default applies. Must be a JSON boolean. See Synchronous and asynchronous responses.
string
required
type (required) — Fixed value: "order".
array
required
orders (required) — Array of order objects. Maximum 10 per request; more returns BATCH_TOO_LARGE.
string
grouping — 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 the orders array uses compact single-letter keys.
int32
required
a (asset) (required) — The integer contract ID identifying which perpetual to trade.
boolean
required
b (isBuy) (required) — true to buy/go long; false to sell/go short.
string
required
p (price) (required) — 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 isMarket is false, or the execution price when it is true.
Must be greater than zero and aligned to the contract’s tickSize. A missing, zero, or misaligned price is rejected.
string
required
s (size) (required) — Order quantity as a raw integer string. Must be positive.
boolean
r (reduceOnly) — true restricts the order to reducing an existing position. Omitting the field is equivalent to false.
object
required
t (orderType) (required) — Selects limit, market, or trigger behavior. See Order types.
string
c (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, and to correlate asynchronous results.Only decimal digits (0–9) are accepted, at most 20 bytes, within the int64 range. Hexadecimal, UUID, 0x-prefixed, or signed strings return 400 INVALID_PARAM with errors[].reason INVALID_FORMAT; a value outside int64 returns OUT_OF_RANGE. Omitting the field or sending "" sets no client order ID. Do not use 0 — an unset client order ID is reported as "0", so an order placed with 0 cannot be told apart from one with none.
string
builderAddress (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 (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 server 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 crosses triggerPx, the server places the order described by the remaining fields.
string
required
trigger.triggerPx (required) — Trigger price as a raw integer string, greater than zero. Evaluated against the mark price.
boolean
required
trigger.isMarket (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
trigger.tpsl (required) — "tp" or "sl". Sets the direction of the trigger comparison, matching the convention used by tpSl.
Constraints and behavior:
  • Single order only. Trigger orders are valid when orders has exactly one element. A batch containing one is rejected with 400 BAD_REQUEST.
  • The trigger price is always evaluated against the mark price; no other price source can be selected.
  • A trigger order can carry inline tp* / sl* fields. On a trigger order they define the take-profit and stop-loss of the order placed after the trigger fires — not when the trigger order itself fires, which is trigger.triggerPx. The fields and rules are the same as for an entry order; see Inline take-profit and stop-loss.
  • The same field names mean something different on tpSl: there tpPrice is the conditional order’s own trigger price, and the TP/SL of the order placed after it fires is openTpPrice / openSlPrice. Read each action’s field table separately.
  • The response differs from an ordinary order — see Trigger order response.
  • A resting trigger order appears in userOrders with isConditional: true, an orderType of TPM / TPL / SM / SL, and its triggerPrice. On the orderUpdates channel it carries the compact cond: true flag.
  • Cancel it with cancelConditional, passing the tpOrderId / slOrderId from the trigger order response, or with cancelTpSl; there is no dedicated cancel action.

Inline take-profit and stop-loss

A limit, market, or trigger order can arm its own exits. These fields are part of the signed payload, so include them when you compute the signature. The sl* fields mirror the tp* fields exactly.
string
tpPrice — Take-profit trigger price. "0" or omitted means no take-profit.
string
tpLimitPrice — 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
tpSize — Quantity to close on trigger. "0" closes the entire position.
int
tpTriggerType — Price source for the trigger: 0 for mark price, 1 for oracle price. No other value is accepted.
int
tpOrderType — 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
slPrice — Stop-loss trigger price. Mirrors tpPrice.
string
slLimitPrice — Execution price once the stop-loss triggers. Mirrors tpLimitPrice.
string
slSize — Quantity to close on trigger. Mirrors tpSize.
int
slTriggerType — Price source for the stop-loss trigger. Mirrors tpTriggerType.
int
slOrderType — Order type placed when the stop-loss triggers. Mirrors tpOrderType.
Inline TP/SL applies to single-order requests only. In a batch of two or more, every order’s tp* / sl* fields are ignored. A reduce-only order must not carry them — the whole order is rejected if it does.
Once the entry order is completely filled, the armed levels become conditional orders bound to the resulting position. They appear in userOrders with isConditional: true and isPositionTpsl: true, with tpslParentOrderId pointing at the entry order. A partial fill does not arm them.

Response

Order submission returns either HTTP 200 with per-order results (sync: true), or HTTP 202 acknowledging the request for asynchronous processing (sync: false). Without sync the server default decides, so clients must handle both. A request that fails parameter validation returns 400 INVALID_PARAM in either mode and is not submitted.
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. count is always 1 — one request accepted — even when orders[] holds several orders; do not use it to check the batch size.

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 a 202 acknowledgement. Always 1: it acknowledges the request, not the number of orders in it.
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.
A top-level "status": "ok" does not mean every order succeeded. Inspect each element of statuses — a rejected order appears there as an error entry alongside successful siblings.

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 the statuses[] shape to it.
With 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:

Price and size constraints

Check these against configs for the contract before signing. A failure is reported in that order’s statuses[] entry, or on the orderUpdates channel for a 202.
  • Price. p must be greater than zero and an exact multiple of tickSize, for market orders as well as limit orders, and must stay within the contract’s tick range (price exceeds tick range (maxTicks x tickSize)).
  • Size. s must be greater than zero and an exact multiple of stepSize.
  • Price band. priceBandBps (denominator 1e4) limits only the aggressive direction: a limit buy priced above the mark price, or a limit sell priced below it, by more than the band is rejected. A buy below or a sell above the mark price is not limited by the band.
  • Minimum notional. A non-reduce-only order whose notional value is below the top-level minNotionalValue is rejected. notionalScaleMultiplier converts price × size into notional.
  • Size and position caps. maxOrderSize caps the size of one non-reduce-only order; maxPositionSize caps the position that results from it.
See Notional, and the limits enforced on it for the arithmetic.
A market order is executed as IOC regardless of any tif you supply.

Errors

Order rejections

These appear as the error string of the order’s statuses[] entry (HTTP 200), or on orderUpdates after a 202. Messages are fixed strings and do not interpolate your values — read the limit that was breached from configs.

HTTP errors

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.