size, avg_price, realized_pnl, and total_bought for every (wallet, token) pair the v2 exchange has ever touched. Joined to market metadata so every row carries question, slug, outcome, image, and condition_id.
Backed by the v2.position view. A position is considered closed when size = 0; otherwise open.
Request
Authentication
Paid tier required. Pass your API key viax-api-key, Authorization: Bearer, or ?key=:
402 Payment Required.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
wallet | string | No | Filter by wallet address (0x + 40 hex). |
token_id | string | No | Filter by outcome token ID (uint256 as decimal string). |
condition_id | string | No | Filter by market condition_id (0x + 64 hex) β returns positions on every outcome of that market. |
status | string | No | open (size > 0), closed (size = 0), or all (default). |
min_size | number | No | Minimum size (in outcome shares). |
limit | integer | No | Results per page (1-500, default 100). |
offset | integer | No | Skip this many results (0-10000000, default 0). |
order | string | No | desc (largest position first, default) or asc (smallest first). |
Parameter validation
wallet: regex^0x[a-f0-9]{40}$.condition_id: regex^0x[a-f0-9]{64}$.token_id: 1-78 digits,^[0-9]+$.status: whitelist{open, closed, all}.order: whitelist{asc, desc}.
400 Bad Request with {"error": "..."}.
Response
Response fields
| Field | Type | Description |
|---|---|---|
count | integer | Number of positions in this page. |
source | string | Always "onchain-v2". |
pagination.limit / offset / has_more | Same as /clobv2/trades. | |
positions[].wallet | string | 20-byte address holding the position. |
positions[].token_id | string | Outcome token ID (uint256 as decimal string). |
positions[].condition_id | string | 32-byte market condition_id. |
positions[].size | string (numeric) | Outcome tokens held, already scaled /1e6. Zero means the position is closed. |
positions[].avg_price | string (numeric) | Volume-weighted average entry price, 0.0β1.0. |
positions[].total_bought_usdc | string (numeric) | Cumulative USDC spent acquiring this position. |
positions[].realized_pnl_usdc | string (numeric) | Realized P&L in USDC from partial or full exits. Can be negative (losses). |
positions[].status | string | "open" if size > 0, else "closed". |
positions[].question | string | null | Market question. |
positions[].event_title | string | null | Parent event title. |
positions[].slug | string | null | Polymarket URL slug. |
positions[].image | string | null | CDN URL of the market icon. |
positions[].outcome | string | Outcome label ("Yes", "No", "Up", neg-risk candidate name, etc.). |
Rate-limit headers
Every response includes:Examples
Error responses
| Status | Body | When |
|---|---|---|
400 | {"error": "invalid wallet address ..."} or {"error": "status must be one of [open, closed, all]"} | Parameter validation failed. |
401 | {"error": "missing API key ..."} or {"error": "invalid or revoked API key"} | No key or bad key. |
402 | {"error": "paid plan required ..."} | Free tier. |
429 | {"error": "rate limit exceeded", "reset_at": <unix>} | Rate limit hit. |
5xx | {"error": "temporary_data_provider_error"} | Temporary data provider issue. Retry with backoff. |
Notes
- A position exists as soon as a wallet has touched a token on v2, even after itβs been closed (
size = 0). Closed positions still carry theirrealized_pnl_usdcfor historical accounting. total_bought_usdcis cumulative USDC spent acquiring β it does NOT decrease on partial exits. Use it for true cost basis.- On neg-risk markets (multi-outcome events like PGA winners), a wallet can hold positions on many outcomes under the same
event_title. Each outcome is its owncondition_id. - Positions with
size = 0andrealized_pnl = 0andtotal_bought = 0exist when a wallet held a position and fully transferred it off-chain without realizing PnL. - Numeric fields are returned as strings β parse to
Decimal/BigNumberbefore math.

