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

# Pagination

> Page through list endpoints with cursors.

List endpoints that can return many results are cursor-paginated. Each response returns
one page of results plus a cursor you use to fetch the next page.

## Endpoints that aren't paginated

Not every list endpoint is paginated. Collections that are bounded per user return a
**bare JSON array** — no envelope, and no `limit` or `cursor` parameters:

```
GET /v1/api-keys/
GET /v1/auto-ramp-accounts/
GET /v1/auto-ramp-addresses/
GET /v1/bank-accounts/
GET /v1/bills/
GET /v1/cards/
GET /v1/funding-sources/
GET /v1/integrator/webhooks
```

Every other list endpoint — on-ramps, off-ramps, card transactions, webhook deliveries,
debit cards and the wallet-kit collections — uses the cursor envelope below.

If you write one generic list helper, branch on `Array.isArray(response)` rather than
assuming `data` is always present.

## Response envelope

Paginated responses wrap the results in an envelope:

```json theme={null}
{
  "data": [ /* results for this page */ ],
  "hasMore": true,
  "nextCursor": "eyJpZCI6..."
}
```

* `data`: the results for this page
* `hasMore`: whether more results exist after this page
* `nextCursor`: pass this value as `cursor` to fetch the next page. It's `null` when
  there are no more results

## Fetch pages

Set the page size with `limit` (default 50), and fetch the next page by passing the
previous response's `nextCursor` as `cursor`.

```bash theme={null}
# First page
curl "https://platform.spritz.finance/v1/off-ramps/?limit=50" \
  # plus your integrator signing headers and the user's Authorization (see Authentication)

# Next page
curl "https://platform.spritz.finance/v1/off-ramps/?limit=50&cursor=eyJpZCI6..." \
  # plus your integrator signing headers and the user's Authorization
```

Loop until `hasMore` is `false`:

```ts theme={null}
let cursor: string | undefined
let hasMore = true

while (hasMore) {
  const url = new URL("https://platform.spritz.finance/v1/off-ramps/")
  url.searchParams.set("limit", "50")
  if (cursor) url.searchParams.set("cursor", cursor)

  const page = await signedGet(url) // send a signed GET, see Authentication

  for (const item of page.data) {
    // handle each result
  }

  cursor = page.nextCursor
  hasMore = page.hasMore
}
```

Treat cursors as opaque. Don't construct or parse them; just echo `nextCursor` back as
`cursor`.

## Filter and sort

Many list endpoints accept filters and a sort order alongside pagination. For example,
`GET /v1/off-ramps/` accepts `status`, `chain`, and `accountId`, plus `sort` (`asc` or
`desc`). Filters apply consistently across pages. See each endpoint in the
[API Reference](/api-reference) for its full set of parameters.
