Pagination
Page through Kustomer list endpoints with page and pageSize, follow links.next, and handle cursor-based and very large result sets.
List endpoints return results a page at a time. Most use page numbers; a few use cursors. Either way, the safest approach is to follow links.next until it's null.
Page-number pagination
Pass page (starting at 1) and pageSize:
curl "https://acme.api.kustomerapp.com/v1/customers?page=2&pageSize=100" \
-H "Authorization: Bearer $KUSTOMER_API_KEY"{
"meta": { "pageSize": 100, "page": 2, "total": 4210, "totalPages": 43 },
"links": {
"self": "/v1/customers?page=2&pageSize=100",
"first": "/v1/customers?page=1&pageSize=100",
"prev": "/v1/customers?page=1&pageSize=100",
"next": "/v1/customers?page=3&pageSize=100"
},
"data": [ ... ]
}Page sizes
pageSize limits vary by endpoint. The reference page for each list shows its default and maximum.
Request the largest page size you can handle. Fewer, larger pages use less of your rate limit.
Iterate every page
async function* listAll(path: string) {
let next: string | null = `${path}${path.includes('?') ? '&' : '?'}pageSize=100`
while (next) {
const res = await kfetch(next) // retries 429s; see Making requests
const body = await res.json()
yield* body.data
next = body.links?.next ?? null
}
}
for await (const customer of listAll('/v1/customers')) {
console.log(customer.id, customer.attributes.name)
}links.next is a path. Prefix it with your base URL.
Cursor pagination
A few endpoints, such as the audit log, page with before and after cursors instead. Their links.next already contains the cursor:
{ "links": { "next": "/v1/audit-logs?count=1&before=62799c44a96e7f160834199c" } }The same "follow links.next" loop works without changes.
Large result sets
Deep pagination gets slower and can hit limits. For exports and syncs:
- Search returns only the first 10,000 matches. A request where
page×pageSizeis over 10,000 fails with400, andpageSizegoes up to 500. Split large queries into time windows onupdated_atorcreated_at, and page through each window. See Search recipes. - Sort for stability. Records created or updated while you page can shift between pages. Window by time, or sort by a stable field where the endpoint supports it.
- Incremental sync. After the first full pass, query only records updated since your last run instead of re-listing everything.
- Subscribe instead of polling. If you poll for changes, consider outbound webhooks.