Polydata API v3

A fast analytics API for Polymarket — traders, leaderboards, markets, events, weather, whales, oracle accuracy and more. Everything is served straight from our database; no third-party API ever sits on the request path.

Closed beta. No SLA is in effect. Endpoints, response shapes and limits may change with notice. See beta terms.

Introduction

The API is organized into 13 verticals. Every endpoint returns JSON and carries the same tariff-metadata envelope, so you always know your plan, whether the result was trimmed, and what to upgrade for more.

All you need to make your first call: a base URL, an API key, and the X-API-Key header. Jump straight to the quickstart if you like.

Base URL

https://dev-api.polydata.pro/api/v3

All paths below are relative to this base. HTTPS only.

Authentication

Every request (except the public health/status probes) must send your API key in the X-API-Key header.

X-API-Key: pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  • Your key is delivered directly and once. We store only its SHA-256 hash — we cannot recover or re-send the raw key. Treat it like a password.
  • Missing / invalid / revoked key → HTTP 401.
  • Public probes that need no key: GET /health, GET /status, GET /status/public.

Plans & rate limits

Beta cohort default tier: explorer300 requests / 60 s (≈5 req/s).

TierRequests / 60 sHistory capCompare walletsExport
free3030 d1no
explorer (you)300180 d2no
trader1 000365 d3yes
alphavery highall10yes
Hitting the limit? You get HTTP 429 with a Retry-After header (seconds until the next window). Back off and retry after that delay. Need more during the beta? Ask us to bump your key to trader — no new key required.

Response envelope

Every response carries tariff metadata alongside the data. When you hit a plan cap the API does not hard-fail — it returns HTTP 200 with the result trimmed and truncated: true.

FieldMeaning
planYour effective tier for this call.
truncatedtrue if the result was trimmed by a plan cap.
lock_reasone.g. "plan_limit" when a feature is locked, else null.
upgrade_hintTier that would unlock more, or null.
available_sections / locked_sectionsWhat this tier can / cannot see.
max_history_daysHistory window cap (null = no cap / all history).
max_rowsRow cap for the current call.

Quickstart

# Health (no key needed)
curl https://dev-api.polydata.pro/api/v3/health

# Trader stats (with your key)
curl -H "X-API-Key: pk_live_xxxxxxxx" \
  "https://dev-api.polydata.pro/api/v3/trader/0x015458216dd5521addbe6f9e87a8a0e841ab5b34/stats"

# Top traders, 30-day window
curl -H "X-API-Key: pk_live_xxxxxxxx" \
  "https://dev-api.polydata.pro/api/v3/leaderboard/traders?period=30d"

A 200 with a JSON body means you're in. A 401 means the key header is missing or wrong; a 429 means you hit the rate limit (honor Retry-After).


Health & status

public · no key
GET/healthLiveness + database reachability.
GET/statusSame payload (legacy alias).
GET/status/publicPer-subsystem freshness grades for the public status page.
# Public — no key required
curl "https://dev-api.polydata.pro/api/v3/health"

Trader

{address} = lowercase 0x…
GET/trader/{address}/statsLifetime summary: trades, volume, active days, unique markets, username.
GET/trader/{address}/activity/daily?limit=90Per-day time series (max 365).
GET/trader/{address}/markets?limit=50Top markets by volume (max 200).
GET/trader/{address}/trades?limit=50Recent fills, keyset pagination (max 200).
GET/trader/compare?address=0x..&address=0x..Side-by-side compare (explorer: 2 wallets).
POST/trader/{address}/export-jobsQueue a snapshot export (trader/alpha only).
GET/trader/export-jobs/{job_id}Export job status.
GET/trader/export-jobs/{job_id}/downloadDownload finished export.
# Lifetime stats for one wallet
curl -H "X-API-Key: pk_live_xxxxxxxx" \
  "https://dev-api.polydata.pro/api/v3/trader/0x015458216dd5521addbe6f9e87a8a0e841ab5b34/stats"

Leaderboard

