List Positions
Retrieves all current positions held in a portfolio, including token balances, their USD values and unrealized profit and loss. Positions are ordered by current USD value, largest first. Supports cursor-based pagination for efficient handling of large position datasets.
Endpoint
Portfolio API: GET https://ddp.definitive.fi/v2/portfolio/positions
Organization API: Replace
/v2/portfolio/with/v2/organization/portfolios/{portfolioId}/. See Portfolio vs. Organization API.
Query Parameters
| Parameter | Type | Required | Description | Default |
|---|---|---|---|---|
| limit | number | No | Maximum number of positions to return (1-100) | 20 |
| cursor | string | No | Opaque cursor from the previous response | - |
| includeDustBalances | string | No | "true" to include positions with notional value less than $1.00 | "false" |
Examples
const json = await AuthHelpers.signAndSend({
path: "/v2/portfolio/positions",
method: "GET",
queryParams: { limit: "20" },
apiKey: process.env.API_KEY,
apiSecret: process.env.API_SECRET,
});Response
{
positions: [
{
asset: {
id: string, // e.g. "00000000-0000-0000-0000-000000000001"
name: string, // e.g. "USD Coin"
ticker: string, // e.g. "USDC"
address: string, // e.g. "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
chain: {
id: string, // e.g. "8453"
name: string, // e.g. "Base"
namespace: string // e.g. "eip155"
}
},
balance: number, // e.g. 1000.50
balanceExact: string, // e.g. "2560.541327525718100163" (no precision loss)
notional: number, // e.g. 1000.50 (in USD)
vaultId: string, // e.g. "00000000-0000-0000-0000-000000000003"
portfolioId: string, // e.g. "00000000-0000-0000-0000-000000000002"
entryPrice: string, // e.g. "1000.50"
profitAndLoss: string, // e.g. "40.11"
profitAndLossPercent: string // e.g. "24.6" (as in 24.6%)
}
// ... additional positions
],
nextCursor: string | null, // opaque value to pass unchanged, or null if no more pages
hasMore: boolean, // true if more positions are available
limit: number // e.g. 20
}Pagination
This endpoint uses cursor-based pagination for optimal performance:
- First Request: Make a request without a
cursorparameter - Subsequent Requests: Use the
nextCursorvalue from the previous response - End of Data: When
hasMoreisfalse, there are no more positions to fetch - Cursor Value: Treat the cursor as opaque and pass it back unchanged
Pagination Example
let cursor = null;
let allPositions = [];
do {
const queryParams = { limit: "20" };
if (cursor) queryParams.cursor = cursor;
const response = await AuthHelpers.signAndSend({
path: `/v2/organization/portfolios/${portfolioId}/positions`,
method: "GET",
apiKey: process.env.API_KEY,
apiSecret: process.env.API_SECRET,
queryParams,
});
allPositions.push(...response.positions);
cursor = response.nextCursor;
} while (response.hasMore);