> ## Documentation Index
> Fetch the complete documentation index at: https://developers.perkstar.co.uk/llms.txt
> Use this file to discover all available pages before exploring further.

# Pagination

> Traverse large customer, enrolment, transaction, card, and webhook collections safely.

List endpoints use cursor pagination. A response has this shape:

```json theme={null}
{
  "data": [],
  "has_more": true,
  "next_cursor": "cmexample",
  "limit": 100
}
```

Pass `next_cursor` back as `cursor`:

```bash theme={null}
curl "$PERKSTAR_API_URL/customers?limit=100&cursor=cmexample" \
  --header "Authorization: Bearer $PERKSTAR_API_KEY"
```

## Rules

* Treat cursors as opaque strings. Do not parse or increment them.
* Stop when `has_more` is false or `next_cursor` is null.
* Keep the same filters while following a cursor.
* Process each page before requesting the next one to avoid memory spikes.
* Checkpoint the last completed cursor in long-running backfills.
* Make your destination writes idempotent because records can change during a scan.

<Note>
  Cursor pagination is not a frozen database snapshot. For ongoing sync, store
  Perkstar record IDs and `updated_at` values, and use webhooks to react to new
  activity between reconciliation runs.
</Note>

## TypeScript SDK

The official SDK follows cursors automatically:

```ts theme={null}
for await (const customer of perkstar.customers.list({ limit: 100 })) {
  await upsertCustomer(customer);
}
```


## Related topics

- [Python SDK](/sdks/python.md)
- [TypeScript SDK](/sdks/typescript.md)
- [Changelog](/changelog.md)
