Pagination and filtering

Every list endpoint on the Client API is paginated and returns the same envelope, whatever the resource. The rows are in data; everything else describes the page you are looking at.

{
  "data": [ ... ],
  "totalCount": 137,
  "pageNumber": 1,
  "pageSize": 50,
  "totalPages": 3,
  "hasNextPage": true,
  "hasPreviousPage": false
}
FieldTypeDescription
dataarrayThe rows on this page, in the requested order.
totalCountintegerTotal number of rows matching the filters, across all pages.
pageNumberintegerThe 1-based page you are on.
pageSizeintegerThe number of rows requested per page.
totalPagesintegerTotal number of pages at this pageSize.
hasNextPagebooleanWhether a further page exists. Prefer this over comparing pageNumber with totalPages.
hasPreviousPagebooleanWhether an earlier page exists.

Paging parameters

These four query parameters work the same way on every list endpoint. All of them have defaults, so all of them can be omitted.

ParameterDefaultNotes
pageNumber11-based. Maximum 100000.
pageSize50Between 1 and 200. A larger value is rejected with 400.
orderByVariesThe sort key. Allowed values differ per endpoint, so check the endpoint page: GET /v1/accounts accepts clientName, accountNumber, iban and parentName, while GET /v1/transactions accepts date and amount.
orderDirectionVariesasc or desc. Accounts default to asc, transactions to desc.

Filtering

Filters are plain query parameters and combine with AND. They are documented per endpoint, because they follow the shape of the resource, but a few conventions hold everywhere:

  • Id filters (accountId, clientId, payeeId) match exactly.
  • Name filters (clientName, accountName) match as case-insensitive substrings.
  • Identifier filters (accountNumber, iban) match exactly, but case-insensitively.
  • Range filters come in From/To pairs and are inclusive at both ends: dateFrom/dateTo,valueDateFrom/valueDateTo, createdFrom/createdTo, amountFrom/amountTo.
  • Repeatable filters are sent as the same key more than once rather than as a comma-separated list. transactionTypes on GET /v1/transactions is the one to watch: send ?transactionTypes=A&transactionTypes=B.
  • Boolean switches default to false. On GET /v1/accounts, includeClosed=true brings back closed accounts and includeBalances=true populates the balances array; leave the latter off when you only need the account list, because it is the more expensive read.
  • clientId, where it appears, must name a member of your auth group. It narrows the results to that member; omit it to see every member's data.

Reading a full result set

Request page 1, process data, and keep requesting the next page while hasNextPage is true.

page = 1
loop:
  response = GET /v1/transactions?pageNumber={page}&pageSize=200
  process response.data
  if not response.hasNextPage: break
  page = page + 1

Two things to keep in mind. First, paging is offset-based, so rows created while you are walking the pages can shift the window; when you need a stable view, constrain the query with a createdTo or dateTo bound before you start. Second, remember that the DPoP htu claim excludes the query string, so the proof for page 2 is built from the same URL as the proof for page 1, while each page still needs its own fresh proof.