Skip to main content
Bravado uses two distinct pagination patterns depending on the nature of the data being returned. Most list endpoints use classic offset/limit pagination, which is simple to implement and supports random access. Trade history and activity timeline endpoints use cursor-based pagination, which is more efficient for large, append-only datasets and guarantees you won’t miss records if new data arrives between pages.

Offset/limit pagination

For most list endpoints, you control pagination using limit and offset query parameters. The response includes metadata fields that tell you how many total records exist and whether there are more pages to fetch. Endpoints that use offset/limit:
  • GET /leaderboard
  • GET /traders/{address}/positions
  • GET /v2/trade/positions
  • GET /v2/trade/combo/positions
  • PMWAS statement endpoints (with r1_limit / r1_offset, see PMWAS R1 pagination)
Example request:
Example response:
Use total, limit, and offset to determine whether another page exists. Stop when offset + limit >= total (or when has_more is false). Python iteration example:
Request the largest page size your use case allows to minimise the number of round trips. See the page size limits table below for per-endpoint maximums.

Cursor-based pagination

Trade history and activity timeline endpoints use cursor-based pagination. Instead of an offset, you pass a cursor value returned by the previous response to fetch the next page. This approach is safe against data mutations between pages and handles high-volume datasets efficiently.

Trade history cursors

GET /traders/{address}/trades and GET /trades use a compound cursor made up of two fields: The response includes next_cursor (a block_timestamp value) and next_cursor_log_idx. When next_cursor is null, you have reached the end of the dataset. Python iteration example:
Always pass both cursor_ts and next_cursor_log_idx together when available. Omitting next_cursor_log_idx when multiple trades share the same timestamp can cause duplicates or skipped records.

Activity timeline cursor

GET /v2/trade/activity uses an opaque string cursor rather than a timestamp integer. Treat the next_cursor value as opaque, do not parse or construct it manually. Example request (first page):
Example response:
Example request (next page):
When next_cursor is null or absent, you have fetched all available activity. Python iteration example:

PMWAS R1 pagination

The PMWAS statements endpoint has a nested pagination layer for R1 disposition rows within each statement. Use r1_limit and r1_offset to page through disposition rows independently of the top-level statement pages.
Check has_more_r1 in the response to determine whether additional R1 rows exist for the current statement page. For direct access to R1 rows without the parent statement wrapper, use the standalone endpoint:

Page size limits

Requesting more than the maximum allowed limit for an endpoint will result in a 400 Bad Request. Use these maximums as your target batch size when iterating through large datasets.