Skip to content

Get Positions

Retrieve detailed information about positions for the authenticated subaccount with flexible filtering by status, time range, and pagination. This unified endpoint supports both current and historical position data.

Endpoint

POST https://papi.synthetix.io/v1/trade

Request

Request Format

{
  "params": {
    "action": "getPositions",
    "subAccountId": "1867542890123456789",
    "symbol": "BTC-USDT",
    "status": "open",
    "limit": 100,
    "offset": 0,
    "sortBy": "createdAt",
    "sortOrder": "desc"
  },
  "nonce": 1735689600000,
  "signature": {
    "v": 28,
    "r": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
    "s": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
  }
}

Request Parameters

ParameterTypeRequiredDescription
paramsobjectYesRequest parameters wrapper
params.actionstringYesMust be "getPositions"
params.subAccountIdstringYesSubAccount ID to retrieve positions for
params.symbolstringNoFilter by specific market symbol (e.g., "BTC-USDT")
params.statusstringNoFilter by position status: "open", "close", "update"
params.fromTimeintegerNoStart time in Unix milliseconds for time-based filtering
params.toTimeintegerNoEnd time in Unix milliseconds for time-based filtering
params.limitintegerNoMaximum number of positions to return (default: 50, max: 1000)
params.offsetintegerNoNumber of positions to skip for pagination (default: 0)
params.sortBystringNoSort field: "createdAt", "updatedAt", "symbol", "quantity"
params.sortOrderstringNoSort direction: "asc" or "desc" (default: "desc")
ParameterTypeRequiredDescription
nonceuint64YesUnix milliseconds timestamp (must be monotonically increasing)
signatureobjectYesEIP-712 signature object
expiresAfteruint64NoUnix milliseconds expiration timestamp (5x rate limit on stale cancels)

Response

Response Structure

FieldTypeDescription
statusstringAlways "ok" for successful requests or "error" for failures
responsearrayArray of position objects matching filter criteria (omitted when status is "error")
errorobjectError details (only present when status is "error")
requestIdstringRequest tracking identifier
timestampintegerUnix milliseconds timestamp

Success Response Examples

Multiple Positions (Open and Closed)

{
  "status": "ok",
  "response": [
    {
      "positionId": "pos_12345",
      "subAccountId": "1867542890123456789",
      "symbol": "ETH-USDT",
      "side": "long",
      "entryPrice": "3000.00",
      "quantity": "0.5000",
      "unrealizedPnl": "0.00",
      "usedMargin": "0.00",
      "maintenanceMargin": "0.00",
      "liquidationPrice": "0.00",
      "status": "close",
      "netFunding": "8.50",
      "takeProfitOrderIds": [],
      "stopLossOrderIds": [],
      "updatedAt": 1735689600000,
      "createdAt": 1735686000000
    },
    {
      "positionId": "pos_12346",
      "subAccountId": "1867542890123456789",
      "symbol": "BTC-USDT",
      "side": "short",
      "entryPrice": "42000.00",
      "quantity": "0.1000",
      "unrealizedPnl": "-12.50",
      "usedMargin": "840.00",
      "maintenanceMargin": "420.00",
      "liquidationPrice": "45000.00",
      "status": "open",
      "netFunding": "8.50",
      "takeProfitOrderIds": [],
      "stopLossOrderIds": ["sl_002"],
      "updatedAt": 1735689600000,
      "createdAt": 1735680000000
    }
  ],
  "request_id": "5ccf215d37e3ae6d",
  "timestamp": "2025-01-01T00:00:00Z"
}

Open Positions Only

{
  "status": "ok",
  "response": [
    {
      "positionId": "pos_12347",
      "subAccountId": "1867542890123456789",
      "symbol": "BTC-USDT",
      "side": "long",
      "entryPrice": "43500.00",
      "quantity": "0.2000",
      "unrealizedPnl": "200.00",
      "usedMargin": "1740.00",
      "maintenanceMargin": "870.00",
      "liquidationPrice": "41000.00",
      "status": "open",
      "netFunding": "8.50",
      "takeProfitOrderIds": ["tp_001"],
      "stopLossOrderIds": ["sl_003"],
      "updatedAt": 1735689700000,
      "createdAt": 1735689000000
    }
  ],
  "request_id": "5ccf215d37e3ae6e",
  "timestamp": "2025-01-01T00:00:00Z"
}

Empty Result Set

{
  "status": "ok",
  "response": [],
  "request_id": "5ccf215d37e3ae6f",
  "timestamp": "2025-01-01T00:00:00Z"
}

