Orders
Guide for placing and cancelling orders through o2 SDKs.
Use the SDK when one is available for your language. The SDK handles session signing, nonce handling, market lookup, precision scaling, and request submission. Use the raw API examples only when you are building your own client or need lower-level control.
For endpoint-only reference, see POST /v1/session/actions. For the full session model, see Session Keys and Authentication & Signing.
Create Order
Create an order with the SDK first. Prices and quantities are human-readable strings in the SDK examples; the SDK scales them to the integer values expected by the API.
// Requires an active session for the market.
const result = await client.createOrder("fFUEL/fUSDC", "buy", "1", "5");
console.log("Order tx:", result.txId);
if (result.orders?.length) {
console.log("Order ID:", result.orders[0].order_id);
}# Requires an active session for the market.
from o2_sdk import OrderSide, OrderType
result = await client.create_order(
market="fFUEL/fUSDC",
side=OrderSide.BUY,
price="1",
quantity="5",
order_type=OrderType.SPOT,
)
print(f"Order tx: {result.tx_id}")
if result.orders:
print(f"Order ID: {result.orders[0].order_id}")// Requires an active session for the market.
use o2_sdk::{OrderType, Side};
let result = client
.create_order(
&mut session,
"fFUEL/fUSDC",
Side::Buy,
"1",
"5",
OrderType::Spot,
true,
true,
)
.await?;
println!("Order tx: {}", result.tx_id.as_deref().unwrap_or("?"));
if let Some(orders) = &result.orders {
println!("Order ID: {}", orders[0].order_id);
}createOrder / create_order automatically prepends SettleBalance by default. The total action count, including settle, must not exceed 5.
Raw API
Raw order creation uses a CreateOrder action inside POST /v1/session/actions:
{
"CreateOrder": {
"side": "Buy",
"price": "1000000000",
"quantity": "5000000000",
"order_type": "Spot"
}
}Use Precision & Decimals to convert human prices and quantities into raw integer values.
Order Types
The SDK examples above use a standard spot order. For common order-type variants, pass the corresponding SDK order type when your SDK exposes it. If your SDK version does not expose a helper for a specific advanced order type, use the raw API shape or the lower-level session action builder.
| Order Type | Use When |
|---|---|
Spot | You want a normal order that can fill immediately and rest on the book if not fully filled |
Market | You want immediate execution against available liquidity |
Limit | You need execution at a specified price or better |
PostOnly | You only want to add liquidity as a maker |
FillOrKill | The full order must execute immediately or fail |
BoundedMarket | You want market-style execution with price protection |
SDK Examples
import { createOrderAction } from "@o2exchange/sdk";
const postOnly = createOrderAction("sell", "2", "5", "PostOnly");from o2_sdk import OrderSide, OrderType
batch = (
client.actions_for("fFUEL/fUSDC")
.create_order(OrderSide.SELL, "2", "5", OrderType.POST_ONLY)
.build()
)use o2_sdk::{OrderType, Side};
let actions = client
.actions_for("fFUEL/fUSDC")
.await?
.create_order(Side::Sell, "2", "5", OrderType::PostOnly)
.build()?;Raw API
Set CreateOrder.order_type to one of these values:
| Order Type | Raw order_type Value |
|---|---|
| Spot | "Spot" |
| Market | "Market" |
| Limit | { "Limit": ["1000000000", "1734876543210"] } |
| Post Only | "PostOnly" |
| Fill Or Kill | "FillOrKill" |
| Bounded Market | { "BoundedMarket": { "max_price": "1100000000", "min_price": "900000000" } } |
Notes:
- Buy limit orders execute at the limit price or lower.
- Sell limit orders execute at the limit price or higher.
PostOnlyreverts if any quantity would execute immediately as a taker.FillOrKillfails unless the full order can execute immediately.BoundedMarketrequiresmax_pricegreater than or equal tomin_price.
Cancel Order
Cancel an open order by order ID.
await client.cancelOrder("0xORDER_ID", "fFUEL/fUSDC");
console.log("Order cancelled");await client.cancel_order(
order_id="0xORDER_ID",
market="fFUEL/fUSDC",
)
print("Order cancelled")client
.cancel_order(
&mut session,
"0xORDER_ID",
"fFUEL/fUSDC",
)
.await?;
println!("Order cancelled");Raw API
Raw cancellation uses a CancelOrder action inside POST /v1/session/actions:
{
"CancelOrder": {
"order_id": "0x..."
}
}For low-level signing details specific to cancellation, see Cancelling an Order.
Batch Order Actions
Batch actions let you submit multiple order actions in one request. Use them when you need atomic order placement, cancellation, and settlement behavior.
import {
createOrderAction,
settleBalanceAction,
} from "@o2exchange/sdk";
const response = await client.batchActions([
{
market: "fFUEL/fUSDC",
actions: [
settleBalanceAction(),
createOrderAction("buy", "0.1", "50"),
createOrderAction("buy", "1", "5"),
createOrderAction("sell", "2", "5", "PostOnly"),
],
},
], true);
console.log("Batch tx:", response.txId);from o2_sdk import OrderSide, OrderType
batch = (
client.actions_for("fFUEL/fUSDC")
.settle_balance()
.create_order(OrderSide.BUY, "0.1", "50")
.create_order(OrderSide.BUY, "1", "5")
.create_order(OrderSide.SELL, "2", "5", OrderType.POST_ONLY)
.build()
)
result = await client.batch_actions([batch], collect_orders=True)
print(f"Batch tx: {result.tx_id}")use o2_sdk::{OrderType, Side};
let actions = client
.actions_for("fFUEL/fUSDC")
.await?
.settle_balance()
.create_order(Side::Buy, "0.1", "50", OrderType::Spot)
.create_order(Side::Buy, "1", "5", OrderType::Spot)
.create_order(Side::Sell, "2", "5", OrderType::PostOnly)
.build()?;
let result = client
.batch_actions(&mut session, "fFUEL/fUSDC", actions, true)
.await?;
println!("Batch tx: {}", result.tx_id.as_deref().unwrap_or("?"));Raw API
{
"actions": [
{
"market_id": "0x1234567890abcdef...",
"actions": [
{
"CreateOrder": {
"side": "Buy",
"price": "1000000000",
"quantity": "100000000",
"order_type": "Spot"
}
},
{
"CancelOrder": {
"order_id": "0xabcdef..."
}
}
]
}
]
}The total action count, including SettleBalance, must not exceed 5.
Related Session Requirements
- Create or update a session before submitting session actions.
- Session keys can place and cancel orders, but cannot withdraw funds.
- Use the owner key for withdrawals and privileged account operations.
- Use Nonces when coordinating retries or concurrent requests.