Placing orders

How matching works: frequent batch auctions

MNX does not match orders the instant they arrive. Orders are collected into short batches and matched at discrete intervals (about every 200ms) — a Frequent Batch Auction (FBA). Each batch clears at a single uniform clearing price: the price that maximizes matched volume, applied to every trade in the batch. Orders eligible on each side are allocated pro rata (proportionally to their remaining size) rather than by queue position.

Practical consequences for an API client:

The place-order request

POST /v0/orders (authenticated). The order must carry an EIP-712 signature — see Authentication & signing. A representative limit order:

POST /v0/orders
{
  "market_id": 1,
  "side": "LONG",
  "order_type": "LIMIT",
  "price": 2000,
  "quantity": 0.5,
  "leverage": 2,
  "expiration_seconds": 0,
  "salt": "123456789",
  "signature": "0x...",
  "signature_type": 1
}
FieldMeaning
market_idThe market to trade, from GET /v0/markets.
sideLONG (buy) or SHORT (sell).
order_typeMARKET, LIMIT, or a conditional type (below).
priceLimit price in human units (omit or 0 for market orders). Must be a multiple of the market's tick size (the smallest price increment).
quantity / usd_amountOrder size in base units, or a USD budget from which the server computes the quantity. Quantity must be a multiple of the step size and at least the minimum order size.
leveragePosition leverage — how many dollars of exposure per dollar of margin (collateral) you put up. A positive whole number, capped by the market's maximum; defaults to 1.
expiration_secondsUnix timestamp (in seconds) after which the order expires, or 0 for good-til-canceled.
trigger_priceRequired for conditional order types.
reduce_onlyIf true, the order may only shrink an existing position, never open or grow one.
salt, signature, signature_typeThe EIP-712 signature material; the salt and expiration must match the values signed into the order struct.

The server validates the signature, checks the order against the market's parameters (tick size, step size, minimum and maximum order size, leverage cap, and price bands around the oracle price), and reserves margin for it. Orders that open or increase a position reserve full margin up front; orders that close an existing position reserve no margin, since they reduce exposure. The exact market parameters are returned by GET /v0/markets.

Two helper endpoints let you pre-check an order: POST /v0/orders/calculate-quantity (size an order from a USD budget, including an estimated clearing price) and POST /v0/orders/estimate (estimate the exact quantity, cost, fees, clearing price, margin health, and any required automatic top-up, while also returning available_margin, max_quantity, and max_notional from the same live snapshot). Send size: 0 when only maximum sizing is needed; limit-order estimates still require price.

Order types

Beyond MARKET and LIMIT, six conditional types wait for the market's mark price (used for unrealized profit and loss and conditional triggers) to cross a trigger before entering the matching pipeline:

TypeExecutes asReduce-only
STOP_MARKET / STOP_LIMITMARKET / LIMITOptional
TAKE_PROFIT_MARKET / TAKE_PROFIT_LIMITMARKET / LIMITAlways
STOP_LOSS_MARKET / STOP_LOSS_LIMITMARKET / LIMITAlways

Conditional orders rest with status PENDING_TRIGGER and reserve margin up front like any other order. Triggers are evaluated after each mark-price update. Stop and stop-loss orders trigger when the mark price moves against the order's direction (mark ≥ trigger for a buy, mark ≤ trigger for a sell); take-profit orders trigger on the favorable crossing (mark ≤ trigger for a buy, mark ≥ trigger for a sell). On trigger, the order becomes a regular market or limit order with status OPEN and enters the next batch.

The response

A successful placement returns the accepted order — including its order_id and order_hash, which you need for cancels and status reads — plus a fills array, an updated balance snapshot when available, and a read_after bookmark you can pass to subsequent reads for read-your-own-writes consistency (see Getting started). Because matching happens at the next batch, expect fills to arrive after placement, not in it.

Cancelling orders

Cancel responses include an is_duplicate flag: retrying a cancel that already succeeded is safe and reports itself as a duplicate rather than failing.

Reading order status and fills

Order status is one of OPEN, FILLED, CANCELLED, EXPIRED, PENDING_TRIGGER, or CANCEL_PENDING_FINALIZE (a cancel accepted while a batch containing the order is settling).

For push-based updates instead of polling, subscribe to your user topic on the WebSocket feed — see WebSockets.