Position Object

FieldTypeDescription
positionIdstringPosition identifier
subAccountIdstringSubaccount identifier
symbolstringTrading symbol (e.g., "BTC-USDT")
sidestringPosition side: "long" or "short"
entryPricestringAverage entry price
quantitystringPosition size/quantity
realizedPnlstringRealized profit/loss
unrealizedPnlstringUnrealized profit/loss
usedMarginstringMargin used for this position
maintenanceMarginstringMaintenance margin required
liquidationPricestringPosition liquidation price
statusstringPosition status: "open", "close", "update"
netFundingstringNet funding payments (positive = received)
takeProfitOrderIdsarray[string]Array of take profit order IDs
stopLossOrderIdsarray[string]Array of stop loss order IDs
updatedAtintegerLast update timestamp (Unix milliseconds, not seconds!)
createdAtintegerCreation timestamp (Unix milliseconds, not seconds!)

Position Status Types

StatusDescriptionCharacteristics
openActive positionHas unrealized PnL, margin requirements, liquidation price
closeClosed positionOnly realized PnL, no margin requirements
updatePosition being updatedTransitional state during modifications

Position Calculations

  • realizedPnl: Profit/loss from closed portions of the position
  • unrealizedPnl: Current profit/loss based on mark price (open positions only)
  • usedMargin: Margin currently allocated to this position
  • maintenanceMargin: Minimum margin for position maintenance
  • liquidationPrice: Price at which position would be liquidated (open positions only)
  • entryPrice: Volume-weighted average price of all fills that opened the position
  • netFunding: Net funding payments received/paid for this position

Error Response

{
  "status": "error",
  "error": {
    "message": "Failed to get positions",
    "code": "INTERNAL_ERROR"
  },
  "request_id": "5ccf215d37e3ae6d",
  "timestamp": "2025-01-01T00:00:00Z"
}

Code Examples

Get All Positions

{
  "params": {
    "action": "getPositions",
    "subAccountId": "1867542890123456789",
    "limit": 100
  },
  "nonce": 1735689600000,
  "signature": {
    "v": 28,
    "r": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
    "s": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
  }
}

Position Information

  • Real-time Data: Open position data is updated in real-time with current mark prices and PnL
  • Risk Metrics: Includes liquidation prices, margin requirements, and position-level risk assessment
  • Order Links: References to associated take profit and stop loss orders
  • Detailed Margins: Both used margin and maintenance margin requirements
  • USDT Denomination: All monetary values are denominated in USDT for consistency
  • Performance Tracking: Comprehensive PnL, volume, and fee tracking per position

Code Example

EIP-712 Signature

const domain = {
  name: "Synthetix",
  version: "1",
  chainId: 1,
  verifyingContract: "0x0000000000000000000000000000000000000000"
};
 
const types = {
  GetPositionsRequest: [
    { name: "subAccountId", type: "uint256" },
    { name: "action", type: "string" },
    { name: "status", type: "string[]" },
    { name: "symbol", type: "string" },
    { name: "fromTime", type: "uint256" },
    { name: "toTime", type: "uint256" },
    { name: "nonce", type: "uint256" }
  ]
};
 
const message = {
  subAccountId: "1867542890123456789",
  type: "getPositions",
  status: ["open"],
  symbol: "BTC-USDT",
  fromTime: 1704067200000,
  toTime: 1704153600000,
  nonce: Date.now()
};
 
const signature = await signer._signTypedData(domain, types, message);

Implementation Notes

  • Authentication requires signature by account owner or authorized delegate
  • Subaccount ID must be valid and accessible to requesting wallet
  • Pagination: Use limit parameter (default: 50, max: 1000)
  • Returns all positions for the subaccount in current implementation

Signing

All trading methods are signed using EIP-712. Each successful trading request will contain:

  • A piece of structured data that includes the sender address
  • A signature of the hash of that structured data, signed by the sender

For detailed information on EIP-712 signing, see EIP-712 Signing.

Nonce Management

The nonce system prevents replay attacks and ensures order uniqueness:

  • Use current timestamp in milliseconds as nonce
  • Each nonce must be greater than the previous one
  • Recommended: Use Date.now() or equivalent
  • If nonce conflicts occur, increment by 1 and retry

Error Handling

Common error scenarios:

ErrorDescription
Invalid signatureEIP-712 signature validation failed
Invalid market symbolMarket symbol not recognized
Nonce already usedNonce must be greater than previous value
Rate limit exceededToo many requests in time window
Request expiredexpiresAfter timestamp has passed