Skip to main content
POST
cURL

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.

Path Parameters

marginAccountId
string
default:2b1a5f9c-0000-4000-8000-000000000001
required

Margin account UUID for the isolated bucket being simulated.

Body

application/json
marginAccountId
string | null

Margin account UUID for the isolated bucket being simulated.

tradingPairId
string<uuid> | null
side
string | null
positionSide
string | null

Deprecated compatibility value. side is authoritative; when present, BUY must carry LONG and SELL must carry SHORT.

orderType
string | null
price
string | null
quantity
string | null
leverage
string | null

Required for normal orders; optional and ignored for reduce-only.

reduceOnly
boolean | null
slippageToleranceBps
integer<int32> | null

MARKET only: client slippage tolerance in basis points, 0..1000, the same rule placement enforces — a LIMIT or IOC preview carrying it is rejected. Tightens the previewed walk to the band the real order will run under and never widens it; omit for the placement default.

Required range: x <= 1000

Response

OK

accepted
boolean | null
rejectReason
string | null
equityAfter
string | null
initialMarginRequiredAfter
string | null
maintenanceMarginRequiredAfter
string | null
freeCollateralAfter
string | null
estimatedFee
string | null

What this order pays in fees once its WHOLE size has executed, priced by the role each part of it plays against the book right now: the taker rate (plus the application's additional taker fee) on the quantity that would cross immediately, and the maker rate on the quantity that would rest and be filled later. Both rates are the caller's own tier-resolved rates. One figure covers both cases — an order that crosses entirely, one that rests entirely, and every split in between.

Signed: NEGATIVE means a net rebate, which is the honest answer for a resting order on a pair whose maker fee is negative. Populated even when accepted is false, and populated for reduce-only orders — closing a position pays fees like any other fill.

It assumes the resting part eventually fills, so it states what the order costs if it runs to completion, not a probability-weighted figure: cancel before the remainder fills and only the crossing part was ever charged.

ABSENT — never zero — when the engine could not price the order: it was refused before it could be matched, or its resolved maker tier exceeds the pair's cap. Absence means unknown, so do not render it as a free order.

estimatedLiquidationPrice
string | null

Estimated liquidation mark-price. In ISOLATED mode, this is the position/risk-bucket threshold. In CROSS mode, it is conditional: it varies only the target position's mark while all other marks in the cross risk bucket remain unchanged. Other position marks, funding, realized PnL, fees/reserves, and collateral can change it. Treat an absent or blank value as unavailable, never as zero.

marginAccountId
string | null

The margin account the simulation was resolved against. Always populated; useful for auto-resolved buckets where the caller didn't supply the id.

strategyKey
string | null

Populated when the simulated account is an auto-resolved bucket.

riskBucketId
string | null

Present when the simulation resolved against a risk bucket.

marginMode
string | null

Present when the simulation resolved against a risk bucket. Values: ISOLATED, CROSS.

selectedTradingPairIds
string<uuid>[] | null

The cross scope the preview ran against; absent for isolated previews and never a request's deprecated list. SimulateRiskBucketOrderRisk in CROSS mode reports the DERIVED scope: the active cross bucket's recorded pairs (a pair whose positions have closed stays recorded until a later cross order on another pair reconciles the bucket), every pair with an open position in that bucket, and the previewed pair — the previewed pair alone before the first cross order. SimulateOrderRisk and SimulateParentMarginOrderRisk report the recorded pairs plus the previewed pair.

Minimum string length: 1
expectedMatchResult
object | null

The simulated match the engine ran to admit this order (0XM-2746): the same MatchResult shape CreateOrderResponse.match_result carries for a real placement, produced by the same simulate_match_with_stp walk over the live book at the moment of the preview — under the caller's slippage_tolerance_bps merged tighter-wins with the mandatory 1,000 bps protective band, the caller's own self-trade-prevention default (the preview runs under the caller's wallet, as placement does) and reduce-only sizing. Not a handler-side re-walk of an orderbook snapshot, so a preflight and the placement it precedes read the same numbers — the reason this rides the risk simulation rather than a separate quote endpoint. What a preview cannot carry: a post-only flag, TP/SL legs and a per-order self-trade-prevention override, so a post-only placement that would cross is refused by placement, not by this preview.

Fields: total_filled is what the walk fills; remaining_quantity what it could NOT fill inside the merged band — the partial-fill / band-cut indicator (0 means the whole size executes; a MARKET preview with a non-zero remainder comes back partially filled when placed); average_fill_price is the quantity-weighted fill price and execution_price_range.worst_price the worst level reached (highest ask a BUY takes, lowest bid a SELL hits), both absent when nothing crosses; status is the status placement would end in: FILLED for a full fill, CANCELLED for a MARKET order the band or the depth cuts short (a MARKET remainder cannot rest, so the fills execute and the rest is cancelled — read remaining_quantity for the partial fill), SUBMITTED for a LIMIT that rests, PARTIALLY_FILLED for a LIMIT that crosses partly and rests the remainder; actual_slippage_bps the realized slippage against reference_price as the engine computes it for a placement, absent when nothing crosses; max_slippage_bps echoes the caller's tolerance, not the merged band. A LIMIT preview that would rest reports 0 filled, the full size remaining and no prices.

For a LIMIT or IOC preview the engine measures slippage against the LIMIT price and reports none when every fill improved on it, exactly as the placement's match_result does; reference_price below is therefore published for MARKET previews only.

Priced against the book RIGHT NOW. For a take-profit / stop-loss the close runs later, on a different book, under the wider 1,200 bps band the engine stamps on a triggered market leg and anchored at trigger time — so for a TP/SL estimate apply actual_slippage_bps to the TRIGGER price as an impact figure rather than displaying this call's absolute average price. Fees for this walk are estimated_fee above, at the caller's own tier, which can lag the engine's copy by one refresh interval.

PRESENT ONLY when accepted is true. Absent — never zeros — on every refused preview (accepted: false with a reject_reason): validation, an unknown market or account, insufficient margin, a maker-risk constraint, a MARKET order with nothing fillable inside the band, and the post-match maker-risk revalidation, whose match the engine discards. Such previews may still carry estimated_fee, which is priced independently of risk state. Treat absence as unknown, not as "fills at zero".

referencePrice
string | null

The touch on the taking side when a MARKET preview ran (best ask for a BUY, best bid for a SELL) — what expectedMatchResult's walk and its actualSlippageBps are measured from. Present only when accepted is true and the preview is a MARKET order; a LIMIT or IOC preview is measured against its own limit price and publishes nothing here.

Example:

"100.25"