POST /v1/orders. This page covers exactly what to sign and how to compute the
amounts so the matching engine accepts your order.
EIP-712 domain
verifyingContract is the market’s ctf_exchange_address — read it from the
market object. Do not hard-code it; it can differ per chain.
The Order struct
The typed-data primary type is Order, with these 12 fields in this order:
The order kind (
LIMIT / MARKET / GTD) is not part of the signed
struct — it travels on the REST request body only as order_type. The signed
struct carries side as a number, not the human-readable string.Outcome → token
Pick thetoken_id for the outcome you want from
GET /v1/markets/{condition_id}/tokens:
outcome: 1 and the YES token_id.
Prices are 2-decimal ticks
A price is a YES probability in[0.01, 1.00], quantized to 2 decimal places
(100 ticks). Sign at sub-tick precision and the on-chain crossing check can
reject the match, so round first:
Amount math
Readdecimals from the market’s /tokens response (18 on BSC). Then, with
price (already quantized) and size as decimal strings:
decimals. BUY ceils the
collateral and SELL floors it — this asymmetric rounding is what keeps the
on-chain crossing check satisfied. It costs at most 1 wei.
Complete example (viem)
Submit the order
The request body wraps the signed struct in snake_case, plus the human-readableorder_type, outcome, price, and size:
status: OPEN for accepted orders — matching is asynchronous:
Each item in
results[] is either a success or an inline
{ "error": { "code", "message" } }. A mixed array is normal — always inspect
every item. Fills and status transitions arrive on the
user WebSocket channel, not here.Idempotency
Set anfs-idempotency-key header on POST /v1/orders to make retries safe.
Replaying the same key + same body returns the cached result with
_idempotent_replayed: true. The same key + a different body returns
IDEMPOTENCY_CONFLICT (409). Idempotency is honored on order placement only.
Cancelling
POST /v1/orders/cancel— cancel by hash (up to 100), by filter (condition_id+chain_id+ optionaloutcome/side), or all (empty body).POST /v1/orders/{order_hash}/cancel-onchain— returns unsigned calldata for a hard on-chain cancel against the CTF Exchange. You submit and pay for that transaction yourself; the backend does not send it.