Skip to main content
POST
Create new order

Authorizations

X-Monaco-Signature
string
header
required

Ed25519 session-key request signing. Every authenticated request carries three headers: X-Monaco-PublicKey (64-char lowercase-hex session public key), X-Monaco-Timestamp (Unix milliseconds, within 30s of server time), and X-Monaco-Signature (hex ed25519 signature). The signature is over METHOD\npath?query\ntimestamp_ms\nSHA256_hex(body), where the body hash is the SHA-256 of the empty byte string when there is no body. Obtain the session keypair from POST /api/v1/auth/challenge followed by POST /api/v1/auth/verify.

Body

application/json
tradingPairId
string<uuid>
required

Trading pair UUID

Example:

"afae0e16-2d05-4ee9-9ee8-afae0e162d05"

orderType
string
required

Order type: LIMIT or MARKET

Example:

"LIMIT"

side
string
required

Order side: BUY or SELL

Example:

"BUY"

quantity
string
required

Order quantity as decimal string

Example:

"0.5"

price
string | null

Limit price as decimal string (required for LIMIT orders)

Example:

"35000.00"

tradingMode
string | null

Trading mode: SPOT or MARGIN (default: SPOT)

Example:

"SPOT"

slippageToleranceBps
integer<int32> | null

Maximum slippage tolerance in basis points (market orders only)

Required range: x <= 10000
Example:

50

useMasterBalance
boolean | null

Use master account balance for sub-account orders

Example:

false

expirationDate
string | null

Order expiration date (ISO 8601, must be in the future)

Example:

"2026-06-01T00:00:00Z"

timeInForce
string | null

Time in force: GTC, IOC, or FOK. LIMIT orders only; rejected on MARKET orders.

Example:

"GTC"

marginAccountId
string<uuid> | null

Margin account UUID for margin orders

Example:

"123e4567-e89b-12d3-a456-426614174000"

riskBucketId
string<uuid> | null

Existing isolated risk bucket UUID for risk-bucket-scoped margin orders

Example:

"123e4567-e89b-12d3-a456-426614174001"

riskBucketCollateral
string | null

Decimal collateral allocated as an order budget in a new isolated risk bucket. Fills commit their required margin and paid-fee funding to position backing; unfilled or unused order funds do not protect the position from liquidation. Use position margin adjustment to add liquidation protection. The API creates the bucket ID and the matching engine persists it through the durable log.

Example:

"1000"

positionSide
enum<string> | null
deprecated

DEPRECATED compatibility field. Order side is authoritative. When supplied, BUY requires LONG and SELL requires SHORT; NONE is rejected.

Available options:
LONG,
SHORT
Example:

"LONG"

leverage
string | null

Leverage multiplier as a decimal string. Required for normal margin orders; optional and ignored for reduce-only orders.

Example:

"5"

reduceOnly
boolean | null

Whether the margin order is reduce-only

Example:

false

takeProfit
object
stopLoss
object
strategyKey
string | null

Strategy key used to group risk buckets for delegated/margin orders

Example:

"my-strategy"

marginMode
enum<string> | null

Risk bucket mode for margin orders. Defaults to ISOLATED. Values: ISOLATED, CROSS.

Available options:
ISOLATED,
CROSS
Example:

"CROSS"

postOnly
boolean | null

Post-only: reject instead of matching if this limit order would cross the book — rejected with HTTP 400 / gRPC INVALID_ARGUMENT carrying the structured error code POST_ONLY_WOULD_CROSS (REST error-envelope 'code' field; gRPC google.rpc.ErrorInfo reason; batch per-item error.code). Matching the 'post-only order would cross' message substring is a legacy fallback. LIMIT orders with GTC only; rejected on MARKET orders and IOC/FOK.

Example:

false

clientOrderId
string | null

Client-assigned correlation handle, echoed back on order reads (detail and list) and on order WebSocket events. At most 64 characters from [A-Za-z0-9._:-]; surrounding whitespace is trimmed before storage, and a blank or whitespace-only value is treated as absent. Uniqueness is enforced only among your orders that are RESTING on the book: a create or replace reusing a value another of your resting orders still holds is rejected with HTTP 409 / gRPC ALREADY_EXISTS and the code CLIENT_ORDER_ID_CONFLICT. An order that never rests — MARKET, IOC/FOK, or a LIMIT that fills completely on arrival — does not take the handle, and the value is released the moment any order reaches a terminal state. It is therefore NOT an idempotency key: resubmitting after a lost response can execute a second time. Reconcile a lost response against the order WebSocket stream, which carries this value on the submit acknowledgement and on fills, including for orders that never rest; order history is replica-backed and can omit an order that did land. The stream is not replayable and has no sequence number to backfill from, and its fan-out is non-persistent Core NATS: the service can re-establish an ended upstream subscription without closing your socket, so events can be missed while your connection still looks healthy. A matching event is therefore positive proof the order was accepted, but silence is NEVER evidence it was not, and no client-observable condition makes it so. Absent positive evidence the outcome is unresolved: hold and escalate rather than resubmitting. Rejections split in two: one rejected before acceptance (malformed, post-only would cross, handle conflict, a plain MARKET submit with no liquidity, rejected during pricing) fails the request, emits no event and is never written to order history (an order rejected AFTER acceptance is persisted with status REJECTED, so only the pre-acceptance class is absent); an accepted LIMIT with IOC or FOK that cannot fill, or an accepted MARKET order whose apparent liquidity is invalidated by maker-risk revalidation, returns 2xx with matchResult.status REJECTED and emits OrderPlaced then OrderRejected, both carrying this value. A 2xx therefore does not mean the order executed. Where no surface is conclusive, do not resubmit.

