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.
Order Types
Section titled “Order Types”| Type | Behavior | Use Case |
|---|---|---|
| GTC (Good-Til-Cancelled) | Rests on the book until filled or cancelled | Passive 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 cancelled | All-or-nothing execution |
| FAK (Fill-And-Kill) | Fills as many shares as available immediately, cancels the rest | Partial 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
Section titled “Post-Only Orders”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
CANCELEDwith no partial fills
Tick Sizes
Section titled “Tick Sizes”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 Size | Precision | Example Prices |
|---|---|---|
0.1 | 1 decimal | 0.1, 0.2, 0.5 |
0.01 | 2 decimals | 0.01, 0.50, 0.99 |
0.001 | 3 decimals | 0.001, 0.500, 0.999 |
0.0001 | 4 decimals | 0.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?;Order States
Section titled “Order States”| Status | Description |
|---|---|
LIVE | Order is resting on the book with unfilled size remaining |
MATCHED | Order has been fully filled |
CANCELED | Order 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.
Neg Risk (Multi-Outcome Markets)
Section titled “Neg Risk (Multi-Outcome Markets)”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.
Balance Checks
Section titled “Balance Checks”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)Querying Orders
Section titled “Querying Orders”All query endpoints require L2 authentication.
Get a Single Order
Section titled “Get a Single Order”let order = client.order("ORDER_ID").await?;println!("{:?}", order);REST:
GET /data/order/{order_id}Get Open Orders
Section titled “Get Open Orders”use openfish_client_sdk::clob::types::request::OrdersRequest;
// All open orderslet orders = client.orders(&OrdersRequest::default(), None).await?;println!("{} open orders", orders.data.len());
// Filtered by marketlet request = OrdersRequest::builder() .market("CONDITION_ID".parse()?) .build();let market_orders = client.orders(&request, None).await?;REST:
GET /data/ordersOpenOrder Object
Section titled “OpenOrder Object”| Field | Type | Description |
|---|---|---|
id | string | Order ID (UUID) |
status | string | LIVE, MATCHED, or CANCELED |
market | string | Condition ID |
asset_id | string | Token ID |
side | string | BUY or SELL |
original_size | string | Size at placement |
size_matched | string | Cumulative filled amount |
price | string | Limit price |
outcome | string | Outcome label (e.g., “Yes”, “No”) |
order_type | string | GTC, GTD, FOK, or FAK |
maker_address | string | Funder address |
owner | string | API key of the order owner |
expiration | string | Unix expiration timestamp (0 if none) |
created_at | number | Unix creation timestamp |
Trade History
Section titled “Trade History”Each matched order generates a trade. Trades move through these lifecycle stages:
| Status | Terminal | Description |
|---|---|---|
MATCHED | No | Matched and pending settlement |
MINED | No | Submitted onchain, awaiting finality |
CONFIRMED | Yes | Finalized successfully |
RETRYING | No | Transaction failed, being retried |
FAILED | Yes | Failed 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);}Error Messages
Section titled “Error Messages”| Error | Description |
|---|---|
price {p} violates tick size {t} | Price is not a multiple of the market’s tick size |
insufficient USDC balance | Funder lacks USDC for a BUY order |
insufficient token balance | Funder lacks tokens for a SELL order |
your region is close-only | Geographic restriction: only SELL orders allowed |