Skip to content
Last updated

Pagination Guide

The Bermuda Commercial Bank Open Banking API uses cursor-based pagination with server-side result-set management for efficient handling of large datasets.


🔢 Pagination Parameters

Request Parameters (query string)

ParameterTypeDescription
pageStartintegerThe record (page number) from which the response should be displayed (default: 1)
pageSizeintegerThe total number of records per page (max: 1000, default 100 if pageSize omitted)
pageTokenstringOpaque cursor ID received from the previous response – required for subsequent requests

Response Parameters (returned in meta.pagination)

ParameterTypeDescription
page_sizeintegerThe total number of records per page (echoed from request or default)
page_startintegerThe record from which the current response is displayed
total_sizeintegerThe total number of records present in the complete result set
page_tokenstringOpaque cursor ID for this result set – use in subsequent requests

ℹ️ Naming convention difference
Request parameters are camelCase (pageStart, pageSize, pageToken).
Response properties are snake_case (page_start, page_size, page_token, total_size).


🧮 Pagination Mathematics

Given a dataset with total_size records and page_size records per page:

  • Total Pages: ceil(total_size / page_size)
  • Records on Last Page: total_size % page_size (or page_size if evenly divisible)

Example Calculation

If you have 345 total records with page_size = 100:

  • Page 1: Records 1-100 (100 records)
  • Page 2: Records 101-200 (100 records)
  • Page 3: Records 201-300 (100 records)
  • Page 4: Records 301-345 (45 records)
  • Total Pages: ceil(345 / 100) = 4 pages

⚙️ How Pagination Works Internally

Server-Side Cursor Management

  1. First Request – The server creates a cursor for the result set based on:
    • Query parameters (filters, sorting, etc.)
    • Business logic and security rules
    • Current data state at request time
    🔹Note: Sorting is not yet supported
  2. Cursor Token – The server returns an opaque cursor ID in page_token
    • Example: "202503190209330227.01,100"
    • Encodes pagination context (including page_size)
    • Unique to this specific query run
  3. Subsequent Requests – Reuse the same cursor for pages 2, 3, …
    • Token remains valid until it expires or query parameters change
    • Ensures a consistent view across the entire pagination sequence

Important Notes

  • Page Token embeds Page Size – The page_token contains the original page_size, so do not send pageSize again after the first request.
  • Cursor Expiration – Cursors may expire after a period of inactivity; handle 4xx errors by restarting pagination.
  • Changing Parameters – Any change to filtering/sorting invalidates the existing cursor; start a new sequence.

👨‍💻 Client Usage Guide

Step 1 – First Request

Send the initial call with an optional pageSize parameter:

GET /api/accounts/1000012345/payments?pageSize=100

Sample Response

{
  "meta": {
    "pagination": {
      "page_start": 1,
      "page_token": "202503190209330227.01,100",
      "total_size": 345,
      "page_size": 100
    }
  },
  "data": [
    // First 100 records
  ]
}

Step 2 – Calculate Total Pages

const totalPages = Math.ceil(totalSize / pageSize);
// Example: Math.ceil(345 / 100) = 4

Step 3 – Subsequent Requests

Use the pageToken from the previous response together with the desired pageStart value:

GET /api/accounts/1000012345/payments?pageToken=202503190209330227.01,100&pageStart=2

Response

{
  "meta": {
    "pagination": {
      "page_start": 2,
      "page_token": "202503190209330227.01,100",
      "total_size": 345,
      "page_size": 100
    }
  },
  "data": [
    // Records 101-200
  ]
}

Step 4 – Continue Until Last Page

Repeat Step 3 with increasing pageStart values (3, 4, …) until you reach totalPages.


📋 Best Practices

✅ Do

  • Store the pageToken from the first response and reuse it for all subsequent requests.
  • Calculate total pages using ceil(total_size / page_size) to know when to stop.
  • Handle the last page which may contain fewer records than page_size.
  • Specify pageSize only in the first request – it's embedded in the token thereafter.

❌ Don't

  • Don't send pageSize in subsequent requests – the token already contains it.
  • Don't reuse tokens across different query parameters – each unique query gets its own cursor.
  • Don't assume cursors last forever – handle expired token errors by restarting the sequence.

🚨 Error Handling

If a cursor expires or becomes invalid you will receive an error response. In that case:

  1. Start over with a new first request (without pageToken).
  2. The server will create a new cursor and return a fresh pageToken.