Pagination
Lists are newest first and paged with a cursor. Never with an offset.
Every list endpoint returns the same shape:
{
"object": "list",
"data": [{ "id": "pay_1042", "object": "payment", "…": "…" }],
"has_more": true,
"next_cursor": "eyJpZCI6MTAzOH0"
}| Parameter | Meaning |
|---|---|
limit | Page size, 1-100. Default 20. |
cursor | The next_cursor of the previous page. Omit it for the first (newest) page. |
created_gte, created_lt | Optional time window (ISO 8601), where the endpoint supports it. |
Lists are ordered newest first. has_more: false and next_cursor: null mark the last page.
Paging through a list
The SDK pages for you. for await fetches the next page when it needs it:
for await (const payment of zp.payments.list({ created_gte: '2026-09-01T00:00:00Z', limit: 100 })) {
await record(payment);
}Awaiting a list call returns one page:
const page = await zp.payments.list({ limit: 50 });
console.log(page.data.length, page.has_more, page.next_cursor);Rules
- Cursors are opaque. Pass them back unchanged. They are tied to one list: a cursor from another list, or a modified one, answers
400 cursor_invalid. - Keep your filters. Send the same filters with every page of one walk.
- Stable under inserts. Cursors are keyset-based, not offsets. New objects created while you page appear at the top of the list, never as duplicates or gaps in the pages you are reading.
- Time windows for reconciliation. Use
created_gteandcreated_ltto walk one closed period, for example one day in UTC. See Reconciling payments.
GET /v1/webhook_endpoints returns all endpoints of the mode (at most 16) in one list.
Events are kept for 30 days: GET /v1/events never goes further back.