Skip to main content
Polymarket data is a four-level hierarchy. History endpoints sit on markets and tokens. Discovery endpoints sit on the layers above them.

Identifiers

Discovery objects include both an id and a slug. History routes accept either on {id_or_slug}.
Persist the exact id or slug you used, plus the timestamp when you built the universe. Discovery results change as markets open and resolve. If the universe drifts, backtests are not comparable.
Token-level history uses {token_id}:
  • GET /v1/tokens/{token_id}/prices
  • GET /v1/tokens/{token_id}/books
Market-level price and book endpoints return every token in the market. If a market has more than 200 tokens, those endpoints refuse the request and tell you to query one token at a time.

Timestamps

Keep the pipeline in UTC.
  • Discovery date filters use ISO 8601 timestamps.
  • History start_ts is inclusive. end_ts is exclusive.
  • Both accept ISO 8601 (2025-09-01T00:00:00Z) or Unix seconds (1756684800).
  • History rows expose t as ISO 8601.
Convert to local time only for display. Mixing naive and aware datetimes, or dropping timezone info, shifts signals by hours without an obvious error.

Resolutions

History endpoints require resolution. Allowed values: 1m, 10m, 1h, 6h, 1d. Your plan’s finest allowed resolution comes back on GET /v1/usage as limits.granularity_allowed. Requesting a finer bucket returns 403.

What each history family is for

  • Prices — token probability from 0.0 to 1.0. Field name is p.
  • Metrics — market-level volume, liquidity, and spread.
  • Booksbids and asks as [price, size] arrays, best level first.
Join prices to metrics before you backtest. Price bars alone do not tell you whether a print was tradable at your size. Even a simple spread filter changes which setups survive.