Skip to main content
The polynode API provides two main surfaces:
  1. V3 Historical Data — query the complete Polymarket V1 + V2 historical dataset. 1.2 billion fills, 228 million positions, 2.7 million wallets. Dual P&L (realized + unrealized), position tracking with settlement status, builder analytics, market search, and leaderboards.
  2. Real-time Streaming — live WebSocket feeds for settlements, trades, price updates, position changes, and more. See the WebSocket tab.
The V3 endpoints are live and provide the most comprehensive Polymarket dataset available.

V3 Data API — Base URL

Authentication

Every /v3/* endpoint requires an API key. Pass it either as a key query parameter or as a bearer token in the Authorization header:
Get a key from the dashboard. All examples in this section assume ?key=YOUR_KEY is appended (omitted only for brevity in the code blocks).

Dataset Scale

Query GET /v3/stats for live counts. Current scale:

Key features

  • Dual P&L — realized and unrealized profit/loss for every wallet, computed from the full event history using weighted-average cost basis math
  • Position status — every position is tagged as open, closed, redeemable, or redeemed based on live settlement data
  • Redeemable payouts — see exactly how much USDC a wallet can claim from resolved markets
  • Builder attribution — 77 million fills attributed to 1,502 unique builders
  • Batch queries — query up to 100 wallets in a single call
  • Time-range filters — filter trades, redemptions, and activity by Unix timestamp
  • Market search — full-text search across 1 million+ market questions

Amounts and precision

Monetary fields come in two conventions depending on the endpoint: Decimal USD (JSON number). Used by aggregated P&L responses (wallet summary, batch, pnl, positions) and by token-price responses (/v3/markets/{token_id}/price, /v3/tokens/{token_id}):
net_realized_pnl: 22053845.825455 means 22,053,845.83USD.price:0.42means22,053,845.83 USD**. `price: 0.42` means **0.42 per share (Polymarket outcome prices are always in the range 0–1). Raw 6-decimal USDC (JSON string). Used by event-level rows — fees, splits, merges, redemptions, NRC, activity, tag-leaderboard rollups, market-positions rows:
Divide by 1_000_000 to get USD. "120469388830" is 120,469.38883 USDC. Full-precision decimal (JSON string). Used by raw subgraph fields like volume_all_time, liquidity, price:
These are stored at full Postgres numeric precision (up to ~50 digits). Round on the client; do not parse as a JS Number. Each endpoint’s response-fields table explicitly notes which convention applies.

Identifiers and large numbers

Polymarket token_id and position_id values are 78-digit decimal integers (uint256). They are returned as JSON strings so they survive standard JSON parsers — IEEE 754 doubles cannot represent them. Treat them as opaque strings; do not parse them as numbers.

Nullable fields

Many fields can be null in real responses even when the example shows a populated value — typically when a row was created before the metadata pipeline backfilled it, or when a market hasn’t resolved yet. Each endpoint’s response-fields table has a Nullable column. Defensive clients should accept null for any field marked nullable, plus for any field whose row predates indexing.

Response envelopes

Endpoints fall into three envelope shapes: Standard ungrouped list responses also include rows_returned, has_more, offset, limit, and elapsed_ms. Grouped trade responses are the exception: with group_by=order_hash, the response includes trades, rows_returned, grouped_by, and elapsed_ms, but omits has_more, offset, and limit.

Timestamps

All Unix timestamps in responses are in seconds (e.g., "1778674056"). The resolved_at field in resolutions uses milliseconds (e.g., "1778674836000"). Datetime strings like updated_at are in UTC.

Rate limits

V3 REST data endpoints require a paid API key. Limits are shared across all API keys owned by the same account, so keys can be used at the same time without multiplying the account’s throughput. See Rate Limits for the full tier table and heavy-endpoint details.

Pagination

All list endpoints support:
  • ?limit=N — results per page (default 100, max 300)
  • ?offset=N — skip N results
Ungrouped responses include the actual limit used, plus has_more: true/false to indicate if more pages exist. Grouped trade requests still accept limit and offset, but their responses omit those fields and has_more; track the requested values and stop after an empty trades array. For deep trade-history walks, prefer after and before time windows instead of very large offsets.

Response format

Every response includes elapsed_ms showing server-side query time in milliseconds.

Endpoint categories

Explorer

Browse the data interactively with pre-built SQL recipes at explorer.polynode.dev.