Make a First Request
Fetch a wallet’s current positions:data; paginated routes add a pagination
object (row fields trimmed here for brevity):
data: null or an empty list, never an error. Each
endpoint’s reference page describes its full row shape and every filter.
Paginate With Cursors
Pagination is cursor-only; there is nooffset query parameter. To walk a
result set:
- Send the first request with an optional
limit(each endpoint documents its default and maximum). - Read
pagination.next_cursorfrom the response and re-send the request withcursor=<next_cursor>. - Stop when
next_cursorisnull.has_moreis exact, so an empty or short page does not mean the walk is over.
- On the feeds (
/v2/trades,/v2/activity,/v2/activity/combos), re-send the same filters on every page. The cursor carries only its seek anchor, so changing a filter mid-walk silently re-anchors the feed. - Where a cursor binds its query (positions, boards, combo positions),
restating the same values is fine, but contradicting them returns a
400. On/v2/positions/combos, keep sendinguseralongside the cursor. On/v2/holders, keep sendingcondition. Other routes that bind the query can resume with the bare cursor.
limit parameter only applies to the first page; once a cursor is
supplied, the cursor’s own page size wins. The offset field in pagination
is display metadata for numbering rows across pages, not a request parameter.
Shared Conventions
Every v2 endpoint follows the same vocabulary and encoding rules.Identifiers
Query parameters accept both
snake_case and camelCase spellings.
Units and Sentinels
- Bare
volumeandsizevalues are outcome shares; fields suffixed_usdcare USD amounts; volumes prefixedtaker_count one side of each trade. - All amounts are JSON numbers.
outcome_index: 999means the outcome could not be labeled.- A missing or
nullnumeric field means unavailable, never zero.
Time Windows
Windowed routes takestart and end as epoch seconds. Treatment of an
omitted or 0 bound differs by route (for example, /v2/activity floors an
omitted start to three years back, while /v2/prices-history rejects a 0
bound with a 400), so check the parameter documentation on each endpoint
page before relying on a default.
Price History Resolution and Availability
/v2/prices-history serves each token from a graded store: a rolling
raw window (one-minute serving) plus five-minute, thirty-minute, three-hour,
and twelve-hour series. The coarse pair is permanent, so every token’s
full history is always available at twelve-hour grain (and at three-hour
grain from July 2026 onward); the fine grains are windowed. The availability
minimums are: raw at least 7 days, five-minute at least 60 days,
thirty-minute at least 90 days. These are floors, not exact horizons: data
expires in multi-day chunks, so a grain usually reaches a few days further
back than its minimum. bucket_seconds=60 over a window starting a month ago
is therefore an incompatible pair: both values are valid, and there is no
data at their intersection.
The two ways of asking behave differently on purpose:
- Send
bucket_secondsand the request means exactly that grid: the response holds every stored observation snapped to it and nothing else. Over a range where the store has nothing at or below that grain the page is empty, and where the stored history is coarser than the grid the page is sparse. Both are correct answers, never a silent substitution at a different width. - Omit it and the server measures, per request, which series actually cover this token and window, and serves the densest one: sized to the span, then coarsened only as far as coverage requires. Clients should not build their own availability tables; coverage is discovered from the data on every request, and it extends as the store grows.
- On a pinned request,
resolution_secondsechoes the requested grid, not the density of what filled it. Counting rows is the only density measure. - Deep history predates the fine grains: before July 2026 the store’s finest observations are three-hour or twelve-hour points, so a pinned fine bucket over old ranges returns those observations on your grid, sparsely.
bucket_seconds of 300, 1800, 10800, or 43200,
or omit it. A 60-second width over several days is both slow and, past the
raw window, empty.
Errors and Rate Limits
Request errors return a400 with a message envelope:
429 and a Retry-After header; retry after the
given delay. The IP-based request limits for /v2 routes are listed on the
Rate Limits page.
Endpoints
Wallet
Wallet
Feeds
Feeds
Markets
Markets
Boards
Boards
Service
Service
https://data-api.polymarket.com/v2/openapi.json,
with an interactive explorer at
https://data-api.polymarket.com/v2/docs.
Next Steps
- Coming from the v1 Data API routes? See Migrating to Data API v2.
- Browse the endpoint pages in the sidebar for full parameter and response documentation.