Skip to main content
Every list endpoint (GET /v1/markets, GET /v1/trades, GET /v1/markets/{id}/predictions, GET /v1/webhooks/events) returns a paginated response with an opaque cursor. GET /v1/portfolio/positions is not cursor-paginated in v1 — it returns the full position set in a single { data, _meta } response and accepts only a ?marketId= filter. We deliberately do not support offset-based pagination — offsets are inconsistent under concurrent writes and degrade with table size.

Wire shape

Walking pages

When pagination.cursor is null (or hasMore: false), you’ve reached the end.

TypeScript SDK

The SDK’s list() methods return a Page that’s both the first page (with data and pagination) and an AsyncIterable<Item> for walking every page lazily:
page.getNextPage() is memoised — calling it twice returns the same Promise.

Limits

Override with ?limit=N. Requests with limit > 100 get clamped to 100 silently.

Filtering

Most list endpoints accept filters that compose with pagination:
The cursor encodes the filter context. Don’t change filters mid-walk — generate a new cursor by re-requesting the first page.

Cursor stability

Cursors are stable for at least 7 days. If you persist a cursor (e.g. for a daily incremental fetch) and use it later, it’ll continue to work as long as the underlying row hasn’t been deleted. After 7 days we make no guarantees — restart the walk from the first page. Cursors are tied to the page they came from. Don’t try to construct your own — they’re opaque on purpose, and the encoding may change.

Insertion behaviour during a walk

Because cursors are anchored to row ids (not offsets), new rows inserted after you started a walk don’t shift your cursor. You’ll never see the same item twice, and you’ll never skip an item that existed when you started. Items inserted during the walk that fall before your cursor on the natural sort order won’t appear in the current walk. Re-fetch from the first page to pick them up.

Total counts

We don’t return a total count — counting all rows on every page is expensive at scale. If you need a count for UX:
  • For trades: GET /v1/account/usage returns 24h/7d/30d aggregates.
  • For markets: walk the full list (cheap with ?limit=100 and ETags).
If you really need exact totals for a custom dashboard, the account telemetry endpoint is your friend.

Next

ETags

Combine pagination with If-None-Match to skip unchanged pages.

Endpoint Reference

The interactive spec with full pagination examples.