Skip to main content
Every list endpoint in the BlooBank API uses cursor-based pagination with opaque tokens. This page gives the mental model; for the exact request/response contract, see the Pagination reference.

The mental model

Think of pagination as a cursor over a stable result set:
  1. Your first request defines the cursor by supplying filter, order_by, and page_size.
  2. The server returns a page of items plus a nextPageToken — a sealed envelope describing where the cursor stopped.
  3. On the next call, you hand that envelope back as page_token. The server resumes the cursor.
  4. When the server runs out of items, nextPageToken is null. You stop.
The token is opaque to you. Do not parse it, log it, or persist it next to business state. It carries:
  • The pagination protocol version
  • An expiration timestamp (typically 48 hours)
  • A fingerprint of filter + order_by (so you cannot mix-and-match across iterations)
  • The cursor position
This is the same model used by Stripe, GCP, and the AWS SDK list operations — chosen over offset-based pagination because it is robust to inserts and deletes between pages.

Why not offset-based?

Offset-based pagination (?offset=100&limit=20) is intuitive but breaks at scale: Cursor-based pagination avoids all three. Pages are anchored to specific items, not positions.

When to paginate

The server’s maximum is 100. Exceeding it does not error — the value is silently coerced down.

The shape of a list response

Every list endpoint returns this envelope:
When the collection is exhausted, nextPageToken is explicitly null (not omitted, not empty string). That is your single signal for end-of-iteration.

The “iterate until null” pattern

The pattern: iterate, yield, advance, stop when token is null.

What you must keep stable across pages

Across calls within a single iteration, you must keep these identical:
  • filter
  • order_by
  • The endpoint URL
Changing any of them with a token from a previous query returns INVALID_PAGE_TOKEN (HTTP 400). The token is bound to the query context. You may change:
  • page_size (the server honors the new value)

When tokens expire

Tokens live ~48 hours. If a user pauses an iteration and resumes a day later, you might still be within the window. If they resume a week later, the token will return INVALID_PAGE_TOKEN. Handle this gracefully:
Restarting is acceptable — your filter and order_by are unchanged, so you will re-traverse from the start. For idempotent consumers (using idempotencyKey or upserts), re-traversal is harmless.

Reference

Pagination — full reference contract

Request parameters, response shape, errors, URL encoding.