Skip to main content
GET
/
v1
/
markets
/
{id}
/
positions
Market positions & P&L
curl --request GET \
  --url https://api.polynode.dev/v1/markets/{id}/positions \
  --header 'x-api-key: <api-key>'
{
  "condition_id": "0x895e01dbf3e6a33cd9a44ca0f8cdb5df1bd2b0b6ebed5300d28f8da7145145e4",
  "market_title": "Will Donald Trump win the 2028 Republican presidential nomination?",
  "slug": "will-donald-trump-win-the-2028-republican-presidential-nomination",
  "outcome_names": [
    "Yes",
    "No"
  ],
  "outcomes": [
    {
      "token": "3039641309958397001906153616677074061284510636203465131156925998487819889437",
      "positions": [
        {
          "proxyWallet": "0xa5ef39c3d3e10d0b270233af41cac69796b12966",
          "name": "",
          "outcome": "No",
          "outcomeIndex": 1,
          "size": 1735573.72,
          "avgPrice": 0,
          "currPrice": 0.9835,
          "currentValue": 1706936.75,
          "cashPnl": 1706936.75,
          "realizedPnl": 0,
          "totalPnl": 1706936.75
        },
        {
          "proxyWallet": "0xc2e7800b5af46e6093872b177b7a5e7f0563be51",
          "name": "beachboy4",
          "outcome": "Yes",
          "outcomeIndex": 0,
          "size": 248651.26,
          "avgPrice": 0.040276,
          "currPrice": 0.0165,
          "currentValue": 4102.75,
          "cashPnl": -5911.93,
          "realizedPnl": 0,
          "totalPnl": -5911.93,
          "firstTradeAt": 1753016057,
          "lastTradeAt": 1765034355
        }
      ]
    }
  ]
}

Documentation Index

Fetch the complete documentation index at: https://polynode.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

Returns every wallet with a position in a single market, broken out by outcome (e.g. Up/Down or Yes/No) and ranked by P&L. The natural feed for “top traders on this market” leaderboards, top-X-by-PnL widgets, and per-market trader audits. Path accepts either the market slug (e.g. btc-updown-5m-1777179000) or the condition_id (e.g. 0xa7ae8a41...). It does not accept an outcome token id — pass the market identifier, not the side.
Field shape is camelCase (avgPrice, realizedPnl, etc.) — distinct from polynode’s V2 onchain endpoints which use snake_case. Different schemas, different use cases. Default cap is 50 rows per outcome; configurable up to 500.

Request

GET /v1/markets/{slug-or-condition-id}/positions
ParameterTypeLocationDescription
idstringpathMarket slug or condition_id (0x…). Not an outcome token id.
limitintegerqueryMax rows per outcome. Default 50, max 500.
offsetintegerquerySkip first N rows.
sortBystringqueryTOTAL_PNL (default), REALIZED_PNL, CURRENT_VALUE, SIZE, INITIAL_VALUE.
sortDirectionstringqueryDESC (default) or ASC.
statusstringqueryOPEN, CLOSED, or ALL (default).
min_sizenumberqueryDrop positions with size < min_size from each outcome. Use min_size=0.0001 to filter to current holders only (excludes historical participants who closed out to zero).
includeTradesbooleanqueryWhen true, adds firstTradeAt / lastTradeAt (unix seconds) per row. Heavy — separate 20 req/min rate limit per key.
userstringqueryFilter to a single wallet, or up to 20 wallets comma-separated, scoped to this market.
TOTAL_PNL and REALIZED_PNL are sorted by Polymarket’s data-api directly. CURRENT_VALUE, SIZE, and INITIAL_VALUE are sorted in-process after the fetch (and after min_size if set), so they pair cleanly with the holder-filtering use case.

Response

{
  "condition_id": "0xa7ae8a4119fe00f231e693ed717339dd1e13da4617c79f3b1522ab1aee3965b6",
  "market_title": "Bitcoin Up or Down - April 26, 12:50AM-12:55AM ET",
  "slug": "btc-updown-5m-1777179000",
  "image": "https://polymarket-upload.s3.us-east-2.amazonaws.com/BTC+fullsize.png",
  "outcome_names": ["Up", "Down"],
  "outcomes": [
    {
      "token": "90684694382683135738693577247532961739938461809085935450142382916430459093778",
      "positions": [
        {
          "proxyWallet": "0x9a1d392572d0e6bfefbf9302101b9e44c8ee86d6",
          "name": "kq9000",
          "profileImage": "",
          "verified": false,
          "asset": "90684694382683135738693577247532961739938461809085935450142382916430459093778",
          "conditionId": "0xa7ae8a4119fe00f231e693ed717339dd1e13da4617c79f3b1522ab1aee3965b6",
          "outcome": "Up",
          "outcomeIndex": 0,
          "size": 0,
          "avgPrice": 0.4592,
          "currPrice": 1,
          "currentValue": 0,
          "totalBought": 1633.1987,
          "realizedPnl": 812.5754,
          "cashPnl": 0,
          "totalPnl": 812.5754,
          "firstTradeAt": 1777179030,
          "lastTradeAt": 1777179152
        }
      ]
    },
    { "token": "96824…", "positions": [ "…" ] }
  ]
}

