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:

Shell
curl "https://acme.api.kustomerapp.com/v1/customers?page=2&pageSize=100" \
  -H "Authorization: Bearer $KUSTOMER_API_KEY"
200 OK
{
  "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": [ ... ]
}
FieldMeaning
meta.page, meta.pageSizeThe page you got and its size
meta.total, meta.totalPagesTotal matches and pages, on endpoints that report them
links.nextPath to the next page, or null on the last page
links.prev, links.first, links.lastOther pages, where available

Page sizes

pageSize limits vary by endpoint. The reference page for each list shows its default and maximum.

EndpointsTypical maximum
Most lists100
Users and teams500
Search500
Conversation times1,000

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:

JSON
{ "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 × pageSize is over 10,000 fails with 400, and pageSize goes up to 500. Split large queries into time windows on updated_at or created_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.