Skip to content

Order Endpoints

Place Limit Order

POST /orders

Authentication: EIP-712 Order signature

Request Body

{
  "owner_address": "0x...",
  "side": "bid",
  "amount": "1000.0",
  "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 Quantity in natural units (base-token side)
price string Yes Price in natural units (quote per base)
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.

Response

{
  "order_id": "00000000-0000-4000-8000-000000000001"
}

Cancel Order

POST /orders/cancel

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

{
  "status": "ok"
}

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

DELETE /orders/cancel-all

Authentication: API Key required

Query Parameters

Parameter Type Required Description
owner_address address Yes Must match the authenticated API-key owner

Response

{
  "cancelled": ["order-id-1"],
  "failed": [],
  "skipped_cooldown": ["order-id-2"],
  "total": 1
}

total is the number of orders successfully cancelled.

Get Order

GET /orders/{order_id}

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": "399.6", "amount_raw": "399600000" }
    ],
    "fees_paid": [
      { "type": "gas", "token": "USDC", "token_address": "0x...", "amount": "0.42", "amount_raw": "420000" }
    ]
  }
}

Response Notes

  • order_type is limit for limit orders and vl/cancel flows, and swap for orders created through POST /swap.
  • expiration echoes the signed order deadline as a string when present.
  • error_code is a typed terminal failure code. See the error envelope table below for the full public set. Any unrecognised internal failure collapses to TRANSIENT_SETTLEMENT_FAILURE.
  • vl_batch_id is set when the order belongs to a Virtual Liquidity batch.
  • settlement_summary aggregates per-fill settlement progress for the order. latest_failed_fill_failure_reason is a curated, display-oriented revert name for the most recent failed fill (anything outside the public allowlist is returned as null).
  • settlement_economics is the public owner-perspective view of a fill. It contains:
    • gross_debits / gross_credits — the order's gross execution totals (price × quantity), what the owner paid into and received out of the trade before any wallet-side gas adjustment.
    • balance_debits / balance_credits — the actual wallet/vault movement after gas-mode adjustment. For a swap with gas_mode = "receive_less", balance_credits shows the post-gas amount the recipient sees; balance_debits matches gross_debits. For a swap with gas_mode = "pay_more", the relationship inverts.
    • fees_paid — explicit user-visible fees such as gas, with type and token attribution.

It does not expose protocol spread capture or counterparty transfer splits. Use balance_debits / balance_credits for wallet or vault movement displays; use gross_debits / gross_credits for execution-level reporting (P&L, average fill price). - Positive-spread fills can make filled_amount / filled_quote_amount differ from the user's total source-token debit.

External order statuses are:

  • pending — submitted, resting on the book, or partially filled; the order can still receive more fills or be cancelled
  • matched — 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 via settlement_summary) and will not return to pending
  • settled — chain-confirmed terminal success
  • failed — chain-confirmed revert, or pre-broadcast failure / rejection
  • cancelled — terminal cancel

Error Envelope

POST /orders returns a typed envelope on every 4xx failure (including the self-match 409). The wire shape is:

{
  "detail": {
    "detail": "Order placement failed",
    "error_code": "INSUFFICIENT_EQUITY"
  }
}

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
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

GET /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

POST /orders/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

POST /orders/vl/cancel

Authentication: EIP-712 CancelVLBatch signature

Request Body

{
  "owner_address": "0x...",
  "vl_batch_id": "00000000-0000-4000-8000-000000000010",
  "signature": "0x..."
}

Response

{
  "status": "ok"
}

status is the cancellation result and is typically ok.

Get Fills For One Order

GET /fills/{order_id}

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": "99.88", "amount_raw": "99880000" }
        ],
        "fees_paid": [
          { "type": "gas", "token": "EURC", "token_address": "0x...", "amount": "0.12", "amount_raw": "120000" }
        ]
      }
    }
  ]
}

Per-fill settlement_status values:

  • pending — settlement transaction has not been broadcast yet (tx_hash is null)
  • confirming — settlement transaction broadcast and awaiting block confirmations (tx_hash is populated; safe to watch on chain)
  • settled — chain-confirmed terminal success
  • failed — settlement-level failure
  • reverted — 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. Fills may include both maker_order_id and taker_order_id as references, but the response does not expand the counterparty's signed order payload, protocol spread capture, or counterparty transfer split. tx_hash is safe to expose because it is the on-chain settlement transaction reference.

List Fills Across Orders

GET /fills

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": []
      }
    }
  ]
}