Top-level fields

FieldTypeDescription
condition_idstringMarket condition id
market_titlestringHuman-readable market question
slugstringMarket slug
imagestringMarket image URL
outcome_namesstring[]Ordered outcome labels (["Up","Down"], ["Yes","No"], etc.)
outcomes[]arrayOne entry per outcome — each holds a positions array
outcomes[].tokenstringOutcome token id
outcomes[].positions[]arrayTraders with positions in this outcome, sorted by sortBy

Per-trader fields (outcomes[].positions[])

FieldTypeDescription
proxyWalletstringTrader address (Gnosis Safe proxy)
namestringDisplay name (often empty or auto-generated)
profileImagestringProfile image URL (often empty)
verifiedbooleanVerified flag
assetstringOutcome token id (same as outcomes[].token)
conditionIdstringMarket condition id
outcomestringOutcome label ("Up", "No", etc.)
outcomeIndexnumber0-based position in outcome_names
sizenumberCurrent token balance. 0 = fully exited or never held.
avgPricenumberVolume-weighted average entry price
currPricenumberCurrent market price (or terminal 1.0/0.0 for resolved markets)
currentValuenumberMark-to-market value of remaining shares (size × currPrice)
totalBoughtnumberLifetime tokens acquired
realizedPnlnumberRealized P&L from sells + redemptions, in USDC
cashPnlnumberP&L from cash flows (separate accounting axis)
totalPnlnumberNet portfolio P&L for this position
firstTradeAtnumberUnix seconds — only with ?includeTrades=true
lastTradeAtnumberUnix seconds — only with ?includeTrades=true

Examples

Top 10 traders on a market by total P&L

curl "https://api.polynode.dev/v1/markets/btc-updown-5m-1777179000/positions?limit=10&sortBy=TOTAL_PNL&sortDirection=DESC" \
  -H "x-api-key: YOUR_KEY"

By condition_id, with first/last trade timestamps

curl "https://api.polynode.dev/v1/markets/0xa7ae8a4119fe00f231e693ed717339dd1e13da4617c79f3b1522ab1aee3965b6/positions?includeTrades=true&limit=20" \
  -H "x-api-key: YOUR_KEY"

Drill into specific wallets within a market

curl "https://api.polynode.dev/v1/markets/btc-updown-5m-1777179000/positions?user=0x9a1d392572d0e6bfefbf9302101b9e44c8ee86d6,0x44bd2993a69d8b569859ed8c0bf0b946f733f71a" \
  -H "x-api-key: YOUR_KEY"

Closed positions only

curl "https://api.polynode.dev/v1/markets/btc-updown-5m-1777179000/positions?status=CLOSED&sortBy=REALIZED_PNL" \
  -H "x-api-key: YOUR_KEY"

Notes

  • Default cap of 50 rows per outcome unless limit is set higher (max 500). On very large markets with deep tail traders, paginate with offset.
  • Sort ties on equal P&L are non-deterministic — two wallets at the same totalPnl may swap positions between calls. Use proxyWallet as a stable secondary key on the client side if you need consistent ordering.
  • size = 0 is normal on closed positions, redeemed positions, or fully-exited positions. Use realizedPnl and totalBought to detect history.
  • firstTradeAt / lastTradeAt require ?includeTrades=true and trip a separate heavy-endpoint rate limit (20 req/min per key). Don’t request it on every refresh — fetch once and cache.

When to use this vs. other position endpoints

If you wantUse
Top traders ranked on a single marketThis endpoint
One wallet’s positions across all marketsGET /v2/wallets/{addr}/positions/onchain
All trades on a market (chronological fill feed)GET /v2/onchain/markets/{tokenId}/trades

Authorizations

x-api-key
string
header
required

Path Parameters

id
string
required

Condition ID (0x-prefixed) or market slug

Query Parameters

limit
integer
default:50

Maximum holders per outcome token (default 50, max 500)

Required range: 1 <= x <= 500
offset
integer
default:0

Pagination offset (default 0)

Required range: x >= 0
sortBy
enum<string>
default:TOTAL_PNL

Sort holders by field

Available options:
TOKENS,
CASH_PNL,
REALIZED_PNL,
TOTAL_PNL
sortDirection
enum<string>
default:DESC

Sort direction

Available options:
ASC,
DESC
status
enum<string>
default:ALL

Filter by position status

Available options:
OPEN,
CLOSED,
ALL
includeTrades
boolean
default:false

Enrich each position with firstTradeAt and lastTradeAt timestamps. Adds one upstream call per holder, so responses will be slower. Default false. Rate limited to 60 requests per minute per key (separate from your standard rate limit).

user
string

Filter to specific wallet address(es). Accepts a single address or multiple comma-separated addresses (max 20). Returns only those wallets' positions in this market.

Response

Market positions grouped by outcome token

Holder positions for a market, grouped by outcome token.

condition_id
string
required

Market condition ID.

outcomes
object[]
required

Array of outcome tokens, each containing a list of holder positions.

market_title
string

Market title (enriched by PolyNode).

slug
string

Market slug (enriched by PolyNode).

outcome_names
string[]

Outcome names (e.g. ["Yes", "No"]).