Skip to content

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/trade

Request

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

ParameterTypeRequiredDescription
paramsobjectYesParameters object containing method details
params.actionstringYesMust be "placeOrders"
params.subAccountIdstringYesSubaccount identifier
params.ordersarrayYesArray of order objects (minimum 1 order)
params.groupingstringNoOrder grouping: "na", "normalTpsl", "positionTpsl"

Common Request Parameters

ParameterTypeRequiredDescription
nonceintegerYesTimestamp in milliseconds (must be increasing)
signatureobjectYesEIP-712 signature object
expiresAfterintegerNoExpiration timestamp (5x rate limit on stale cancels)

Order Object

ParameterTypeRequiredDescription
symbolstringYesMarket symbol (e.g., "BTC-USDT", "ETH-USDT")
sidestringYes"buy" or "sell"
orderTypestringYesOne of: limitGtc, limitIoc, limitAlo, market, triggerSl, triggerTp
pricestringYesPrice as string. Use empty string when not applicable (market orders and trigger market)
quantitystringYesOrder size as string
reduceOnlybooleanYesOnly reduce existing position
postOnlybooleanConditionalWhether order must be maker (no immediate match). Only used for limitGtc orders. Must be false for all other order types
triggerPricestringYesTrigger price as string. Required for triggerSl and triggerTp; empty string otherwise
isTriggerMarketbooleanYesExecution type for trigger orders. true for market-on-trigger, false for limit-on-trigger. Must be false for non-trigger types
closePositionbooleanYesClose entire position when triggered (TP/SL orders only). Must be false for non-trigger types
clientOrderIdstringNo128-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: triggerPrice required; isTriggerMarket determines execution; if true then price="", if false then price required
  • triggerTp: same rules as triggerSl

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

ValueNameDescription
gtcGood Till CanceledOrder remains active until filled or canceled
iocImmediate or CancelFill immediately available quantity, cancel remainder
aloAdd Liquidity OnlyPost-only order, rejected if it would take liquidity

Response

Response Structure

FieldTypeDescription
statusstringAlways "ok" for successful requests or "error" for failures
responseobjectContains operation results (omitted when status is "error")
response.statusesarrayArray of status objects, one per order submitted
errorobjectError details (only present when status is "error")
request_idstringRequest tracking identifier
timestampintegerUnix milliseconds timestamp

Order Status Types

Status TypeDescriptionFields
restingOrder placed in orderbookid
filledOrder completely filledid, avgPrice, totalSize
partiallyFilledOrder partially filledid, avgPrice, filledSize, remainingSize
errorOrder rejectedError 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

ErrorDescriptionSolution
Insufficient marginAccount lacks required marginAdd collateral or reduce order size
Order expiredexpiresAfter timestamp has passedUse longer expiration or remove
Invalid market symbolMarket symbol not recognizedCheck supported markets
Order size too smallBelow minimum order sizeCheck market minimums
Order would be filledPost-only order would take liquidityAdjust price or use different TIF
Position limit exceededMaximum position size reachedReduce 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