Skip to main content

Pagination

Almost every collection returns the same wrapper: data (the items) and pagination (the navigation metadata). The exception is GET /v2/balances, which returns a bare array: you hold one position per asset, so there is nothing to paginate. What changes is what pagination contains, because v2 uses two strategies.

StrategyWhereMetadata
Offset (default)Everything except fillspage, limit, totalItems, totalPages
CursorGET /v2/fills and GET /v2/orders/{id}/fillscount, nextCursor

Offset — the general case

{
"data": [
{ "id": "wd_123", "status": "COMPLETED" },
{ "id": "wd_124", "status": "PENDING" }
],
"pagination": {
"page": 1,
"limit": 25,
"totalItems": 132,
"totalPages": 6
}
}
ParameterDescription
pagePage number. Starts at 1. Defaults to 1.
limitItems per page. Defaults to 25, maximum 100.

Cursor — fills

The two fills endpoints paginate by cursor, not offset:

{
"data": [
{ "id": "1096473", "orderId": "clord_01H…", "baseAmount": "0.01" }
],
"pagination": {
"count": 25,
"nextCursor": "MjAyNi0wNy0yNiAxNzo0MjowMS4wMDMzMDl8OWY4Zi00YQ"
}
}
ParameterDescription
limitItems per page. Defaults to 25, maximum 100.
cursorThe previous page's pagination.nextCursor. Omit it on the first request.

The correct walk: request a page, process data, and if nextCursor is not null, request again passing it as cursor. Repeat until it is null.

Do not infer the end from a short page

count can be lower than the limit you asked for even when more results remain. The only end-of-collection signal is nextCursor: null. A client that stops on a short page silently misses data.

Why fills are the exception

A fill is an execution record: append-only, never reordered. With OFFSET n the database re-scans and discards n rows on every page and — what matters more in a money API — the window shifts under you: a fill landing mid-walk pushes a row from page 2 onto page 3, and a client paging through its own history silently skips it. A keyset cursor is stable against concurrent inserts and costs the same on page 1 as on page 500.

It is also what the market does for this specific resource: Coinbase's /fills is cursor-paged and Binance's myTrades walks by fromId. What you give up is the totals, and for an append-only log "how many fills have I ever had" is not worth a full COUNT on every page.

The cursor is opaque

nextCursor is an opaque token: pass it back verbatim. Its encoding is not part of the contract and may change. Do not parse it, do not construct one, and do not store it as if it were a stable identifier.

Filters

In v2, filters are expressed as query parameters instead of special routes. For example, to list the fills of an order use GET /v2/fills?orderId=… rather than a dedicated route.

See the API Reference for the filters available on each collection.