Account Operations
Execute advanced account operations including contract calls, upgrades, and asset withdrawals.
Common references:
Owner Contract Call
Execute a contract call as the account owner.
POST /v1/accounts/call
Headers
Request Body
curl -X POST \
"https://api.o2.app/v1/accounts/call" \
-H "Accept: application/json" \
-H "O2-Owner-Id: 0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" \
-H "Content-Type: application/json"Rate Limit: 10 requests/minute (Owner ID-based)
Source: packages/api/src/app/routes/v1/accounts.rs:owner_call_contract_handler
Owner Multiple Contract Calls
Execute multiple contract calls in batch as account owner.
POST /v1/accounts/calls
Headers
Request Body
curl -X POST \
"https://api.o2.app/v1/accounts/calls" \
-H "Accept: application/json" \
-H "O2-Owner-Id: 0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" \
-H "Content-Type: application/json"Owner calls with the typed signature variant also accept a parallel_nonce instead of nonce (the typed signature then covers ParallelMultiCallContractArgs), allowing concurrent owner calls. See Parallel Nonces.
Rate Limit: 10 requests/minute (Owner ID-based)
Source: packages/api/src/app/routes/v1/accounts.rs:owner_call_contracts_handler
Upgrade Account
Upgrade trading account contract to newer version.
POST /v1/accounts/upgrade
Headers
Request Body
curl -X POST \
"https://api.o2.app/v1/accounts/upgrade" \
-H "Accept: application/json" \
-H "O2-Owner-Id: 0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" \
-H "Content-Type: application/json"Rate Limit: 10 requests/minute (Owner ID-based)
Source: packages/api/src/app/routes/v1/accounts.rs:upgrade_account_handler
Withdraw Assets
Withdraw assets from a trading account to a Fuel Ignition destination.
Fuel Ignition only
POST /v1/accounts/withdraw is not a Fast Bridge withdrawal to Base, Ethereum, or another EVM destination chain. It withdraws assets from the o2 trading account on Fuel Ignition to a Fuel-side destination identity.
To withdraw from o2/Fuel to an EVM chain, use the Fast Bridge withdrawal flow instead. That flow calls the Fast Bridge AssetRegistry.withdraw_via_fast_bridge_with_fee through an owner-signed account action such as WithdrawViaFastBridgeWithFee; it also requires a destination chain, EVM recipient, and gas-oracle fee quote.
For implementation guidance, see the fast-bridge/withdrawals skill and its withdrawal reference flows. For the protocol-level flow, see Fast Bridge withdrawal flow.
POST /v1/accounts/withdraw
Headers
Request Body
curl -X POST \
"https://api.o2.app/v1/accounts/withdraw" \
-H "Accept: application/json" \
-H "O2-Owner-Id: 0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" \
-H "Content-Type: application/json"This endpoint is for moving funds out of the trading account while staying on Fuel Ignition. It does not unwrap universal wrapped assets or release funds on an EVM chain.
With parallel_nonce (and the typed signature variant), any number of withdrawals can be in flight concurrently — the typed signature covers ParallelWithdrawArgs instead of WithdrawArgs. See Nonces and Parallel Nonces.
Rate Limit: 10 requests/minute (Owner ID-based)
Source: packages/api/src/app/routes/v1/accounts.rs:withdraw_handler
Parallel Nonces
Every nonce-authorized account operation (session actions, withdrawals, session updates, owner actions) accepts either the account's sequential nonce or a parallel nonce. Sequential nonces force one usable transaction at a time, confirmed in order. Parallel nonces remove that constraint: clients generate them locally, keep any number of requests in flight at once, and inclusion order does not matter.
A parallel nonce is a packed u256, transmitted as a decimal string:
| Bits (from LSB) | Width | Field |
|---|---|---|
| 0–7 | 8 | Bitmap position (0–127) |
| 8–135 | 128 | Word position inside the sliding window |
| 136–167 | 32 | Expiry — unix timestamp in seconds; the nonce is unusable after it |
| 168–175 | 8 | Nonce session id (lane), 0–4 |
| 176–255 | 80 | Reserved, must be zero |
Each (session id) lane has an on-chain sliding window of 8 words × 128 bits = 1024 usable positions; consuming positions in the upper half of the window slides it forward. Recommended client flow:
- Read the current window once at startup via
GET /v1/accounts/window. - Initialize a local cursor strictly after the highest consumed position and increment it per request — never reuse a handed-out position, and skip holes (they may belong to still-in-flight transactions).
- Stamp a fresh expiry (e.g. now + 120s) into each nonce at issuance.
- Optionally subscribe to
subscribe_nonce_v2over WebSocket to observe consumption.
Parallel nonces always require the typed signature variant. A consumed, expired, or out-of-window nonce is rejected with HTTP 400 before a transaction is submitted; the contract remains the final authority.
Get Parallel Nonce Window
Read the current parallel-nonce sliding window of a trading account. This is the client's nonce-cursor initialization read; nonce generation itself is local and needs no further server calls.
GET /v1/accounts/window?trade_account_id=0x...&nonce_session_id=0
| Query Parameter | Type | Required | Description |
|---|---|---|---|
trade_account_id | string | Yes | Trading account contract ID. Unknown accounts return an error |
nonce_session_id | number | No | Which nonce session (lane) to read, 0–4. Defaults to 0 |
Response:
{
"nonce_session_id": 0,
"base": "0",
"slots": [
{ "word_position": "0", "bitmap": "15" },
{ "word_position": "1", "bitmap": "0" },
{ "word_position": "2", "bitmap": "0" },
{ "word_position": "3", "bitmap": "0" },
{ "word_position": "4", "bitmap": "0" },
{ "word_position": "5", "bitmap": "0" },
{ "word_position": "6", "bitmap": "0" },
{ "word_position": "7", "bitmap": "0" }
]
}base— lower bound of the active word range[base, base + 8).slots[i]— the slot for wordword_position % 8; bitnofbitmapset means bitmap positionnof that word is consumed. A slot whoseword_positionis outside the active range was recycled by a window slide and counts as empty.
Rate Limit: shared IP-based aggregated limit
Source: packages/api/src/app/routes/v1/parallel_nonce.rs:get_parallel_nonce_window_handler