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 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.
Balance Checks
Section titled “Balance Checks”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)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 meme balance | Funder lacks meme 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 |