Place Orders
Place one or more orders on Synthetix's orderbook. This endpoint always accepts an array of orders for consistency, even when placing a single order.
Endpoint
POST https://papi.synthetix.io/v1/tradeRequest
Request Format
{
"params": {
"action": "placeOrders",
"subAccountId": "1867542890123456789",
"orders": [
{
"symbol": "BTC-USDT",
"side": "buy",
"orderType": "limitGtc",
"price": "50000.00",
"triggerPrice": "",
"quantity": "0.1",
"reduceOnly": false,
"postOnly": false,
"isTriggerMarket": false,
"closePosition": false,
"clientOrderId": "0x1234567890abcdef1234567890abcdef"
}
],
"grouping": "na"
},
"nonce": 1704067200000,
"signature": {
"v": 28,
"r": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"s": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
},
"expiresAfter": 1704067300000
}Request Parameters
Action Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
params | object | Yes | Parameters object containing method details |
params.action | string | Yes | Must be "placeOrders" |
params.subAccountId | string | Yes | Subaccount identifier |
params.orders | array | Yes | Array of order objects (minimum 1 order) |
params.grouping | string | No | Order grouping: "na", "normalTpsl", "positionTpsl" |
Common Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
nonce | integer | Yes | Timestamp in milliseconds (must be increasing) |
signature | object | Yes | EIP-712 signature object |
expiresAfter | integer | No | Expiration timestamp (5x rate limit on stale cancels) |
Order Object
| Parameter | Type | Required | Description |
|---|---|---|---|
symbol | string | Yes | Market symbol (e.g., "BTC-USDT", "ETH-USDT") |
side | string | Yes | "buy" or "sell" |
orderType | string | Yes | One of: limitGtc, limitIoc, limitAlo, market, triggerSl, triggerTp |
price | string | Yes | Price as string. Use empty string when not applicable (market orders and trigger market) |
quantity | string | Yes | Order size as string |
reduceOnly | boolean | Yes | Only reduce existing position |
postOnly | boolean | Conditional | Whether order must be maker (no immediate match). Only used for limitGtc orders. Must be false for all other order types |
triggerPrice | string | Yes | Trigger price as string. Required for triggerSl and triggerTp; empty string otherwise |
isTriggerMarket | boolean | Yes | Execution type for trigger orders. true for market-on-trigger, false for limit-on-trigger. Must be false for non-trigger types |
closePosition | boolean | Yes | Close entire position when triggered (TP/SL orders only). Must be false for non-trigger types |
clientOrderId | string | No | 128-bit hex string (0x + 32 hex chars) |
Order Type Enum and Rules
limitGtc: price required;isTriggerMarket=false;triggerPrice=""limitIoc: price required;isTriggerMarket=false;triggerPrice=""limitAlo: price required;isTriggerMarket=false;triggerPrice=""market: price="";isTriggerMarket=false;triggerPrice=""triggerSl:triggerPricerequired;isTriggerMarketdetermines execution; iftruethenprice="", iffalsethenpricerequiredtriggerTp: same rules astriggerSl
Examples
Limit GTC
{
"orderType": "limitGtc",
"price": "50000.00",
"triggerPrice": "",
"isTriggerMarket": false,
"postOnly": false,
"closePosition": false
}Limit GTC (Post-Only)
{
"orderType": "limitGtc",
"price": "50000.00",
"triggerPrice": "",
"isTriggerMarket": false,
"postOnly": true,
"closePosition": false
}Market
{
"orderType": "market",
"price": "",
"triggerPrice": "",
"isTriggerMarket": false,
"closePosition": false
}Trigger SL (Market)
{
"orderType": "triggerSl",
"price": "",
"triggerPrice": "50000",
"isTriggerMarket": true,
"closePosition": true
}Trigger TP (Limit)
{
"orderType": "triggerTp",
"price": "49950.00",
"triggerPrice": "50000.00",
"isTriggerMarket": false,
"closePosition": true
}Time in Force (TIF) Options
| Value | Name | Description |
|---|---|---|
gtc | Good Till Canceled | Order remains active until filled or canceled |
ioc | Immediate or Cancel | Fill immediately available quantity, cancel remainder |
alo | Add Liquidity Only | Post-only order, rejected if it would take liquidity |
Response
Response Structure
| Field | Type | Description |
|---|---|---|
status | string | Always "ok" for successful requests or "error" for failures |
response | object | Contains operation results (omitted when status is "error") |
response.statuses | array | Array of status objects, one per order submitted |
error | object | Error details (only present when status is "error") |
request_id | string | Request tracking identifier |
timestamp | integer | Unix milliseconds timestamp |
Order Status Types
| Status Type | Description | Fields |
|---|---|---|
resting | Order placed in orderbook | id |
filled | Order completely filled | id, avgPrice, totalSize |
partiallyFilled | Order partially filled | id, avgPrice, filledSize, remainingSize |
error | Order rejected | Error message string |
Success Response Examples
Single Order - Resting
{
"status": "ok",
"response": {
"statuses": [
{
"resting": {
"id": "1948058938469519360"
}
}
]
},
"request_id": "5ccf215d37e3ae6d",
"timestamp": "2025-01-01T00:00:00Z"
}Single Order - Filled
{
"status": "ok",
"response": {
"statuses": [
{
"filled": {
"id": "1948058938469519361",
"avgPrice": "50001.25",
"totalSize": "0.1"
}
}
]
},
"request_id": "5ccf215d37e3ae6d",
"timestamp": "2025-01-01T00:00:00Z"
}Multiple Orders - Mixed Results
{
"status": "ok",
"response": {
"statuses": [
{
"resting": {
"id": "1948058938469519360"
}
},
{
"filled": {
"id": "1948058938469519361",
"avgPrice": "2999.50",
"totalSize": "1.0"
}
},
{
"error": "Insufficient margin"
}
]
},
"request_id": "5ccf215d37e3ae6d",
"timestamp": "2025-01-01T00:00:00Z"
}Partial Fill Example
{
"status": "ok",
"response": {
"statuses": [
{
"partiallyFilled": {
"id": "1948058938469519362",
"avgPrice": "50000.50",
"filledSize": "0.05",
"remainingSize": "0.05"
}
}
]
},
"request_id": "5ccf215d37e3ae6d",
"timestamp": "2025-01-01T00:00:00Z"
}Error Response
{
"status": "error",
"error": {
"message": "Insufficient margin",
"code": "VALIDATION_ERROR"
},
"request_id": "5ccf215d37e3ae6d",
"timestamp": "2025-01-01T00:00:00Z"
}Examples
Place Single Limit Order (GTC)
{
"params": {
"action": "placeOrders",
"subAccountId": "1867542890123456789",
"orders": [
{
"symbol": "BTC-USDT",
"side": "buy",
"orderType": "limitGtc",
"price": "50000.00",
"triggerPrice": "",
"quantity": "0.1",
"reduceOnly": false,
"postOnly": false,
"isTriggerMarket": false,
"closePosition": false
}
]
},
"nonce": 1704067200000,
"signature": {
"v": 28,
"r": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"s": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
}
}Place Multiple Orders (Batch) — Mixed types
{
"params": {
"action": "placeOrders",
"subAccountId": "1867542890123456789",
"orders": [
{
"symbol": "BTC-USDT",
"side": "buy",
"orderType": "limitGtc",
"price": "49000.00",
"triggerPrice": "",
"quantity": "0.05",
"reduceOnly": false,
"postOnly": false,
"isTriggerMarket": false,
"closePosition": false
},
{
"symbol": "BTC-USDT",
"side": "buy",
"orderType": "limitGtc",
"price": "48000.00",
"triggerPrice": "",
"quantity": "0.1",
"reduceOnly": false,
"postOnly": false,
"isTriggerMarket": false,
"closePosition": false
},
{
"symbol": "BTC-USDT",
"side": "sell",
"quantity": "0.15",
"reduceOnly": true,
"orderType": "triggerSl",
"price": "",
"triggerPrice": "45000",
"isTriggerMarket": true,
"closePosition": false
}
],
"grouping": "na"
},
"nonce": 1704067200000,
"signature": {
"v": 28,
"r": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"s": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
}
}:::info Rate Limiting This batch contains 3 orders, so it consumes 3 orders from your per-subaccount rate limit (100 orders/second). See Rate Limits for details. :::
Implementation Notes
- Order nonces must be monotonically increasing timestamps in milliseconds per subaccount
- Client order IDs enable request tracking with 128-bit hex format (0x prefix + 32 hex characters)
- Limit orders require price specification, trigger orders require trigger price
- Batch operations process orders independently with individual status responses
- Order grouping types:
"na"(none),"normalTpsl"(stop-loss/take-profit),"positionTpsl"(position-based) - All price and quantity values must be provided as strings for precision preservation
Error Handling
Common Errors
| Error | Description | Solution |
|---|---|---|
Insufficient margin | Account lacks required margin | Add collateral or reduce order size |
Order expired | expiresAfter timestamp has passed | Use longer expiration or remove |
Invalid market symbol | Market symbol not recognized | Check supported markets |
Order size too small | Below minimum order size | Check market minimums |
Order would be filled | Post-only order would take liquidity | Adjust price or use different TIF |
Position limit exceeded | Maximum position size reached | Reduce position size |
Batch Order Errors
For batch orders, each order is validated independently. The response includes a status for each order in the same sequence as submitted. Orders that succeed will be processed even if others fail.
Implementation Notes
- Batch operations support multiple orders in a single request
- Client order IDs enable tracking across WebSocket sessions
- Expiration timestamps prevent stale order execution (5x rate limit on stale cancels)
- Partial success responses indicate individual order status in batch operations
Rate Limiting
- Each order in the batch counts separately - A request with 5 orders consumes 5 from your rate limit
- Default limit: 100 orders per second per subaccount
- Failed orders due to validation errors still count against rate limits
- See Rate Limits for complete details
Next Steps
- Authentication - Set up request signing
- WebSocket Trading - Real-time alternative
- Error Handling - Handle errors properly