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:
GET /api/v1/partner/customersGET /api/v1/partner/customers/{customerId}/banking/accountsGET /api/v1/partner/customers/{customerId}/banking/accounts/{accountId}/transactions(pages by ledger journal — one transaction per journal, newest first)GET /api/v1/partner/customers/{customerId}/banking/beneficiariesGET /api/v1/partner/customers/{customerId}/banking/depositsGET /api/v1/partner/customers/{customerId}/banking/withdrawalsGET /api/v1/partner/customers/{customerId}/banking/conversion-requestsGET /api/v1/partner/customers/{customerId}/crypto/depositsGET /api/v1/partner/customers/{customerId}/crypto/withdrawalsGET /api/v1/partner/customers/{customerId}/end-customers/{endCustomerId}/accountsGET /api/v1/partner/customers/{customerId}/payout-batches
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.