Order Endpoints¶
Preview Limit Order¶
Authentication: None
Use preview before asking a wallet to sign a limit order. The endpoint validates only public market metadata and the submitted order fields. It returns the canonical decimal strings and EIP-712 Order payload that should be signed.
Request Body¶
{
"owner_address": "0x...",
"side": "bid",
"amount": "1000",
"price": "1.085",
"order_type": "limit",
"from_address": "0x...",
"to_address": "0x...",
"order_id": "00000000-0000-4000-8000-000000000001",
"uuid_int": "6427948336465191935941739505432058208337171677044006212075520",
"expiration": 1713254400
}
from_address is the market base token and to_address is the market quote token. side controls which token is spent in the signed Order: a bid spends quote, and an ask spends base.
Response¶
{
"ok": true,
"symbol": "EURC/USDC",
"side": "bid",
"normalized_amount": "1000",
"normalized_price": "1.085",
"amount_step": "0.01",
"price_step": "0.0001",
"rounding_mode": "reject_extra_precision",
"canonicalization_required": false,
"from_token": "0x...",
"to_token": "0x...",
"from_amount": "1085000000",
"to_amount": "1000000000",
"notional": "1085.000000",
"eip712_order": {
"user": "0x...",
"expiration": "1713254400",
"feeBps": "0",
"recipient": "0x0000000000000000000000000000000000000000",
"fromToken": "0x...",
"toToken": "0x...",
"fromAmount": "1085000000",
"toAmount": "1000000000",
"initialDepositAmount": "0",
"uuid": "6427948336465191935941739505432058208337171677044006212075520"
},
"eip712_types": {
"Order": [
{ "name": "user", "type": "address" }
]
}
}
The eip712_types.Order array contains the full Order type; the example is abbreviated for readability. Sign eip712_order exactly as returned, then send the final POST /orders request with the normalized amount and price plus the wallet signature.
Preview does not check balances, available liquidity, account eligibility, or other final submission checks. Those checks happen on final submission.
Place Limit Order¶
Authentication: EIP-712 Order signature
Request Body¶
{
"owner_address": "0x...",
"side": "bid",
"amount": "1000",
"price": "1.085",
"order_type": "limit",
"from_address": "0x...",
"to_address": "0x...",
"order_id": "00000000-0000-4000-8000-000000000001",
"uuid_int": "6427948336465191935941739505432058208337171677044006212075520",
"signature": "0x...",
"expiration": 1713254400
}
| Field | Type | Required | Description |
|---|---|---|---|
owner_address | address | Yes | Wallet address of the order owner |
side | string | Yes | bid or ask |
amount | string | Yes | Canonical quantity string on the market amount_step grid |
price | string | Yes | Canonical price string on the market price_step grid |
order_type | string | Yes | Use limit |
from_address | address | Yes | ERC-20 address of the market base token |
to_address | address | Yes | ERC-20 address of the market quote token (must differ from from_address) |
order_id | UUID string | Yes | Human-readable UUID4 order ID |
uuid_int | decimal string | Yes | Composite uint256 bound to order_id |
signature | hex string | Yes | EIP-712 Order signature |
expiration | integer | Yes | Unix timestamp deadline; must satisfy now < expiration <= now + 365 days - 300 seconds |
client_id and fee_bps are not accepted by the live public API.
from_address and to_address identify the market, not the immediate spend direction. For a bid, you buy from_address using to_address; for an ask, you sell from_address for to_address. Resolve these addresses from GET /tokens.
Decimal strings must use plain fixed-point syntax: no signs, exponents, separators, commas, underscores, or whitespace. Final order placement rejects non-canonical strings and non-zero extra precision before signature verification. Call POST /orders/preview first and submit the normalized amount and price exactly.
Response¶
Cancel Order¶
Authentication: EIP-712 CancelOrder signature
Request Body¶
{
"owner_address": "0x...",
"order_id": "00000000-0000-4000-8000-000000000001",
"uuid_int": "6427948336465191935941739505432058208337171677044006212075520",
"signature": "0x..."
}
uuid_int is required because the signed CancelOrder.orderId field is the composite uint256, not the UUID string.
Response¶
Notes¶
- Orders are subject to a cancel cooldown (default 5 minutes).
- Hitting the cooldown returns
429. - If you lost
uuid_int, fetch the order first; it is returned in order status responses.
Cancel All Orders¶
Authentication: API Key required
Query Parameters¶
| Parameter | Type | Required | Description |
|---|---|---|---|
owner_address | address | Yes | Must match the authenticated API-key owner |
Response¶
total is the number of orders successfully cancelled.
Get Order¶
Authentication: API Key required
Response¶
{
"trade_id": "00000000-0000-4000-8000-000000000001",
"owner_address": "0x...",
"status": "pending",
"order_type": "limit",
"symbol": "EURC/USDC",
"side": "bid",
"base_symbol": "EURC",
"quote_symbol": "USDC",
"base_token": "0x...",
"quote_token": "0x...",
"price": "1.085",
"amount": "1000.0",
"remaining_amount": "600.0",
"filled_base_amount": "400.0",
"filled_quote_amount": "434.0",
"notional": "1085.0",
"remaining_notional": "651.0",
"from_token": "0x...",
"to_token": "0x...",
"from_amount": "1085000000",
"filled_amount": "434000000",
"to_amount": "1000000000",
"created_at": "2026-04-15T08:00:00+00:00",
"updated_at": "2026-04-15T08:01:00+00:00",
"expiration": "1713254400",
"error": null,
"error_code": null,
"uuid_int": "6427948336465191935941739505432058208337171677044006212075520",
"vl_batch_id": null,
"settlement_summary": {
"status": "settled",
"total_fill_count": 1,
"pending_fill_count": 0,
"settled_fill_count": 1,
"failed_fill_count": 0,
"reverted_fill_count": 0,
"latest_settlement_id": 42,
"latest_tx_hash": "0x...",
"latest_parent_status": "confirmed",
"latest_fill_settlement_status": "settled",
"latest_failed_fill_failure_reason": null
},
"settlement_economics": {
"perspective_order_id": "00000000-0000-4000-8000-000000000001",
"gross_debits": [
{ "token": "USDC", "token_address": "0x...", "amount": "434.0", "amount_raw": "434000000" }
],
"gross_credits": [
{ "token": "EURC", "token_address": "0x...", "amount": "400.0", "amount_raw": "400000000" }
],
"balance_debits": [
{ "token": "USDC", "token_address": "0x...", "amount": "434.0", "amount_raw": "434000000" }
],
"balance_credits": [
{ "token": "EURC", "token_address": "0x...", "amount": "400.0", "amount_raw": "400000000" }
],
"fees_paid": []
}
}
Response Notes¶
order_typeislimitfor limit orders andvl/cancelflows, andswapfor orders created throughPOST /swap.expirationechoes the signed order deadline as a string when present.error_codeis a typed terminal failure code. See the error envelope table below for the full public set. Any unrecognised internal failure collapses toTRANSIENT_SETTLEMENT_FAILURE.vl_batch_idis set when the order belongs to a Virtual Liquidity batch.settlement_summaryaggregates per-fill settlement progress for the order.latest_failed_fill_failure_reasonis a curated, display-oriented revert name for the most recent failed fill (anything outside the public allowlist is returned asnull).settlement_economicsis the public owner-perspective view of known fills. It contains:gross_debits/gross_credits— compatibility fields for owner-visible public totals. Do not treat them as raw execution totals or use them to reconstruct values outside the documented response schema.balance_debits/balance_credits— the preferred wallet/vault movement totals for reconciliation and user-facing balance displays.fees_paid— explicit user-visible fees such as gas, withtypeand token attribution.
Use balance_debits / balance_credits for wallet or vault movement displays. fees_paid is a line-item explanation of explicit user-visible fees; do not subtract it again from balance_* totals unless your product intentionally presents a separate cost breakdown. - filled_amount, filled_base_amount, and filled_quote_amount are owner-visible progress values when settlement economics are available. Raw source amount fields such as from_amount are emitted from signed/raw accounting values when available, not recomputed from decimal display price.
External order statuses are:
pending— submitted, resting on the book, or partially filled; the order can still receive more fills or be cancelledmatched— every leg has crossed in the matching engine, but the on-chain settlement is still in flight; the match will settle (or surface a revert reason viasettlement_summary) and will not return topendingsettled— chain-confirmed terminal successfailed— chain-confirmed revert, or pre-broadcast failure / rejectioncancelled— terminal cancel
Error Envelope¶
POST /orders returns a typed envelope on every 4xx failure (including the self-match 409). The wire shape is:
Branch on error_code; the human detail is for display only.
error_code | When it surfaces | Client action |
|---|---|---|
ALLOWANCE_INSUFFICIENT | ERC-20 allowance to the spender insufficient at transfer time, including invalid/expired permit signatures | Re-permit or re-approve and retry |
INTENT_DEADLINE_EXPIRED | Signed order's deadline passed before the tx landed | Replace the order with a fresh deadline |
SLIPPAGE_EXCEEDED | The matching engine killed an IOC/FOK because no crossing liquidity exists at the signed price | Widen slippage and re-submit |
NO_LIQUIDITY | Route has no executable depth at the quoted price | Reduce size or try a different pair |
QUOTE_STALE | Quote/plan snapshot or signed deadline expired before submission | Submit a fresh order |
AMOUNT_BELOW_MIN | Amount is below the pair's configured minimum | Increase amount |
INVALID_PRECISION | amount or price has non-zero digits beyond the market grid | Use the previewed normalized value and retry |
INVALID_DECIMAL_FORMAT | amount or price is not a canonical fixed-point positive decimal string | Reformat as the normalized fixed-point string and retry |
STP_BLOCKED | Self-trade prevention: order would have matched the caller's own resting order on the opposite side | Cancel the resting order or revise the side |
INSUFFICIENT_EQUITY | Caller's available equity for the spent token is below the order's frozen-amount requirement | Deposit more or cancel orders that have it tied up |
PAIR_INACTIVE | Trading pair is not currently active | Use GET /markets to find a tradeable pair |
TRANSIENT_SETTLEMENT_FAILURE | Catch-all for non-actionable infrastructure failures and counterparty-state changes; also the safe default for any unknown internal code | Retry; if it persists, escalate operationally |
GET /orders/{id}.error_code is drawn from the same set; error carries the display-oriented revert reason of the most recent reverted fill (free-form text — use error_code for logic).
List Orders¶
Authentication: API Key required
Query Parameters¶
| Parameter | Type | Default | Description |
|---|---|---|---|
owner_address | address | Required | Must match the authenticated owner |
limit | integer | 50 | Max 500 |
offset | integer | 0 | Pagination offset |
status | string | All | Filter by external status: pending, matched, settled, cancelled, failed. |
type | string | All | swap or limit |
symbol | string | All | Pair label search, for example EURC/USDC |
side | string | All | bid or ask |
from_token | string | All | Filter by resolved from-token address |
to_token | string | All | Filter by resolved to-token address |
base_token | string | All | Filter by base-token address |
quote_token | string | All | Filter by quote-token address |
base_currency | string | All | Legacy query-param name that filters on base_symbol, for example EURC |
quote_currency | string | All | Legacy query-param name that filters on quote_symbol, for example USDC |
trade_ids | string | All | Comma-separated trade ID list |
search | string | All | Free-text search across trade fields |
has_error | boolean | All | true returns only errored trades |
min_price / max_price | string | All | Price range filters |
min_amount / max_amount | string | All | Amount range filters |
min_remaining_amount / max_remaining_amount | string | All | Remaining amount range filters |
min_filled_amount / max_filled_amount | string | All | Filled amount range filters |
min_notional / max_notional | string | All | Notional range filters |
created_after / created_before | string | All | ISO8601 or timestamp-compatible created-at bounds |
updated_after / updated_before | string | All | ISO8601 or timestamp-compatible updated-at bounds |
sort_by | string | created_at | Sort field |
order | string | desc | Sort direction (asc or desc) |
Filters are applied across the full matching trade set before pagination, so total reflects all filtered matches and you can paginate against it directly.
Response¶
Each entry in trades has the same schema as the Get Order response, including base_token / quote_token, full numeric breakdown (remaining_amount, filled_base_amount, filled_quote_amount, notional, remaining_notional), vl_batch_id, settlement_summary, and public-safe settlement_economics. total reflects the count after filtering, not the current page size.
{
"trades": [
{
"trade_id": "00000000-0000-4000-8000-000000000001",
"owner_address": "0x...",
"status": "pending",
"order_type": "limit",
"symbol": "EURC/USDC",
"side": "bid",
"base_symbol": "EURC",
"quote_symbol": "USDC",
"base_token": "0x...",
"quote_token": "0x...",
"price": "1.085",
"amount": "1000.0",
"remaining_amount": "1000.0",
"filled_base_amount": "0",
"filled_quote_amount": "0",
"notional": "1085.0",
"remaining_notional": "1085.0",
"from_token": "0x...",
"to_token": "0x...",
"from_amount": "1085000000",
"filled_amount": "0",
"to_amount": "1000000000",
"created_at": "2026-04-15T08:00:00+00:00",
"updated_at": "2026-04-15T08:00:00+00:00",
"expiration": "1713254400",
"error": null,
"error_code": null,
"uuid_int": "6427948336465191935941739505432058208337171677044006212075520",
"vl_batch_id": null,
"settlement_summary": { "status": "pending", "total_fill_count": 0, "pending_fill_count": 0, "settled_fill_count": 0, "failed_fill_count": 0, "reverted_fill_count": 0, "latest_settlement_id": null, "latest_tx_hash": null, "latest_parent_status": null, "latest_fill_settlement_status": null, "latest_failed_fill_failure_reason": null },
"settlement_economics": {
"perspective_order_id": "00000000-0000-4000-8000-000000000001",
"gross_debits": [],
"gross_credits": [],
"balance_debits": [],
"balance_credits": [],
"fees_paid": []
}
}
],
"total": 1
}
Place VL Batch¶
Authentication: EIP-712 Order signature for every sibling order
Request Body¶
{
"orders": [
{
"owner_address": "0x...",
"side": "bid",
"amount": "100.0",
"price": "0.75",
"order_type": "limit",
"from_address": "0x...",
"to_address": "0x...",
"order_id": "00000000-0000-4000-8000-000000000010",
"uuid_int": "6427948336465191935942058520151046588146668590738473494773760",
"signature": "0x...",
"expiration": 1713254400
},
{
"owner_address": "0x...",
"side": "bid",
"amount": "100.0",
"price": "0.80",
"order_type": "limit",
"from_address": "0x...",
"to_address": "0x...",
"order_id": "00000000-0000-4000-8000-000000000011",
"uuid_int": "6427948336465191935942079787798979146800635051651437980286977",
"signature": "0x...",
"expiration": 1713254400
}
]
}
VL Validation Rules¶
| Rule | Description |
|---|---|
| Batch size | 2 to 50 orders (active cap returned at runtime by GET /config under limits.vl_batch) |
| Same owner | All siblings must share one owner_address |
| Same spent token | All siblings must resolve to the same fromToken |
| Unique markets | Exact duplicates and inverse pairs are rejected |
| Shared group | All uuid_int values must share the same VL group_id |
| Sequential legs | leg_id values must be 0, 1, 2, ... in array order |
Each sibling uses the same request semantics as POST /orders: from_address is the market base token, to_address is the quote token, and expiration is required.
Response¶
{
"order_ids": [
"00000000-0000-4000-8000-000000000010",
"00000000-0000-4000-8000-000000000011"
],
"amendments": [
{
"order_id": "00000000-0000-4000-8000-000000000011",
"original_amount": "100.0",
"actual_amount": "62.5",
"reason": "budget_clip"
}
],
"cancelled": [],
"fills": [
{
"order_id": "00000000-0000-4000-8000-000000000010",
"trades": [
{ "quantity": "25", "price": "0.40", "counterparty_order_id": "0x...", "ts": 1713254400 }
],
"remaining": "75"
}
],
"vl_group": {
"primary_id": "00000000-0000-4000-8000-000000000010",
"max_budget": "80",
"budget_consumed": "10",
"spent_token": "USDC"
}
}
| Field | Description |
|---|---|
order_ids | Every leg's order_id in submission order. Always populated. |
amendments | Legs the matching engine clipped at placement so they fit the shared max_budget. The user signed for original_amount but the order rests at actual_amount. reason is "budget_clip". |
cancelled | Legs the matching engine dropped because the budget was already exhausted by an earlier-priority sibling. reason is "quota_exceeded". |
fills | Immediate fills that landed at placement time (a leg crossing multiple makers produces multiple trades[] entries). This is success, not rejection — remaining is the leg's left_amount after the immediate fills. |
vl_group | Authoritative budget snapshot: max_budget − budget_consumed is what future fills can still draw from. spent_token is the shared fromToken symbol. |
amendments, cancelled, and fills are empty lists when every leg rests at its signed size with no immediate fill. Older clients ignoring these fields keep their existing order_ids-only contract.
Cancel VL Batch¶
Authentication: EIP-712 CancelVLBatch signature
Request Body¶
{
"owner_address": "0x...",
"vl_batch_id": "00000000-0000-4000-8000-000000000010",
"signature": "0x..."
}
Response¶
status is the cancellation result and is typically ok.
Get Fills For One Order¶
Authentication: API Key required
Query Parameters¶
| Parameter | Type | Default |
|---|---|---|
limit | integer | 100 |
offset | integer | 0 |
Response¶
{
"items": [
{
"maker_order_id": "maker-order-id",
"taker_order_id": "taker-order-id",
"quantity": "100.0",
"price": "0.75",
"settlement_status": "pending",
"tx_hash": null,
"timestamp": "2026-04-15T08:00:00+00:00",
"failure_reason": null,
"settlement_economics": {
"perspective_order_id": "taker-order-id",
"gross_debits": [
{ "token": "USDC", "token_address": "0x...", "amount": "75.0", "amount_raw": "75000000" }
],
"gross_credits": [
{ "token": "EURC", "token_address": "0x...", "amount": "100.0", "amount_raw": "100000000" }
],
"balance_debits": [
{ "token": "USDC", "token_address": "0x...", "amount": "75.0", "amount_raw": "75000000" }
],
"balance_credits": [
{ "token": "EURC", "token_address": "0x...", "amount": "100.0", "amount_raw": "100000000" }
],
"fees_paid": []
}
}
]
}
Per-fill settlement_status values:
pending— settlement transaction has not been broadcast yet (tx_hashisnull)confirming— settlement transaction broadcast and awaiting block confirmations (tx_hashis populated; safe to watch on chain)settled— chain-confirmed terminal successfailed— settlement-level failurereverted— per-leg revert inside the on-chain batcher; the parent settlement transaction may still have succeeded
failure_reason, when present, is one of a fixed allowlist of decoded contract revert names. Anything outside that allowlist is returned as null so the field shape stays a closed set.
Fill-level settlement_economics uses the same public-safe owner perspective as orders. Fill price is the public owner-effective price when accounting provides it. Fills may include both maker_order_id and taker_order_id as references. tx_hash is safe to expose because it is the on-chain settlement transaction reference.
List Fills Across Orders¶
Authentication: API Key required
Query Parameters¶
| Parameter | Type | Default | Description |
|---|---|---|---|
owner_address | address | Required | Must match the authenticated owner |
order_status | string | All | pending, matched, settled, cancelled, failed |
settlement_status | string | All | pending, confirming, settled, failed, reverted |
limit | integer | 100 | Max 500 |
offset | integer | 0 | Pagination offset |
Response¶
{
"items": [
{
"maker_order_id": "maker-order-id",
"taker_order_id": "taker-order-id",
"quantity": "100.0",
"price": "0.75",
"settlement_status": "pending",
"tx_hash": null,
"timestamp": "2026-04-15T08:00:00+00:00",
"failure_reason": null,
"settlement_economics": {
"perspective_order_id": "taker-order-id",
"gross_debits": [],
"gross_credits": [],
"balance_debits": [],
"balance_credits": [],
"fees_paid": []
}
}
]
}