Skip to content

API Notation

Synthetix API conventions and data formats.

1. Naming Conventions

The Synthetix API uses mixed naming conventions based on field type:

Field CategoryConventionExamples
Business/Domain FieldscamelCasesubAccountId, clientOrderId, orderType, walletAddress
System Fields (REST responses)snake_caserequest_id, timestamp (RFC3339 string)
System Fields (WebSocket)Shortenedid (in requests/responses)
MethodscamelCaseplaceOrders, cancelOrders, getPositions
Notification Methods (WS)snake_casemarket_price_update, order_update, orderbook_depth_update
SymbolsDash-separatedBTC-USDT, ETH-USDT (format: BASE-QUOTE)

Field Naming by Protocol

ContextFieldFormatExample
REST ResponsesRequest trackingrequest_id (snake_case)"request_id": "5ccf215d37e3ae6d"
REST ResponsesTimestampsRFC3339 string"timestamp": "2025-01-01T00:00:00Z"
WebSocketRequest trackingid"id": "request-123"
All ProtocolsBusiness datacamelCase"subAccountId": "123456789"
WS NotificationsMethod namessnake_case"method": "market_price_update"

2. Data Types

Numeric Precision

All prices and quantities as strings to avoid floating-point errors:

// ✓ Correct - All numeric values as strings
{
  "price": "50000.50",
  "quantity": "0.1",
  "leverage": "10"
}
 
// ✗ Wrong - Numeric values as numbers
{
  "price": 50000.50,
  "quantity": 0.1,
  "leverage": 10
}

Timestamps & Nonces

Context matters for timestamp format:
ContextFormatExample
Request fields (nonce)Positive, incrementing integer"nonce": 1704067200000
Request fields (expiresAfter)Unix seconds (number)"expiresAfter": 1704067260
REST response fieldsRFC3339 string"timestamp": "2025-01-01T00:00:00Z"
WebSocket response fieldsUnix milliseconds (number)"timestamp": 1704067200000
// ✓ Correct - Request with Unix timestamps
{
  "nonce": 1704067200000,        // Positive integer nonce
  "expiresAfter": 1704067260     // Unix seconds
}
 
// ✓ Correct - REST API response with RFC3339 string
{
  "status": "ok",
  "response": {...},
  "request_id": "5ccf215d37e3ae6d",
  "timestamp": "2025-01-01T00:00:00Z"  // String in REST responses
}

Booleans & Arrays

{
  "reduceOnly": false,           // ✓ Boolean
  "orders": [{...}, {...}],      // ✓ Array for batch ops
  "orders": []                   // ✓ Empty arrays valid
}

3. Identifiers

ID TypeFormatExamplePurpose
subAccountIdString (uint64)"1234567890123456789"Trading account
orderIdString (uint64)"1948058938469519360"System order ID
clientOrderId0x + 32 hex"0x1234567890abcdef1234567890abcdef"Client tracking
request_id16 hex chars"5ccf215d37e3ae6d"Server tracking (REST)
idClient-defined"request-123"Request tracking (WebSocket)
address0x + 40 hex"0x742d35Cc6634C0532925a3b844Bc9e7D1333D6E2"Ethereum wallet

Subaccount ID Error Messages

Invalid subaccount IDs are rejected during request decoding with specific error messages:

ConditionError message
"0""subaccount id cannot be zero"
Negative value"subaccount id cannot be negative"
Value exceeds maximum"subaccount id too large"
Non-numeric input"subaccount id cannot be parsed"

This applies to all endpoints that accept subaccount IDs, including getSubAccount, getSubAccounts, transferCollateral, createSubaccount, getSubAccountIds, and related WebSocket trade methods and subscriptions.

ID Usage Rules

OperationRequires subAccountIdExample
New orders✓ YesplaceOrders
Existing resources✗ NocancelOrders with orderId
Public data✗ NogetMarketData

4. Trading Constructs

Order Types (Static)

// Limit GTC
{"orderType": "limitGtc", "price": "50000", "triggerPrice": "", "isTriggerMarket": false}
 
// Limit IOC
{"orderType": "limitIoc", "price": "50000", "triggerPrice": "", "isTriggerMarket": false}
 
// Market
{"orderType": "market", "price": "", "triggerPrice": "", "isTriggerMarket": false}
 
// Trigger Stop Loss (market on trigger)
{"orderType": "triggerSl", "price": "", "triggerPrice": "50000", "isTriggerMarket": true}
 
// Trigger Take Profit (limit on trigger)
{"orderType": "triggerTp", "price": "49950", "triggerPrice": "50000", "isTriggerMarket": false}

Rules:

  • limitGtc/limitIoc: price required; isTriggerMarket=false; triggerPrice=""
  • market: price=""; isTriggerMarket=false; triggerPrice=""
  • triggerSl/triggerTp: triggerPrice required; if isTriggerMarket=true then price="", else price required

Time in Force

ValueDescription
gtcGood Till Canceled
iocImmediate or Cancel
postOnlyPost-only flag on limitGtc orders

States

Order States: started, open, partiallyFilled, filled, cancelled, rejected, modifying

Position States: open, close, update

Side: buy, sell

5. Request Envelopes

REST Info Endpoints

Wrap all request parameters inside a params object and identify the target operation with params.action.

{
  "params": {
    "action": "getMarkets",
    "symbol": "BTC-USDT",
    "limit": 100
  }
}
  • params.action maps to the specific public info method
  • Additional request fields live alongside params.action inside params

REST Trade Endpoints

Trading requests wrap method inputs inside params while keeping authentication fields at the top level.

{
  "params": {
    "action": "placeOrders",
    "subAccountId": "1867542890123456789",
    "orders": [{ /* ... */ }]
  },
  "nonce": 1704067200000,
  "expiresAfter": 1704067260,
  "signature": {
    "v": 28,
    "r": "0x...",
    "s": "0x..."
  }
}
  • params.action identifies the trade method; additional method params including subAccountId live inside params
  • nonce is a positive integer (unique per request) and expiresAfter is Unix seconds, both at root level
  • signature follows the shared EIP-712 format at root level

6. API Mechanics

EIP-712 Signatures

{
  "signature": {
    "v": 28,      // Recovery ID: 0, 1, 27, or 28
    "r": "0x...", // 32 bytes hex
    "s": "0x..."  // 32 bytes hex
  }
}

Response Format

REST API responses use snake_case for system fields:

{
  "status": "ok",              // "ok" or "error"
  "response": {...},           // Success data (omitted on error)
  "error": {                   // Error details (omitted on success)
    "code": "VALIDATION_ERROR",
    "message": "Description"
  },
  "request_id": "5ccf215d37e3ae6d",  // snake_case for REST
  "timestamp": "2025-01-01T00:00:00Z" // RFC3339 string for REST
}

WebSocket responses use shortened field names:

{
  "id": "request-123",         // Matches client's request ID
  "status": 200,               // HTTP-style status code
  "result": {...}              // Success data (omitted on error)
}

Error Codes

CodeHTTPDescription
VALIDATION_ERROR400Invalid request
INVALID_FORMAT400Incorrect format
INVALID_VALUE400Out of range
NOT_FOUND404Resource missing
INTERNAL_ERROR500System error

Quick Reference

Validation Patterns

  • subAccountId: ^\d{1,19}$ (uint64 as string)
  • clientOrderId: ^0x[a-fA-F0-9]{32}$
  • request_id: ^[a-f0-9]{16}$ (REST API responses)
  • id: varies by context (WebSocket client-set)

Implementation Notes

  • Omit null values - remove optional fields entirely