/v2/prices-historyGet a token's price history
The price-history series for one outcome token, or a single point-in-time observation. Three window forms, exactly one per request: `start` (with optional `end`), `interval`, or `as_of`. Points are served oldest-first; pass `?cursor=` from a prior response's `next_cursor` for the next page.
- Base URL
- https://data-api.polymarket.com
- Auth
- Public, no key
- Rate limit
- 200 req / 10s (20 per second)
- Limit applies to
- /v2/prices-history
Things to know
Every v2 response wraps its payload in a data field. Paginated reads return an opaque cursor in pagination and do not accept offset. Under load the API answers 429 with a Retry-After header.
In our test on 29 September 2026 this returned 60-second buckets for a 5-minute market up to 8 days old and nothing for markets 15 days or older. Do not rely on it for history beyond about a week.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| token_id | query | stringnull | yes | Outcome token id (the CLOB asset id the chart is keyed by). Required. `tokenId` is an accepted alias. |
| start | query | integernull | no | Window start, epoch seconds, INCLUSIVE. Alone it means "up to the present", and is capped at 15 days back from now. Pass `end` too when paging: a window that tracks the present keeps growing at the tip, and the 15-day cap is re-checked on every page, so a walk that starts near the cap can outlive… |
| end | query | integernull | no | Window end, epoch seconds, EXCLUSIVE. Requires `start`; on its own it would ask for every point ever recorded up to `end`. |
| interval | query | stringnull | no | Relative window INSTEAD of `start`/`end`: `max`, `all`, `1m`, `1w`, `1d`, `6h`, `1h`, matched case-sensitively. An empty `interval=` is a malformed value, not an absent one. |
| bucket_seconds | query | integernull | no | Bucket width in SECONDS (60…86400). `bucketSeconds` is an accepted alias. OMIT it and the server sizes the width to the window: the finest tier grain (60, 300, 1800, 10800, 43200) that keeps the series under ~2,500 points, except that an explicit window wider than 12 hours never defaults to the 60s… |
| as_of | query | integernull | no | Point-in-time read, epoch seconds, INCLUSIVE: the latest observation at or before this instant. Cannot be combined with a window. `asOf` is an accepted alias. |
| limit | query | integernull | no | First-page size; defaults to the cap (10,000). Ignored when `cursor` is supplied (the cursor's size wins). |
| cursor | query | stringnull | no | Opaque pagination cursor from a prior response's `next_cursor`. |
token_id is listed as optional in Polymarket's OpenAPI spec, but the API returns 400 without it (checked 2026-10-04).
Example
curl -X GET "https://data-api.polymarket.com/v2/prices-history?token_id=<token_id>"Returns a list of objects with these fields
| Field | Type | Description |
|---|---|---|
| price | number | Price in the range 0…1. Always a JSON number. |
| resolution_seconds | integer | Width of the window this price was observed in: `0` for an exact tick, the bucket width for an aggregate. |
| timestamp | integer | The OBSERVATION's own time, epoch seconds, never the time that was asked for. A raw tick reports the tick; an aggregate reports its bucket start. |
Responses
| Status | Meaning |
|---|---|
| 200 | A page of the price-history series |
| 400 | Invalid query params or cursor |
| 429 | Per-client rate limit; retry after `Retry-After` |
| 500 | Internal server error |
| 503 | Timed out at the Timescale statement timeout, no pooled connection within the acquire budget, or the reader is unavailable; retry after `Retry-After` |
From Polymarket's published OpenAPI spec and rate-limit tables, synced 2026-10-04.