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 related mutually exclusive outcomes may carry neg_risk=true. In the current meme/off-chain deployment, this flag is trading metadata used by the CLOB and clients. Users still place normal orders against the displayed outcome token_id.


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

  • BUY orders: meme collateral must cover size * price + estimated_max_fee
  • SELL orders: outcome share 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 meme balanceFunder lacks meme 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