Skip to main content
POST
Create TWAP 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"

side
string
required

Order side: BUY or SELL

Example:

"BUY"

quantity
string
required

Total quantity to execute across the window as decimal string. Must be at least 2x the pair's minimum order size so it can be sliced, and small enough that the window's slice budget can carry it with every child at or below the pair's maximum order size.

Example:

"10"

durationSeconds
integer<int64> | null

Execution window length in seconds from launch. Exactly one of durationSeconds or endTime must be set. Bounds (env-tunable defaults): 60 to 2592000 (1 minute to 30 days).

Example:

3600

startTime
string | null

Window start (RFC 3339, UTC only — use a Z suffix; non-UTC offsets are rejected). Only valid together with endTime; defaults to now.

Example:

"2026-08-01T10:00:00Z"

endTime
string | null

Window end (RFC 3339, UTC only — use a Z suffix; non-UTC offsets are rejected). Exactly one of durationSeconds or endTime must be set. The effective window must satisfy the same duration bounds. Execution stops hard at this time; any unfilled remainder is reported as shortfall.

Example:

"2026-08-01T11:00:00Z"

limitPrice
string | null

Optional parent-level limit price as decimal string. BUY child orders never execute above it, SELL children never below it. Omitted: slippage band protection only.

Example:

"35000.00"

slippageToleranceBps
integer<int32> | null

Per-slice protective price band in basis points around the reference price (default 100 = 1%, maximum 500 = 5% — deliberately tighter than the standalone market-order cap; TWAP slices never sweep deep)

Required range: x <= 500
Example:

100

randomize
boolean | null

Apply seeded randomization to slice sizes and timing (default true). The seed is recorded for audit, so the schedule is reproducible to compliance but unpredictable to the market.

Example:

true

reduceOnly
boolean | null

Whether the TWAP parent is reduce-only (margin only). Child orders inherit it and clamp to the live position.

Example:

false

tradingMode
string | null

Trading mode: SPOT or MARGIN (default: SPOT)

Example:

"SPOT"

marginAccountId
string<uuid> | null

Margin account UUID for margin TWAP orders. Resolved once at creation and reused by every child order.

Example:

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

riskBucketId
string<uuid> | null

Existing isolated risk bucket UUID for risk-bucket-scoped margin TWAP orders. Snapshot at creation.

Example:

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

marginMode
enum<string> | null

Risk bucket mode for margin TWAP orders. Defaults to ISOLATED. Values: ISOLATED, CROSS. On an isolated-only market (TradingPairData.isolated_only) a CROSS order that is not reduce-only is rejected with HTTP 400 / gRPC INVALID_ARGUMENT carrying the structured error code CROSS_MARGIN_NOT_ALLOWED. One margin mode per market and margin account: while the account holds the pair in its other risk bucket (an open position, or a resting order that is not reduce-only), an order that is not reduce-only is rejected with HTTP 400 / gRPC INVALID_ARGUMENT carrying the structured error code MARGIN_MODE_CONFLICT; reduce-only orders always pass, so a pair already held in both modes can be reduced on either side until one closes.

Available options:
ISOLATED,
CROSS
Example:

"CROSS"

leverage
string | null

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

Example:

"5"

strategyKey
string | null

Strategy key used to group risk buckets for margin orders

Example:

"my-strategy"

useMasterBalance
boolean | null

Use master account balance for sub-account orders

Example:

false

clientTwapId
string | null

Client-assigned idempotency key (max 36 chars), unique per user and application. A duplicate is rejected with 409.

Example:

"oms-3f6a1c"

executionStyle
enum<string> | null

Child execution style. TAKER (default): each slice executes immediately as a banded MARKET order. PASSIVE: each slice rests as a post-only limit at the same-side touch (maker where possible, repriced to follow the touch, never beyond the parent limit price or the protective band), and the leftover is swept as a banded MARKET order at the slice deadline. Passive parents use a slower default slice cadence (~60s).

Available options:
TAKER,
PASSIVE
Example:

"PASSIVE"

triggerPrice
string | null

Price-triggered activation: the parent waits (PENDING) until the reference price reaches or crosses this price in triggerDirection, then runs a floating window of durationSeconds from the trigger instant. Requires triggerDirection and durationSeconds; incompatible with startTime/endTime. Rejected if the condition is already met at creation. Margin markets arm against the oracle mark and the create is rejected while the market has no mark yet (retry once one is published); once the parent is waiting, activation evaluates the mark when it is available and the venue reference price (book-derived median, last-trade fallback) when it is not, so a mark outage cannot leave a live trigger unwatched. Spot markets use the venue reference price throughout.

Example:

"98000.00"

triggerDirection
enum<string> | null

Which way the reference price must cross triggerPrice to activate: ABOVE (activate when price rises to or through it) or BELOW (falls to or through it). Required with triggerPrice; no exact print is required — a reference price observed at or beyond the level activates. The condition is evaluated on the engine's own polling cadence rather than on every market tick, so a price that crosses and reverts entirely between two observations is not seen; there is no high/low watermark.

Available options:
ABOVE,
BELOW
Example:

"BELOW"

conditionalExpiry
string | null

Deadline for the trigger to fire (RFC 3339, UTC only — Z suffix; non-UTC offsets rejected). If the trigger has not fired by then the parent cancels with terminal reason 'trigger expired'. Only valid with triggerPrice; must be in the future and at most the maximum window (default 30 days) from creation, which is also the default when omitted.

Example:

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

Response

OK

twapOrderId
string<uuid> | null

Created TWAP parent order UUID

Example:

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

status
string | null

Result status: SUCCESS or FAILED. SUCCESS means the parent is durably recorded; execution itself is best-effort within the window.

Example:

"SUCCESS"

message
string | null

Human-readable status message

Example:

"TWAP order created successfully"

state
string | null

Initial parent state: always PENDING at create. An unconditional parent activates on its first attempted slice; a conditional one (triggerPrice set) stays PENDING until its trigger fires.

Example:

"PENDING"

marginAccountId
string<uuid> | null

Resolved margin account UUID for margin TWAP orders

riskBucketId
string<uuid> | null

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

plannedSlices
integer<int32> | null

Number of slices in the planned schedule

Example:

120

firstSliceAt
string | null

Planned time of the first slice (ISO 8601). PROVISIONAL for a conditional parent (triggerPrice set): its window floats from the trigger instant, which is unknown at create, so this is computed from the provisional [create, create + durationSeconds] window and is re-anchored when the trigger fires. Read the armed window back from the TWAP read model (startAt / endAt / triggeredAt) instead of scheduling on this value.

Example:

"2026-08-01T10:00:27Z"

endTime
string | null

Resolved window end (ISO 8601). Execution never continues past it. PROVISIONAL for a conditional parent (triggerPrice set) for the same reason as firstSliceAt: the real window is [trigger instant, trigger instant + durationSeconds] and is re-anchored on activation.

Example:

"2026-08-01T11:00:00Z"