Get Trades For Position
Retrieve trade execution history (fills) for a specific position within a subaccount. Unlike getTrades, which returns all trades for a subaccount, this endpoint filters trades to those associated with a single position identified by positionId.
Endpoint
POST https://papi.synthetix.io/v1/tradeRequest
Request Format
{
"params": {
"action": "getTradesForPosition",
"subAccountId": "1867542890123456789",
"positionId": "42",
"limit": 100,
"offset": 0
},
"expiresAfter": 1704067300,
"signature": {
"v": 28,
"r": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"s": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
}
}Request Parameters
Action Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
params | object | Yes | Request parameters wrapper |
params.action | string | Yes | Must be "getTradesForPosition" |
params.subAccountId | string | Yes | SubAccount ID that owns the position |
params.positionId | string | Yes | Position ID to retrieve trades for (numeric string) |
params.limit | integer | No | Maximum number of trades to return (default: 100, max: 1000) |
params.offset | integer | No | Number of trades to skip for pagination (default: 0) |
Common Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
nonce | uint64 | Yes* | Positive integer nonce (must be incrementing and unique per request) |
signature | object | Yes | EIP-712 signature object |
expiresAfter | uint64 | No | Unix milliseconds expiration timestamp (5x rate limit on stale cancels) |
:::info Common Parameters
These are top-level request parameters. The subAccountId parameter is specified within the params object (see each endpoint's parameter table).
:::
:::info SubAccountAction Endpoints
Endpoints using SubAccountAction signing (getPositions, getOpenOrders, getOrderHistory, getTrades, getFundingPayments, getSubAccount, getSubAccounts, getDelegatedSigners, getBalanceUpdates, getWithdrawableAmounts, getFeeRate, getSnaxpotEpochTickets) do not require the nonce parameter. Only signature and optional expiresAfter are needed.
:::
| Parameter | Type | Required | Description |
|---|---|---|---|
expiresAfter | integer | No | Optional expiration timestamp in seconds |
Response
Response Structure
| Field | Type | Description |
|---|---|---|
status | string | Always "ok" for successful requests or "error" for failures |
response | object | Response object containing trades array and pagination info (omitted when status is "error") |
response.trades | array | Array of trade objects for the specified position |
response.trades[].orderType | string | Order type that produced this trade: "limit", "market", "stopMarket", "takeProfitMarket", "stopLimit", or "takeProfitLimit" |
response.hasMore | boolean | Whether more trades exist beyond current result |
error | object | Error details (only present when status is "error") |
request_id | string | Request tracking identifier |
Success Response Examples
Trades for a Position
{
"status": "ok",
"response": {
"trades": [
{
"tradeId": "123456789",
"order": {
"venueId": "1948058938469519360",
"clientId": "cli-1948058938469519360"
},
"orderId": "1948058938469519360",
"symbol": "BTC-USDT",
"side": "buy",
"direction": "open long",
"orderType": "limit",
"price": "50000.50",
"quantity": "0.1",
"realizedPnl": "0.00",
"fee": "5.00",
"feeRate": "0.001",
"markPrice": "50025.00",
"entryPrice": "50000.50",
"timestamp": 1704067200500,
"maker": false,
"reduceOnly": false,
"triggeredByLiquidation": false,
"postOnly": false
},
{
"tradeId": "123456790",
"order": {
"venueId": "1948058938469519361",
"clientId": "cli-1948058938469519361"
},
"orderId": "1948058938469519361",
"symbol": "BTC-USDT",
"side": "buy",
"direction": "open long",
"orderType": "market",
"price": "50100.00",
"quantity": "0.05",
"realizedPnl": "0.00",
"fee": "2.51",
"feeRate": "0.001",
"markPrice": "50110.00",
"entryPrice": "50033.67",
"timestamp": 1704067201000,
"maker": false,
"reduceOnly": false,
"triggeredByLiquidation": false,
"postOnly": false
}
],
"hasMore": false
},
"request_id": "5ccf215d37e3ae6d"
}Empty Result Set
{
"status": "ok",
"response": {
"trades": [],
"hasMore": false
},
"request_id": "5ccf215d37e3ae6f"
}Trade Object
| Field | Type | Description |
|---|---|---|
tradeId | string | Unique trade execution identifier |
order | object | Canonical composite order identifier |
order.venueId | string | Venue-generated order identifier |
order.clientId | string | Optional client-provided order identifier |
orderId | string | Deprecated legacy venue identifier |
orderType | string | Order type that produced this trade: "limit", "market", "stopMarket", "takeProfitMarket", "stopLimit", or "takeProfitLimit" |
symbol | string | Market symbol (e.g., "BTC-USDT") |
side | string | Trade side: "buy" or "sell" |
price | string | Actual filled price of this trade |
quantity | string | Actual filled quantity of this trade |
realizedPnl | string | Realized P&L from position closure |
fee | string | Trading fee amount |
feeRate | string | Fee rate applied |
timestamp | integer | Trade timestamp (Unix milliseconds) |
maker | boolean | true if maker order, false if taker |
reduceOnly | boolean | true if trade reduced existing position |
postOnly | boolean | true if order was post-only (maker-only) |
markPrice | string | Mark price at time of trade |
entryPrice | string | Position average entry price at time of trade |
triggeredByLiquidation | boolean | true if triggered by liquidation |
direction | string | Position direction after trade |
Trade Field Explanations
| Field | Description |
|---|---|
tradeId | Unique identifier for this specific trade execution |
order.venueId | Canonical venue-generated order ID for this trade |
order.clientId | Optional client-provided order ID for this trade |
orderId | Deprecated legacy order ID field |
orderType | Type of order that generated this trade: "limit", "market", "stopMarket", "takeProfitMarket", "stopLimit", or "takeProfitLimit" |
price | Actual execution price at which this trade was filled (not the mark price or entry price) |
quantity | Actual filled quantity for this trade execution |
realizedPnl | Profit/loss realized from this trade |
fee | Trading fee charged for this execution |
feeRate | Fee rate applied (maker/taker rate) |
markPrice | Mark price at time of trade execution (used for unrealized P&L and liquidations) |
entryPrice | Position's average entry price at time of trade (weighted average of all entries) |
maker | Whether this trade provided liquidity (maker) or took liquidity (taker) |
reduceOnly | Whether this trade reduced an existing position |
triggeredByLiquidation | Whether this trade was part of a liquidation |
postOnly | Whether this order was post-only (maker-only) |
Error Response
{
"status": "error",
"error": {
"message": "positionId is required",
"code": "VALIDATION_ERROR"
},
"request_id": "5ccf215d37e3ae6d"
}Examples
Get All Trades for a Position
{
"params": {
"action": "getTradesForPosition",
"subAccountId": "1867542890123456789",
"positionId": "42"
},
"expiresAfter": 1704067300,
"signature": {
"v": 28,
"r": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"s": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
}
}Paginated Request
{
"params": {
"action": "getTradesForPosition",
"subAccountId": "1867542890123456789",
"positionId": "42",
"limit": 50,
"offset": 100
},
"expiresAfter": 1704067300,
"signature": {
"v": 28,
"r": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"s": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
}
}EIP-712 Signature
const domain = {
name: "Synthetix",
version: "1",
chainId: 1,
verifyingContract: "0x0000000000000000000000000000000000000000"
};
const types = {
SubAccountAction: [
{ name: "subAccountId", type: "uint256" },
{ name: "action", type: "string" },
{ name: "expiresAfter", type: "uint256" }
]
};
const message = {
subAccountId: "1867542890123456789",
action: "getTradesForPosition",
expiresAfter: 0
};
const signature = await signer._signTypedData(domain, types, message);Implementation Notes
- Requires a valid subaccount ID (authenticated via EIP-712 signature)
positionIdis required and must be a valid numeric string- Pagination supports up to 1000 trades per request (default: 100)
- Offset must be non-negative
- The
directionfield indicates the position effect (e.g.,"open long","close long","open short","close short") - Unlike
getTrades, this endpoint does not supportsymbol,orderId,startTime, orendTimefilters — it returns all trades for the specified position - The response does not include a
totalcount field; usehasMorefor pagination
Error Handling
Common Errors
| Error | Description | Solution |
|---|---|---|
positionId is required | Missing position ID | Provide positionId in request params |
positionId must be a valid numeric value | Non-numeric position ID | Use a numeric string for positionId |
subaccountId is required | Missing subaccount | Include subAccountId in request params |
Invalid limit | Limit exceeds maximum or is negative | Use limit between 0 and 1000 |
Invalid offset | Negative offset value | Use offset >= 0 |
Authentication failed | Invalid signature | Verify signature generation |
Unauthorized access | No permission for specified subAccountId | Ensure you have access to the specified subaccount |
500 Internal Server Error | Trade history contains an unrecognized direction value (e.g. "unknown", "", or any unexpected string) | Indicates corrupted trade direction data on the backend that requires operator investigation. Previously these cases were silently defaulted to side: "buy" in the response. |
Rate Limiting
- Each request counts as 1 against rate limits
- See Rate Limits for details
Next Steps
- Get Trades - Retrieve all trades for a subaccount
- Get Positions - Query current positions
- Get Position History - Query closed position history
- WebSocket Trading - Real-time trade updates