Skip to content

Orders Overview

Every order on Openfish is fundamentally a limit order. What people call a “market order” is simply a limit order priced aggressively enough to fill on arrival. Orders are EIP-712 signed payloads matched offchain, with optional onchain settlement.


TypeBehaviorUse Case
GTC (Good-Til-Cancelled)Rests on the book until filled or cancelledPassive limit orders
GTD (Good-Til-Date)Active until a specified expiration timestamp (UTC seconds)Auto-expire before events
FOK (Fill-Or-Kill)Must fill immediately and entirely, or the whole order is cancelledAll-or-nothing execution
FAK (Fill-And-Kill)Fills as many shares as available immediately, cancels the restPartial immediate execution
  • GTC and GTD are resting types — they park on the book at your chosen price until something matches them.
  • FOK and FAK are immediate-execution types that consume resting liquidity.
    • BUY: specify the dollar amount to spend
    • SELL: specify the number of shares to sell

Post-only orders guarantee you act as a maker. Should the order cross the spread and trigger an immediate fill, it is rejected instead.

  • Only valid with GTC and GTD order types
  • Combining post-only with FOK or FAK causes rejection
  • Rejection returns status CANCELED with no partial fills

Each market defines a minimum price increment. An order whose price is not an exact multiple of the tick size is rejected with price {p} violates tick size {t}.

Tick SizePrecisionExample Prices
0.11 decimal0.1, 0.2, 0.5
0.012 decimals0.01, 0.50, 0.99
0.0013 decimals0.001, 0.500, 0.999
0.00014 decimals0.0001, 0.5000, 0.9999

The server validates tick size compliance via price % tick_size == 0 before submitting to the engine. The default tick size is 0.01 (2 decimal places).

// The SDK auto-fetches tick size when building orders.
// To query manually:
let tick = client.tick_size(token_id).await?;

StatusDescription
LIVEOrder is resting on the book with unfilled size remaining
MATCHEDOrder has been fully filled
CANCELEDOrder was cancelled by the user, rejected (post-only crossing), or expired (GTD)

A partially filled order with remaining size stays in LIVE status. The size_matched field tracks how much has been filled so far.


Markets with three or more outcomes rely on the Neg Risk CTF Exchange contract. The neg_risk flag on the market object signals this. The Rust SDK identifies neg risk markets automatically from the token ID and routes orders to the appropriate exchange contract.


Before accepting an order, the server confirms the funder holds enough:

  • BUY orders: USDC collateral must cover size * price + estimated_max_fee
  • SELL orders: Conditional token balance must cover size

Available balance subtracts what is already locked in open orders:

maxOrderSize = balance - SUM(openOrderSize - filledAmount)

All query endpoints require L2 authentication.

let order = client.order("ORDER_ID").await?;
println!("{:?}", order);

REST:

Terminal window
GET /data/order/{order_id}
use openfish_client_sdk::clob::types::request::OrdersRequest;
// All open orders
let orders = client.orders(&OrdersRequest::default(), None).await?;
println!("{} open orders", orders.data.len());
// Filtered by market
let request = OrdersRequest::builder()
.market("CONDITION_ID".parse()?)
.build();
let market_orders = client.orders(&request, None).await?;

REST:

Terminal window
GET /data/orders
FieldTypeDescription
idstringOrder ID (UUID)
statusstringLIVE, MATCHED, or CANCELED
marketstringCondition ID
asset_idstringToken ID
sidestringBUY or SELL
original_sizestringSize at placement
size_matchedstringCumulative filled amount
pricestringLimit price
outcomestringOutcome label (e.g., “Yes”, “No”)
order_typestringGTC, GTD, FOK, or FAK
maker_addressstringFunder address
ownerstringAPI key of the order owner
expirationstringUnix expiration timestamp (0 if none)
created_atnumberUnix creation timestamp

Each matched order generates a trade. Trades move through these lifecycle stages:

StatusTerminalDescription
MATCHEDNoMatched and pending settlement
MINEDNoSubmitted onchain, awaiting finality
CONFIRMEDYesFinalized successfully
RETRYINGNoTransaction failed, being retried
FAILEDYesFailed permanently
use openfish_client_sdk::clob::types::request::TradesRequest;
let trades = client.trades(&TradesRequest::default(), None).await?;
for trade in &trades.data {
println!("{}: {} {} at {}", trade.id, trade.side, trade.size, trade.price);
}

ErrorDescription
price {p} violates tick size {t}Price is not a multiple of the market’s tick size
insufficient USDC balanceFunder lacks USDC for a BUY order
insufficient token balanceFunder lacks tokens for a SELL order
your region is close-onlyGeographic restriction: only SELL orders allowed

  • Create Order — Build, sign, and submit orders -> create
  • Cancel Order — Cancel single, batch, or all orders -> cancel