Skip to main content

Endpoint

POST /exchange

Description

Place market or limit orders for perpetual markets. Supports single or batch orders with signature verification.

Request Body

ParameterTypeDescription
action*objectSee below
action.type*stringMust be "order"
action.orders*arraySee below
action.orders[].a*stringAsset ID as 8-char hex string (4 bytes), e.g., "01000000"
action.orders[].b*booleantrue = buy, false = sell
action.orders[].pstringLimit price (required for limit orders), e.g., "50000.0"
action.orders[].s*stringOrder size, e.g., "0.1" for 0.1 BTC
action.orders[].rbooleanReduce-only flag (default: false)
action.orders[].t*objectOrder type configuration, e.g., {"limit":{"tif":"Gtc"}}
action.orders[].t.limit.tifstringTime-in-force: "Gtc", "Alo", "Ioc"
action.orders[].t.trigger.isMarketbooleantrue for stop-market, false for stop-limit
action.orders[].t.trigger.triggerPxstringTrigger price for stop orders
action.orders[].t.trigger.tpslstring"tp" (take profit) or "sl" (stop loss)
action.orders[].cnumberOptional client order id (cloid)
action.orders[].isPositionTpslbooleanOptional flag for position TP/SL orders
action.groupingstringOrder grouping: "na", "normalTpsl", "positionTpsl"
nonce*numberTimestamp in milliseconds for replay protection, e.g., 1701234567890
expiresAfternumberOptional expiration timestamp (ms)
signature*objectSee below
signature.r*stringFirst 32 bytes of signature (hex string), e.g., "0x1234..."
signature.s*stringSecond 32 bytes of signature (hex string), e.g., "0x5678..."
signature.v*numberRecovery ID (27 or 28)

Response

{
  "status": "ok",
  "response": {
    "type": "order",
    "data": {
      "statuses": [
        { "resting": { "oid": "0x1a2b3c4d5e6f7890..." } }
      ]
    }
  },
  "metadata": [
    {
      "orderId": "0x1a2b3c4d5e6f7890...",
      "status": "committed"
    }
  ]
}

Response Fields

FieldTypeDescription
statusstring”ok” on success
response.data.statusesarrayStatus for each order
statuses[].resting.oidstringOrder ID (128-bit hex string, if accepted)
statuses[].errorstringError message (if rejected)
metadataarrayAdditional processing details for each order
metadata[].orderIdstringInternal order ID
metadata[].statusstring”committed” or “rejected”
metadata[].errorstringError details (if rejected)

Example Request

curl -X POST https://api.notional.xyz/exchange \
  -H "Content-Type: application/json" \
  -d '{
    "action": {
      "type": "order",
      "orders": [{
        "a": "01000000",
        "b": true,
        "p": "50000.0",
        "s": "0.1",
        "r": false,
        "t": { "limit": { "tif": "Ioc" } }
      }],
      "grouping": "na"
    },
    "nonce": 1701234567890,
    "signature": {
      "r": "0x1234...",
      "s": "0x5678...",
      "v": 27
    }
  }'

Error Responses

{
  "status": "ok",
  "response": {
    "data": {
      "statuses": [
        { "error": "Insufficient margin" }
      ]
    }
  }
}

Notes

  • Order IDs (oid) are 128-bit hex strings derived from signature + index
  • Time-in-force options: "Gtc" (Good-til-cancel), "Alo" (Add-liquidity-only), "Ioc" (Immediate-or-cancel)
  • Maximum 20 orders per request
  • Orders are idempotent based on signature
  • action.orders[].a is a 4-byte AssetId encoded as 8 hex characters