Skip to content

Pagination

Walk every list endpoint with limit and cursor.

List endpoints return { data, has_more, next_cursor }. Pass limit for the page size, 25 by default and up to 100, and pass next_cursor back as cursor for the next page.

A cursor only works with the list and filters it came from. If it doesn't match, or isn't one the API gave you, the request returns 400 invalid_request with field: "cursor", so start again without it.

GET /links?limit=1200 OK
{
  "data": [
    {
      "id": "lnk_nt842tPNne3lf0ka",
      "kind": "link",
      "code": "v6e4mrczwg",
      "url": "https://checkout.402pay.co/checkout/v6e4mrczwg",
      "name": "Team plan, monthly",
      "description": "Everything in Pro for up to 10 people.",
      "amount": "199.00",
      "currency": "USD",
      "success_url": null,
      "status": "active",
      "disabled_at": null,
      "payments_count": 0,
      "volume": {
        "amount": "0.00",
        "currency": "USD"
      },
      "created_at": "2026-09-26T21:22:46.992Z",
      "updated_at": "2026-09-26T21:22:46.992Z"
    }
  ],
  "has_more": true,
  "next_cursor": "lnk_nt842tPNne3lf0ka"
}
Every pageNode.js
// Walks every page of a list, 100 at a time.
async function* listAll(path) {
  let cursor = null;
  do {
    // A wallet list, such as /wallet/transactions, takes the wallet base URL instead.
    const url = new URL(`https://api.402pay.co/api/v1${path}`);
    url.searchParams.set("limit", "100");
    if (cursor) url.searchParams.set("cursor", cursor);

    const response = await fetch(url, {
      headers: { Authorization: `Bearer ${process.env.PAY402_SECRET_KEY}` },
    });
    const page = await response.json();
    yield* page.data;
    cursor = page.has_more ? page.next_cursor : null;
  } while (cursor);
}

for await (const payment of listAll("/payments?status=succeeded")) {
  console.log(payment.id, payment.amount);
}