Pagination

How list endpoints page

The paged list endpoints below take two query parameters and return a pagination object that tells the truth about the whole matching set:

Parameter Default Range Notes
limit 100 1–500 Clamped silently: limit=0 becomes 1, limit=5000 becomes 500
page 1 ≥ 1 1-based; page=0 or negative becomes 1. A page past the end returns an empty list with the true totals, never an error
curl "https://api.kwiikpay.io/api/v1/partner/customers?limit=100&page=2" -H "X-Api-Key: kp_live_..."
{
  "success": true,
  "status_code": 200,
  "message": "Customers retrieved successfully",
  "data": {
    "customers": [ { "...": "..." } ],
    "pagination": { "current_page": 2, "last_page": 3, "per_page": 100, "total": 247 }
  }
}
Field Meaning
current_page The page you asked for (after clamping)
last_page ceil(total / per_page), never 0 — an empty set reports 1, so current_page <= last_page always holds
per_page The page size actually applied
total The number of matching records across all pages — a real count, not the size of this response

To enumerate everything:

page = 1
do
  response = GET ...?limit=500&page=page
  process(response.data.<items>)
  page += 1
while page <= response.data.pagination.last_page

The count is taken in a separate query before the page is read, so total can move between pages while records are being created. Sort order is newest first with an id tiebreak, so a row never appears on two pages or on none; a record created while you loop can shift the boundary by one.

Which endpoints page

These eleven list operations in the v1 reference page this way:

Reads that return the customer's current holdings (…/banking/balance, …/crypto/wallets) are not lists in this sense and take no paging parameters.

The sub-customer list (/customers/{customerId}/end-customers) returns all of the parent's children in a single page and takes no page or limit. Verification document lists are also unpaginated. The child's …/internal-transfers list returns recent transfers using take (default 50, clamped to 1–200), without page/cursor navigation. See Sub-customers & parent access.

/api/v2/public list endpoints use a different, simpler envelope: limit bounds the response and the body reports count and limit. There is no page parameter there; treat count == limit as "possibly more" and narrow the query.

Release note — what changed on 2026-09-01

Before 2026-09-01 every v1 list returned current_page: 1, last_page: 1, per_page: <limit> and total: <rows in this response> regardless of how much data existed, and ignored page. A client that looped while current_page < last_page stopped after one page, and total agreed with the truncated result. If your integration read total as "rows received", it will now see a larger number; if it never sent page, it now receives page 1 of the honest count and should start looping. Nothing else in the envelope changed.

In practice

For most integrations you list a bounded, filtered set (one customer's beneficiaries, one account's recent transactions) well under one page. Enumerating an entire customer base is where paging matters; prefer reacting to webhooks to keep your store in sync incrementally, and use the account transactions list to rebuild an account's ledger after an outage — it is per account and fiat-only.