Example:

"quote-btc-1130-a"

idempotencyKey
string | null

Optional submission identity, distinct from clientOrderId. Use 1-64 characters from [A-Za-z0-9._:-], without whitespace. Scoped to your authenticated user/subaccount and application, shared by create and batch-create items. Retrying the same key and normalized order payload within 24 hours of the original acceptance returns the original committed submission result, even after a fill or cancellation, without executing again. A full response cache does not prevent new keyed submissions: durable responses may be evicted while exact key history remains retained. If response capacity is protected by pending durability or persistence, a new key is refused with ORDER_SUBMISSION_CAPACITY_EXCEEDED. A retry whose original response cannot currently be retrieved returns ORDER_SUBMISSION_UNAVAILABLE and never executes again. Both are HTTP 503 / gRPC UNAVAILABLE, or per-item errors in batches. Retry the same key and payload; for previously accepted keys, stay within 24 hours of the original acceptance. A capacity refusal does not accept or reserve a new key. Different payload returns IDEMPOTENCY_KEY_CONFLICT (HTTP 409 / gRPC ALREADY_EXISTS; per-item error in batches). Validation failures before acceptance do not reserve the key. The window does not extend on retries; after it expires the key may execute a new order, so never retry an unresolved submission after 24 hours. Generate a fresh key for each intended new order and retain it across transport retries. Without a key, a timeout or 5xx leaves the outcome unknown and must not be blindly retried.

Required string length: 1 - 64
Pattern: ^[A-Za-z0-9._:-]+$
selfTradePreventionMode
enum<string> | null

Per-order self-trade-prevention override: how the engine resolves this order matching against one of your own resting orders (your whole wallet family, subaccounts included; the incoming order's mode governs the step and resting orders' modes are never consulted). CANCEL_MAKER cancels each of your resting orders encountered and keeps matching. CANCEL_TAKER fills third-party liquidity up to the first self-touch, then cancels the incoming order's remainder — a zero-fill CANCELLED outcome is possible. CANCEL_BOTH additionally cancels the encountered resting orders. SKIP trades around your resting orders; a remainder that would rest crossing one of your surviving orders is cancelled instead of resting. Omitted, your wallet's configured default applies, else the platform default CANCEL_MAKER. STP cancellations carry terminalReason SELF_TRADE_PREVENTION and stpCounterpartyOrderId on reads and WebSocket events. With time_in_force FOK: CANCEL_MAKER cancels your makers first and then fills or kills; CANCEL_TAKER and SKIP cancel the whole order when self is in the fill path; CANCEL_BOTH rejects the placement with SELF_TRADE_NOT_ALLOWED. The requested value is echoed back as selfTradePreventionMode on order reads, absent when omitted here.

Available options:
CANCEL_MAKER,
CANCEL_TAKER,
CANCEL_BOTH,
SKIP
Example:

"CANCEL_TAKER"

trailingStop
object | null

Trailing stop attached to this entry order (margin only). Arms only when the order fully fills; cancelled with the order otherwise. One per position.

Response

OK

orderId
string<uuid> | null

Created order UUID

Example:

"123e4567-e89b-12d3-a456-426614174000"

status
string | null

Result status: SUCCESS or FAILED

Example:

"SUCCESS"

message
string | null

Human-readable status message

Example:

"Order created successfully"

matchResult
object
takeProfitOrderId
string<uuid> | null

Created parent take-profit conditional order UUID, when requested

stopLossOrderId
string<uuid> | null

Created parent stop-loss conditional order UUID, when requested

marginAccountId
string<uuid> | null

Resolved margin account UUID for margin orders

riskBucketId
string<uuid> | null

Resolved isolated risk bucket UUID for risk-bucket-scoped margin orders

strategyKey
string | null

Client strategy key carried for compatibility

delegationId
string<uuid> | null

Delegated agent UUID when submitted through a delegated session

trailingStopOrderId
string<uuid> | null

Conditional order id of the trailing stop attached to this entry order, when one was requested