TidePay

Pagination

How list endpoints are paginated across the Tidepay API.

Every list endpoint (GET /offers, /customers, /subscriptions, /payments) shares the same offset-based pagination — two query parameters, limit and start, and results ordered newest first.

Offset, not cursor

Unlike APIs that paginate by object id (starting_after/ending_before), Tidepay pages by numeric offset. There's no has_more flag in the response — see Knowing when you've reached the end below for how to detect the last page.

Parameters

  • limit (optional, default 20) Max number of objects to return, from 1 to 100. Requesting more than 100 is rejected with 400, not silently capped.

  • start (optional, default 0) The offset into the result set. A call with no query params returns the newest 20 rows (start=0). To fetch the next page, pass start equal to the number of rows you've already seen — e.g. after a first page of 20, pass ?start=20 for the second page.

Results are ordered newest first (most recently created row first), so start always counts from the most recent end of the list, not the oldest.

Response shape

There's no shared object: "list" envelope — each endpoint nests its array under a key named for the resource, alongside the limit/start you requested:

GET /v1/customers?limit=2
{
  "customers": [
    {
      "id": "cust_01j8x2q3r4s5t6u7v8w9x0y1z2",
      "walletAddress": "0x71c7656ec7ab88b098defb751b7401b5f6d8976",
      "merchantReferenceId": null,
      "email": "payer@example.com",
      "phone": null,
      "name": null,
      "isSandbox": false,
      "idempotencyKey": null,
      "createdAt": "2026-08-15T09:12:03.000Z",
      "updatedAt": "2026-08-15T09:12:03.000Z"
    },
    {
      "id": "cust_01j8x1a2b3c4d5e6f7g8h9j0k1",
      "walletAddress": null,
      "merchantReferenceId": "ORD-5521",
      "email": null,
      "phone": "+5511998887766",
      "name": "Jane Doe",
      "isSandbox": false,
      "idempotencyKey": null,
      "createdAt": "2026-08-14T22:41:17.000Z",
      "updatedAt": "2026-08-14T22:41:17.000Z"
    }
  ],
  "limit": 2,
  "start": 0
}

The array key differs per endpoint — offers, customers, subscriptions, or payments — matching the resource being listed. limit/start in the response simply echo back what the request resolved to (including the defaults, if you omitted them), not anything computed from the result set.

Knowing when you've reached the end

Since there's no has_more field, infer it from the page size: if the array you got back has fewer items than the limit you requested (or asked for by omission — the default 20), you've reached the end of the list.

let start = 0;
const limit = 100;
let allCustomers: Customer[] = [];

while (true) {
  const res = await fetch(
    `https://api.tidepay.cc/v1/customers?limit=${limit}&start=${start}`,
    { headers: { "X-API-Key": apiKey } },
  );
  const page = await res.json();
  allCustomers = allCustomers.concat(page.customers);

  if (page.customers.length < limit) break; // last page
  start += limit;
}

Pages can drift under concurrent writes

Offset pagination has a known tradeoff: if a row is created or deleted between two page requests, results ordered by createdAt can shift — a row might be skipped, or seen twice, across pages. This is rarely an issue for periodic sync jobs, but if you need a guaranteed-consistent full export, prefer filtering by createdAt/updatedAt bounds you control (where the endpoint supports it) over paging through the entire history in one pass.

Filtering

Some list endpoints accept additional query parameters, always combined with — never instead of — limit/start:

EndpointExtra filters
GET /offers?active=true / ?active=false, ?identifier=
GET /customers?walletAddress=0x...
GET /subscriptions?status=, ?customerId=, ?planId=
GET /payments?status=, ?source=, ?customerId=, ?subscriptionId=, ?offerId=

All filters are optional and narrow the result set before limit/start are applied — start=20 after adding a filter means the 20th row matching that filter, not the 20th row overall.

Related pages

Every list endpoint is also subject to a request-rate quota, separate from pagination — see Consumption limits. The exact response schema for each resource (every field in a Plan, Customer, etc.) is in the API reference.

On this page