period = 1d · 7d · 30d
GET/leaderboard/traders?period=30dTop traders ranked by total PnL (real_pnl, realized + unrealized). See disclaimer.
GET/leaderboard/markets?period=30dTop markets by volume.
# Top traders by realized PnL (30-day window)
curl -H "X-API-Key: pk_live_xxxxxxxx" \
  "https://dev-api.polydata.pro/api/v3/leaderboard/traders?period=30d"

Market

{condition_id} = String PK
GET/market/{condition_id}/overviewMetadata + all-time aggregates + resolution + recent fills.
GET/markets/search?q=...Search markets by title (explorer: up to 50 rows).
# Search markets by title
curl -H "X-API-Key: pk_live_xxxxxxxx" \
  "https://dev-api.polydata.pro/api/v3/markets/search?q=bitcoin"

Event

GET/event/{event_id}Event metadata + aggregate rollup.
GET/event/{event_id}/markets?limit=&offset=Markets belonging to the event.
GET/event/{event_id}/traders?limit=&offset=Top traders on the event.
# Event metadata + aggregate rollup
curl -H "X-API-Key: pk_live_xxxxxxxx" \
  "https://dev-api.polydata.pro/api/v3/event/12345"

Platform stats

cache-first
GET/statsPlatform overview: volume, active markets, traders.
GET/stats/hourlyLast-24h hourly activity.
GET/stats/daily?days=Per-day platform rollup.
GET/stats/growthGrowth / trend metrics.
# Platform overview (volume, active markets, traders)
curl -H "X-API-Key: pk_live_xxxxxxxx" \
  "https://dev-api.polydata.pro/api/v3/stats"

PMX Index

open on all tiers
GET/pmx-indexCurrent snapshot: composite + 5 sub-indices.
GET/pmx-index/{name}/history?interval=1h|6h|1dHistory of one sub-index. name ∈ {PMX-Volume, PMX-Whale, PMX-Politics, PMX-Crypto, PMX-Sentiment}.
# Current composite + 5 sub-indices
curl -H "X-API-Key: pk_live_xxxxxxxx" \
  "https://dev-api.polydata.pro/api/v3/pmx-index"

Oracle (PolyOracle)

Brier score · calibration
GET/oracle/leaderboardTop traders by forecasting accuracy.
GET/oracle/trader/{address}Accuracy breakdown for one wallet.
# Top forecasters by accuracy (Brier score)
curl -H "X-API-Key: pk_live_xxxxxxxx" \
  "https://dev-api.polydata.pro/api/v3/oracle/leaderboard"

Whales

GET/whalesTop wallets by size / activity (each row carries total real_pnl; see disclaimer).
GET/whales/movesRecent large trades.
GET/whales/flow?market_id=Net whale flow (optionally per market).
# Recent large trades
curl -H "X-API-Key: pk_live_xxxxxxxx" \
  "https://dev-api.polydata.pro/api/v3/whales/moves"

Screener

GET/screenerAdvanced market filtering.
GET/screener/summaryAggregate screener summary.
# Advanced market filtering
curl -H "X-API-Key: pk_live_xxxxxxxx" \
  "https://dev-api.polydata.pro/api/v3/screener"

Research & export

export → trader/alpha
GET/research/datasetsCatalog of exportable datasets.
POST/research/export-jobsQueue a CSV/Parquet dataset export.
GET/research/export-jobs/{job_id}Export job status.
GET/research/export-jobs/{job_id}/downloadDownload finished export.
# Catalog of exportable datasets
curl -H "X-API-Key: pk_live_xxxxxxxx" \
  "https://dev-api.polydata.pro/api/v3/research/datasets"

Weather

