Skip to main content
REST endpoints for Polymarket CLOB v2 data. Every endpoint returns JSON enriched with market metadata (question, slug, outcome label, image, condition_id) baked in — you never need to look up a market name separately. This is the v2-only surface. The existing /v2/onchain/* endpoints cover v1 Polymarket. Use /clobv2/* for anything that needs v2 fills, positions, builder attribution, or neg-risk events.

Collateral token: pUSD

v2 trades settle in pUSD (Polymarket USD), an ERC-20 on Polygon at 0xc011a7e12a19f7b1f670d46f03b03f3342e82dfb. Every pUSD is backed 1:1 by USDC.e and the backing is enforced on-chain by the contract, so dollar amounts are exact. Fields named *_usdc in the response schemas (maker_usdc, taker_usdc, fee_usdc, notional_usdc, etc.) are the pUSD amounts of each fill. The “usdc” suffix is a holdover from v1 and reflects the dollar value — it does NOT mean USDC.e was the token that moved. If you’re verifying on-chain against Polygonscan, look for Transfer events on the pUSD contract above, not the USDC.e contract. Why you care:
  • Integrators: an API user wrapping USDC.e → pUSD via Polymarket’s Collateral Onramp will see their wallets/{address}/trades results denominated in the same units their pUSD balance moved.
  • Historical data: early v2 fills (pre-mainnet-launch on April 28, 2026) may show mixed pUSD / USDC.e transfers on-chain as wallets migrated; the aggregated amounts our API returns remain dollar-correct because 1 pUSD = 1 USDC.e.
  • v1 data: the legacy /v2/onchain/* endpoints are v1 Polymarket and genuinely denominated in USDC.e. Different exchange, different collateral.

Base URL

https://api.polynode.dev/clobv2/

Authentication

Every endpoint requires a paid-tier API key (starter and up). Free-tier keys receive 402 Payment Required. Pass your key by any of three methods:
curl "https://api.polynode.dev/clobv2/trades?limit=10" \
  -H "x-api-key: pn_live_..."
Never pass the key in a URL you’d share publicly — the query-param form is fine for local scripts but logs it to server access logs.

Endpoints

Fills

EndpointPurpose
GET /clobv2/tradesGlobal v2 fills feed, filterable by wallet, market, builder, time, size.
GET /clobv2/wallets/{address}/tradesPer-wallet fill history with side always present.
GET /clobv2/markets/{token_id}/tradesPer-outcome-token fill history.

Positions

EndpointPurpose
GET /clobv2/positionsEvery open/closed v2 position across all wallets, filterable by wallet, market, token, size.

Market aggregates

EndpointPurpose
GET /clobv2/markets/{token_id}/volumeLifetime buy/sell counters from per-fill aggregation.
GET /clobv2/markets/{token_id}/orderbookLifetime counters from the subgraph’s orderbook rollup entity.
GET /clobv2/candles/{token_id}OHLCV candles at 1m/5m/15m/1h/4h/1d resolutions, with VWAP and buy/sell split.
GET /clobv2/volume/hourlyPlatform-wide hourly volume buckets.

Builders (v2-exclusive)

EndpointPurpose
GET /clobv2/buildersLeaderboard of every builder that has attributed a v2 fill, ranked by notional.

Neg-risk events (v2-exclusive)

EndpointPurpose
GET /clobv2/neg-risk/eventsParent events (PGA winners, NBA MVP, elections) with full outcome lists.
GET /clobv2/neg-risk/events/{parent_id}/childrenEvery child market inside one event, ranked by volume.

Numeric precision

All USDC / share / price fields in list responses are returned as JSON strings (e.g. "1.3440000000000000", not 1.344) to preserve full database precision. Parse to Decimal / BigNumber / bignumber.js before arithmetic. Integer counts (trade counts, market counts) remain JSON numbers. Single-object market-volume + market-orderbook responses return numbers for convenience.

Response envelope

Every list endpoint wraps results the same way:
{
  "count": 25,
  "source": "onchain-v2",
  "pagination": {
    "limit": 100,
    "offset": 0,
    "has_more": false
  },
  "<collection_name>": [ ... ]
}
  • count: the number of rows in this response.
  • source: always "onchain-v2" for clobv2 endpoints — identifies this as v2 exchange data.
  • pagination: standard offset-based. has_more: true means you can fetch offset += count to get the next page.
  • The array field name matches the endpoint (trades, positions, events, etc.).
Single-object endpoints (e.g. volume, orderbook-rollup) skip the pagination object and include a found boolean.

Rate limits

Every response carries:
x-ratelimit-limit: 100000
x-ratelimit-remaining: 99997
x-ratelimit-reset: 1776665478
Limits are per-API-key over a rolling 60-second window. When exceeded you get 429 Too Many Requests with {"error": "rate limit exceeded", "reset_at": <unix>}.

Error shape

StatusMeaning
400Parameter validation failed (bad hex format, bad enum, out-of-range integer). Body: {"error": "..."}.
401No API key or bad/revoked key.
402Free-tier key — paid plan required.
429Rate limit exceeded.
5xxTransient upstream issue. Clients should retry with backoff.
All error bodies follow {"error": "<human readable>"}. 402 also includes tier and upgrade_url fields.

Known stubs

These endpoints exist on the server but are not yet documented because their supporting historical datasets are still being completed:
  • /clobv2/wallets/{address}/redemptions
  • /clobv2/wallets/{address}/activity
  • /clobv2/markets/{condition_id}/oi
  • /clobv2/oi
They currently return the empty-shape response (count/volume fields zeroed). When coverage is complete, they’ll return populated data and get their own doc pages — no API contract change.