API Notation
Synthetix API conventions and data formats.
1. Naming Conventions
The Synthetix API uses mixed naming conventions based on field type:
| Field Category | Convention | Examples |
|---|---|---|
| Business/Domain Fields | camelCase | subAccountId, clientOrderId, orderType, walletAddress |
| System Fields (REST responses) | snake_case | request_id, timestamp (RFC3339 string) |
| System Fields (WebSocket) | Shortened | id (in requests/responses) |
| Methods | camelCase | placeOrders, cancelOrders, getPositions |
| Notification Methods (WS) | snake_case | market_price_update, order_update, orderbook_depth_update |
| Symbols | Dash-separated | BTC-USDT, ETH-USDT (format: BASE-QUOTE) |
Field Naming by Protocol
| Context | Field | Format | Example |
|---|---|---|---|
| REST Responses | Request tracking | request_id (snake_case) | "request_id": "5ccf215d37e3ae6d" |
| REST Responses | Timestamps | RFC3339 string | "timestamp": "2025-01-01T00:00:00Z" |
| WebSocket | Request tracking | id | "id": "request-123" |
| All Protocols | Business data | camelCase | "subAccountId": "123456789" |
| WS Notifications | Method names | snake_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:| Context | Format | Example |
|---|---|---|
| Request fields (nonce, expiresAfter) | Unix milliseconds (number) | "nonce": 1704067200000 |
| REST response fields | RFC3339 string | "timestamp": "2025-01-01T00:00:00Z" |
| WebSocket response fields | Unix milliseconds (number) | "timestamp": 1704067200000 |
// ✓ Correct - Request with Unix ms numbers
{
"nonce": 1704067200000, // Number in requests
"expiresAfter": 1704067260000 // Number in requests
}
// ✓ 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 Type | Format | Example | Purpose |
|---|---|---|---|
| subAccountId | String (uint64) | "1234567890123456789" | Trading account |
| orderId | String (uint64) | "1948058938469519360" | System order ID |
| clientOrderId | 0x + 32 hex | "0x1234567890abcdef1234567890abcdef" | Client tracking |
| request_id | 16 hex chars | "5ccf215d37e3ae6d" | Server tracking (REST) |
| id | Client-defined | "request-123" | Request tracking (WebSocket) |
| address | 0x + 40 hex | "0x742d35Cc6634C0532925a3b844Bc9e7D1333D6E2" | Ethereum wallet |
ID Usage Rules
| Operation | Requires subAccountId | Example |
|---|---|---|
| New orders | ✓ Yes | placeOrders |
| Existing resources | ✗ No | cancelOrders with orderId |
| Public data | ✗ No | getMarketData |
4. Trading Constructs
Order Types (Static)
// Limit GTC
{"orderType": "limitGtc", "price": "50000", "triggerPrice": "", "isTriggerMarket": false}
// Limit IOC
{"orderType": "limitIoc", "price": "50000", "triggerPrice": "", "isTriggerMarket": false}
// Limit ALO (post-only)
{"orderType": "limitAlo", "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:
limit*: price required;isTriggerMarket=false;triggerPrice=""market: price="";isTriggerMarket=false;triggerPrice=""triggerSl/triggerTp:triggerPricerequired; ifisTriggerMarket=truethenprice="", elsepricerequired
Time in Force
| Value | Description |
|---|---|
gtc | Good Till Canceled |
ioc | Immediate or Cancel |
alo | Add Liquidity Only (Post-only) |
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.actionmaps to the specific public info method- Additional request fields live alongside
params.actioninsideparams
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": 1704067260000,
"signature": {
"v": 28,
"r": "0x...",
"s": "0x..."
}
}params.actionidentifies the trade method; additional method params includingsubAccountIdlive insideparamsnonceandexpiresAfterare Unix ms numbers at root levelsignaturefollows 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
| Code | HTTP | Description |
|---|---|---|
VALIDATION_ERROR | 400 | Invalid request |
INVALID_FORMAT | 400 | Incorrect format |
INVALID_VALUE | 400 | Out of range |
NOT_FOUND | 404 | Resource missing |
INTERNAL_ERROR | 500 | System 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
nullvalues - remove optional fields entirely