9 endpoints
GET/weather/citiesCity grid + live events, forecasts, and volume rollups. Returns top-level volume_24h_total (vertical daily headline) plus per-city lifetime / 24h / 7d fields.
GET/weather/city/{city}City card: forecasts, actuals, anomaly, and the same volume fields as one row in /weather/cities.
GET/weather/city/{city}/forecastMulti-source TMAX/TMIN forecast time series.
GET/weather/city/{city}/actualsObserved daily highs/lows.
GET/weather/city/{city}/anomaliesDeviation vs climate normals.
GET/weather/city/{city}/marketsActive temperature brackets + per-market trade stats (volume there is lifetime on the bracket).
GET/weather/tradersTop weather-market traders.
GET/weather/forecast-evolution/{city}/{date}How a forecast for a date evolved over time.
GET/weather/bot-bundleCompact multi-city snapshot for bots.
Volume semantics (important). On /weather/cities and /weather/city/{city}, volume and volume_lifetime are cumulative USD all-time for that city's temperature markets — do not use them for “traded today” headlines. Use volume_24h (UTC calendar day so far) or the vertical sum volume_24h_total on /weather/cities. volume_7d covers the last 7 UTC calendar days incl. today. volume_as_of is the UTC timestamp when rollups were computed.

Key response fields on GET /weather/cities:

FieldScopeMeaning
volume_24h_totalresponseSum of all cities' volume_24h — use for daily weather vertical headlines.
volume_lifetime_totalresponseSum of all cities' lifetime volume (≈ historical cumulative; stable day-to-day).
volume_7d_totalresponseSum of all cities' 7-day rolling volume.
volume_24heach cityUSD traded today (UTC calendar day).
volume_7deach cityUSD over last 7 UTC calendar days.
volume / volume_lifetimeeach citySame value — cumulative all-time USD (backward-compatible alias).
open_count / market_counteach cityActive brackets / events from live snapshot; falls back to rollup when live sync is empty.
# City grid — use volume_24h_total for "traded today", not sum(volume)
curl -H "X-API-Key: pk_live_xxxxxxxx" \
  "https://dev-api.polydata.pro/api/v3/weather/cities"

# Single city — volume_24h vs volume_lifetime
curl -H "X-API-Key: pk_live_xxxxxxxx" \
  "https://dev-api.polydata.pro/api/v3/weather/city/nyc"

What real_pnl means

The real_pnl value on /trader/*, /whales and the rank on /leaderboard/traders is realized PnL, matching the figure shown on a trader's Polymarket profile ("Profit") and on Polymarket's leaderboard API (responses report pnl_method = "cash_basis_v3"):

real_pnl = (USDC received on sells − USDC paid on buys, across all your trades) + redemption value of the winning side on resolved markets.

Open positions are excluded — exactly like the Polymarket headline number. Polymarket shows the current value of your open positions as a separate figure, not inside "Profit". (An earlier version of this API added open-position mark-to-market into real_pnl; that made active traders read higher than the site, so it was removed.)

Known limitations:

  • Open-position value is not yet exposed. We omit a separate open/unrealized field for now rather than publish an inaccurate one (our last-trade marks underprice open books vs Polymarket).
  • Residual overcount on a few high-volume market-makers. Winning tokens that leave a wallet via peer-to-peer ERC-1155 transfers or umbrella (NegRisk) redemptions have no matching sell trade, so a small set of MM/arbitrage wallets can read a few percent above the site.
  • Resolutions we don't yet have a winner record for. A class of short-term markets (minute-scale crypto Up/Down, dated sports) is archived upstream faster than our sync captures the resolution; those positions read low until the resolution lands.

/trader/{address}/stats also returns realized_pnl (== real_pnl), roi (real_pnl / buy_volume_usd, approximate), win_rate (the share of your resolved markets that closed in profit; null when you have no resolved markets) and pnl_method. unrealized_pnl (open-position value) is reserved and always null for now.

Status page

Live system health (no login):

https://dev-api.polydata.pro/api/v3/status/public   # raw JSON
https://polydata.pro/status                          # human-readable page

If you see elevated errors, check the status page before contacting support — it shows per-subsystem freshness (serving tables, trades, markets).

Support & beta terms

Pre-GA. Endpoints, response shapes, and limits may change with notice. Export jobs are best-effort. No uptime SLA during the beta.

You're in the beta because your feedback shapes GA. Please report any number that looks wrong (send the wallet/market + what you expected), latency spikes, 5xx errors, or endpoints/fields you wish existed.

Contact: support@polydata.pro (or your direct beta channel).