Pagination
List endpoints are cursor-paginated. Walk the cursor to read an entire collection reliably, even while it changes.
Endpoints that return a collection — such as GET /v1/payouts — are paginated with a cursor. Cursor pagination is stable under inserts: new items appearing at the top won't cause you to skip or double-read rows, which offset pagination can.
Request parameters
| Parameter | Description |
|---|---|
limit | Page size, 1–100. Defaults to 25. |
starting_after | A resource id. Returns the page of results immediately after that id. |
List endpoints may also accept resource-specific filters (for example, payouts accept a status and a created_gte / created_lte range). Filters combine with pagination.
Response shape
Every list response has the same envelope:
json
{
"object": "list",
"data": [ { "id": "po_9f8e7d6c5b4a", "object": "payout", "status": "completed" } ],
"has_more": true,
"next_cursor": "po_9f8e7d6c5b4a"
}| Field | Meaning |
|---|---|
data | The array of resources for this page, newest first. |
has_more | true if there are more results after this page. |
next_cursor | The id to pass as starting_after for the next page. null when has_more is false. |
Reading the first page
bash
curl "https://api.caiboglobal.com/v1/payouts?limit=25" \
-H "X-API-Key: $CAIBO_API_KEY"Reading the next page
Pass the previous response's next_cursor as starting_after:
bash
curl "https://api.caiboglobal.com/v1/payouts?limit=25&starting_after=po_9f8e7d6c5b4a" \
-H "X-API-Key: $CAIBO_API_KEY"Walking the whole collection
Loop until has_more is false:
javascript
async function* listAllPayouts(params = {}) {
let cursor = null;
do {
const qs = new URLSearchParams({ limit: "100", ...params });
if (cursor) qs.set("starting_after", cursor);
const res = await fetch(
`https://api.caiboglobal.com/v1/payouts?${qs}`,
{ headers: { "X-API-Key": process.env.CAIBO_API_KEY } },
);
if (!res.ok) throw new Error(await res.text());
const page = await res.json();
for (const payout of page.data) yield payout;
cursor = page.has_more ? page.next_cursor : null;
} while (cursor);
}
// Usage
for await (const payout of listAllPayouts({ status: "completed" })) {
console.log(payout.id, payout.amount, payout.currency);
}Tips
- Use the largest reasonable
limit(up to 100) to reduce round-trips. - Persist
next_cursorif you page across requests or jobs — you can resume exactly where you left off. - Filter server-side (e.g. by
statusor date range) rather than fetching everything and filtering locally.