> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ionicfi.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Pagination

> List endpoint pagination patterns.

List endpoints return a page of objects and accept parameters that control page size and position.

## Offset pagination

Many list endpoints accept:

| Query parameter | Meaning                                                   |
| --------------- | --------------------------------------------------------- |
| `limit`         | Number of items to return. Default is 20. Maximum is 100. |
| `offset`        | Number of items to skip. Must be non-negative.            |

Example:

<CodeGroup>
  ```ts TypeScript theme={null}
  import { Ionic } from "@ionicfi/sdk";

  const ionic = new Ionic({ token: process.env.IONIC_SECRET_KEY });

  const products = await ionic.catalog.products.list({ limit: 20, offset: 40 });
  ```

  ```bash curl theme={null}
  curl "https://api.ionicfi.com/v1/products?limit=20&offset=40" \
    -H "Authorization: Bearer sk_v1_test_..."
  ```
</CodeGroup>

## Cursor pagination

Every list endpoint also supports cursor pagination, and it is the form to
prefer: rows created while you page shift offset-based pages (skipping or
repeating rows), but never a cursor.

| Query parameter  | Meaning                                                                           |
| ---------------- | --------------------------------------------------------------------------------- |
| `limit`          | Page size.                                                                        |
| `starting_after` | The last object id you have seen. Results resume strictly after it, newest first. |

When `has_more` is true, the response includes `next_cursor`, the last
returned object's id. Pass it as `starting_after` on the next request; that is
the whole loop. The two forms cannot be combined in one request.

The server SDK paginates with cursors automatically: iterating a list with
`for await` advances by `starting_after` until `has_more` is false. Pass
`starting_after` yourself to resume a walk from a saved position.

API-key and webhook-endpoint lists preserve their original full-list behavior
when `limit` is omitted. They still return a `Page`, but that page is terminal;
pass a `limit` when you want incremental requests.

```ts TypeScript theme={null}
const ids: string[] = [];
for await (const product of await ionic.catalog.products.list({ limit: 20 })) {
  ids.push(product.id);
}

const resumed = await ionic.catalog.products.list({
  limit: 20,
  starting_after: "prod_123",
});
```

## Client guidance

* Do not assume list responses are complete unless pagination metadata says there are no more results.
* Keep `limit` moderate for interactive experiences.
* When reviewing a large payment history, prefer repeated small pages over very large list requests.
