Session Management
Manage trading sessions and execute automated trading operations using session keys.
Update Trading Session
Create or update a trading session key for automated trading.
PUT /v1/session
Headers
Request Body
Supports both nonce kinds: provide the sequential nonce, or — with the typed signature variant — a parallel_nonce (packed u256, decimal string) so the call does not have to wait behind other in-flight transactions. With parallel_nonce the typed signature covers ParallelSessionArgs instead of SessionArgs. See Parallel Nonces.
Rate Limit: 5 requests/second (Owner ID-based)
Source: packages/api/src/app/routes/v1/session.rs:update_session_handler
Execute Session Actions
Execute multiple trading actions using a session key. Supports up to 5 actions distributed across a maximum of 5 markets (e.g., 5 actions on 1 market, 1 action on 5 markets, or any equivalent split totaling 5 actions).
POST /v1/session/actions
Constraints:
- Maximum 5 actions total
- Maximum 5 markets per request
- Actions can include: CreateOrder, CancelOrder, SettleBalance, RegisterReferer
Headers
Request Body
Market Selection
Action Type
Action Types:
- CreateOrder:
{ "CreateOrder": { "side": "Buy|Sell", "price": "1000", "quantity": "100", "order_type": <OrderType> } } - CancelOrder:
{ "CancelOrder": { "order_id": "0x..." } } - SettleBalance:
{ "SettleBalance": { "to": { "Address": "0x..." } } }—tois an Identity - RegisterReferer:
{ "RegisterReferer": { "referer": { "Address": "0x..." } } }—refereris an Identity
Order Types
The order_type field in CreateOrder actions accepts the following variants:
Spot (Default)
Executes immediately at the best available price. If not fully filled, the remaining quantity is added to the order book.
Format: "Spot"
Example:
{
"CreateOrder": {
"side": "Buy",
"price": "1000000000",
"quantity": "5000000000",
"order_type": "Spot"
}
}Use Case: Standard limit orders that can partially fill and rest on the book.
Market
Executes immediately at the best available price, taking all available liquidity until filled or exhausted. Market orders are automatically cancelled after execution.
Format: "Market"
Example:
{
"CreateOrder": {
"side": "Sell",
"price": "1000000000",
"quantity": "5000000000",
"order_type": "Market"
}
}Use Case: Instant execution at current market price without price guarantee.
Limit
Executes only at the specified price or better with price-time priority. Buy limit orders execute at the limit price or lower; sell limit orders execute at the limit price or higher.
Format: { "Limit": [price, timestamp] }
Parameters:
price(u64): Price level for the limit ordertimestamp(u128): Timestamp for price-time priority
Example:
{
"CreateOrder": {
"side": "Buy",
"price": "1000000000",
"quantity": "5000000000",
"order_type": {
"Limit": ["1000000000", "1734876543210"]
}
}
}Use Case: Controlled price execution with guaranteed price or better.
FillOrKill (FOK)
All or nothing execution. The entire order must be filled immediately or the transaction reverts.
Note: FillOrKill orders execute atomically on chain (complete fill or revert). However, be aware that the transaction will fail if there is insufficient liquidity to completely fill the order at execution time, or on chain order processing delays.
Format: "FillOrKill"
Example:
{
"CreateOrder": {
"side": "Buy",
"price": "1000000000",
"quantity": "5000000000",
"order_type": "FillOrKill"
}
}Use Case: Atomic large orders that require complete fill or no execution.
PostOnly
Maker-only orders that add liquidity to the order book. If any quantity would be filled as a taker (removing liquidity), the transaction reverts.
Format: "PostOnly"
Example:
{
"CreateOrder": {
"side": "Buy",
"price": "1000000000",
"quantity": "5000000000",
"order_type": "PostOnly"
}
}Use Case: Ensure orders only add liquidity to the order book as maker orders.
BoundedMarket
Market order with price protection. Executes immediately at the best available price, but only within specified minimum and maximum price bounds.
Format: { "BoundedMarket": { "max_price": u64, "min_price": u64 } }
Parameters:
max_price(u64): Maximum acceptable pricemin_price(u64): Minimum acceptable price
Validation: max_price must be greater than or equal to min_price
Example:
{
"CreateOrder": {
"side": "Buy",
"price": "1000000000",
"quantity": "5000000000",
"order_type": {
"BoundedMarket": {
"max_price": "1100000000",
"min_price": "900000000"
}
}
}
}Use Case: Market orders with slippage protection, ensuring execution only within acceptable price range.
Order Type Summary
| Order Type | Execution | Price Control | Reverts If | Best For |
|---|---|---|---|---|
| Spot | Immediate + Book | Best available | - | Standard trading |
| Market | Immediate | Best available | - | Quick execution |
| Limit | Price-time priority | Exact or better | - | Guaranteed price |
| FillOrKill | All-or-nothing | Best available | Not fully filled | Atomic fills |
| PostOnly | Maker only | Best available | Any taker fill | Guaranteed maker execution |
| BoundedMarket | Within bounds | Min/max range | Outside bounds | Protected market orders |
Example Request Body:
{
"actions": [
{
"market_id": "0x1234567890abcdef...",
"actions": [
{
"CreateOrder": {
"side": "Buy",
"price": "1000000000",
"quantity": "100000000",
"order_type": "Spot"
}
},
{
"CreateOrder": {
"side": "Sell",
"price": "1050000000",
"quantity": "50000000",
"order_type": "PostOnly"
}
},
{
"CancelOrder": {
"order_id": "0xabcdef..."
}
}
]
}
],
"signature": {
"Secp256k1": "0x789..."
},
"nonce": "2",
"trade_account_id": "0xdef456...",
"session_id": {
"Address": "0xabc123..."
},
"collect_orders": true
}Example with Multiple Order Types:
{
"actions": [
{
"market_id": "0x1234567890abcdef...",
"actions": [
{
"CreateOrder": {
"side": "Buy",
"price": "1000000000",
"quantity": "5000000000",
"order_type": {
"BoundedMarket": {
"max_price": "1100000000",
"min_price": "900000000"
}
}
}
}
]
},
{
"market_id": "0xfedcba9876543210...",
"actions": [
{
"CreateOrder": {
"side": "Sell",
"price": "2000000000",
"quantity": "10000000000",
"order_type": "FillOrKill"
}
}
]
}
],
"signature": {
"Secp256k1": "0x789..."
},
"nonce": "3",
"trade_account_id": "0xdef456...",
"session_id": {
"Address": "0xabc123..."
},
"collect_orders": true
}Parallel Nonces
By default a session action uses the account's sequential nonce (nonce field): only one transaction can be usable at a time and they must confirm in order. To run any number of session actions concurrently, replace nonce with parallel_nonce — a packed u256 (decimal string) that the client generates locally; see Parallel Nonces for the layout and lifecycle.
Differences from the sequential flow:
- Provide
parallel_nonceand omitnonce(providing neither is rejected). - The session signature covers
(parallel_nonce, calls): sha256 over the ABI encoding of the packed nonce followed by the reconstructed contract calls, signed by the session key. - Requests are independent: submit as many as you like in parallel, and inclusion order does not matter. A consumed, expired, or out-of-window nonce is rejected with HTTP 400 before any transaction is submitted.
Example Request Body (parallel):
{
"actions": [
{
"market_id": "0x1234567890abcdef...",
"actions": [
{
"CreateOrder": {
"side": "Buy",
"price": "1000000000",
"quantity": "100000000",
"order_type": "Spot"
}
}
]
}
],
"signature": {
"Secp256k1": "0x789..."
},
"parallel_nonce": "374144419156711147060143317175368453031918731001600",
"trade_account_id": "0xdef456...",
"session_id": {
"Address": "0xabc123..."
},
"collect_orders": true
}Rate Limit: 5 requests/second (Owner ID-based)
Source: packages/api/src/app/routes/v1/session.rs:session_actions_handler