Pagination — bRRAIn Docs

How to page through list endpoints — cursor-based pagination, page sizes, and total counts.

Pagination

List endpoints return at most a page of results. To get the rest, you page through.

bRRAIn uses cursor-based pagination. Cursors are opaque tokens we hand back to you; pass the next cursor to get the next page.

Why cursors

Offset-based pagination (?offset=1000&limit=100) doesn't tolerate inserts and deletes happening between requests. With cursors, the page boundary is fixed by the resource state at the time the cursor was issued, so you don't see duplicates or skips.

Request

Every list endpoint accepts:

  • limit — page size. Default 50; max 1000. Larger requests are clamped silently.
  • cursor — the next-cursor from the previous response. Omit on the first request.

Some endpoints accept additional filters (zone=, since=, created_by=, etc.) — see each endpoint's documentation.

Response

GET /api/orgs/{org_id}/records?limit=100
HTTP/1.1 200 OK
Content-Type: application/json

{
  "data": [
    { "id": "rec_001", ... },
    { "id": "rec_002", ... },
    ...
    { "id": "rec_100", ... }
  ],
  "next_cursor": "eyJpZCI6InJlY18xMDAi...",
  "has_more": true,
  "approximate_total": 4823
}
  • data — the page of results.
  • next_cursor — pass to the next request to get the next page. Absent on the last page.
  • has_moretrue if more pages exist after this one.
  • approximate_total — best-effort count. Useful for UI but don't rely on it for correctness.

Following cursors

def all_records(client, org_id):
    cursor = None
    while True:
        params = {"limit": 100}
        if cursor:
            params["cursor"] = cursor
        r = client.get(f"/api/orgs/{org_id}/records", params=params)
        for record in r["data"]:
            yield record
        if not r.get("has_more"):
            return
        cursor = r["next_cursor"]

Cursor expiry

Cursors expire after 24 hours. If you store cursors and try to resume after that, you'll get 400 Bad Request with cursor_expired. Restart from the beginning.

Reverse pagination

A few endpoints support reverse pagination via a before cursor instead of cursor. Used for "show me the previous page" UIs:

GET /api/orgs/{org_id}/records?limit=100&before=eyJpZCI...

Sort order

List endpoints document their sort order. Most default to created-descending so the newest items come first. You can override with sort= where the endpoint allows.

Cursors encode the sort order they were issued under. You can't use a cursor from one sort with a different sort.

Eventual consistency

For very recently-created or recently-deleted resources, list endpoints may take a second or two to reflect the change. Use the resource's GET endpoint for strong consistency.

Counting without paging

If you only need the count, most list endpoints accept limit=0:

GET /api/orgs/{org_id}/records?limit=0
HTTP/1.1 200 OK

{
  "data": [],
  "approximate_total": 4823
}

This is cheaper than fetching all the data. For exact counts, use the count endpoint variant where one is documented.

SDK helpers

The bRRAIn SDK exposes iterate(...) helpers that handle pagination, retry, and rate-limit backoff for you. Prefer them over hand-rolling cursor loops.

Where to next