Skip to main content
GET
Market positions & P&L
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

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

Top-level fields

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

Examples

Top 10 traders on a market by total P&L

By condition_id, with first/last trade timestamps

Drill into specific wallets within a market

Closed positions only

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

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. 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"]).