Sign each request with a fresh HMAC signature. The cURL and HTTP header values below are placeholders, not reusable credentials. For runnable signing code, use request signing examples.
analytics.read). Each successful response costs 1 API credit.
- Venue: Polymarket only. There is no
venueparameter. - Exchange scope: CTF Exchange V1 and V2 (
exchange_scope: "ctf_v1_v2"on every response). Markets created on ExchangeV3 (combo markets, live since about 2026-11-02) are not covered yet. - Predexon-compatible names.
entries[],rank,user,position_shares,position_value_usd,avg_price,realized_pnl,unrealized_pnl,trade_count,first_trade_at,last_trade_at,paginationandtotal_countuse Predexon’s names, so you can switch base URLs. The other fields are additions. - Same numbers as positions. Each row has the same shares, mark, cost, realized and unrealized PnL as the matching row of
GET /v2/polymarket/positionsfor that wallet and token.
GET /v2/polymarket/market/{condition_id}/top-holders
yes returns holders of the first outcome (outcome_index 0) only. no returns holders of the second outcome (outcome_index 1) only. Omit it to get both outcomes.Keep positions holding at least this many shares. A positive decimal with at most 6 decimal places.
Keep holders with at least this many trades in this market. Must be
1 or more. Holders with no trade record in this market are excluded.true also fills total_count, total_holders and unseeded_holders. Otherwise those fields are null.Rank by
shares, value (position value at the current mark), pnl (realized + unrealized) or trades (trade count in this market). Always descending. A holder whose figure is unknown sorts last in every sort.The
pagination.pagination_key of the previous page. It only works with the same side, min_shares, min_trades and sort. A key from a different query is refused with a 400.400. They are never ignored.
Response
One object per (holder, outcome token), in rank order. The fields are in the table below.
Wallets holding this market whose balance is not yet known. They are counted here but not ranked.
null unless include_count=true.Always
ctf_v1_v2: the CTF Exchange V1/V2 facts. ExchangeV3 (combo) fills are not included yet.Always
market: trade_count, first_trade_at and last_trade_at count this market only, not the wallet’s lifetime.Unknown is
null, never 0. For many open holders, the cost of their shares cannot yet be attributed. Those rows have cost_source: "unknown", with avg_price, cost_basis, unrealized_pnl and total_pnl all null. Do not read null as a zero cost or a breakeven position.Ordering and paging
Ties are broken by wallet, then token id. Paging is keyset-based, so a page never repeats or skips a row while the data does not change. Withsort=value or sort=pnl, rows are ordered by live marks, so a page boundary is exact only while the marks hold between your two requests. shares and trades are exact.
Errors
Two layers answer a
400, and their envelopes differ. The API edge sends {"error": "<message>", "code": "unknown_param" | "invalid_param", "param": "<name>"}. The analytics service sends {"error": "BAD_REQUEST" | "NOT_FOUND" | "UNAVAILABLE", "message": "<message>"}. Read the typed code from code when it is present, otherwise from error.
Related
- Global positions: the same rows for any wallet, market or token.
- Market volume chart: the market’s traded volume over time.