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, getOrdersHistory, getTrades, getFundingPayments, getSubAccount, getSubAccounts, getDelegatedSigners, getBalanceUpdates) 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
