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

ParameterDescription
limitPage size, 1–100. Defaults to 25.
starting_afterA 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"
}
FieldMeaning
dataThe array of resources for this page, newest first.
has_moretrue if there are more results after this page.
next_cursorThe 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_cursor if you page across requests or jobs — you can resume exactly where you left off.
  • Filter server-side (e.g. by status or date range) rather than fetching everything and filtering locally.