# Cursor-Based Pagination — next_page_token Guide

> List endpoints in the v1 API use opaque cursor-based pagination — not page numbers — via a next_page_token you pass back verbatim, never decode or construct yourself.

Every list endpoint in v1 (`GET /batches`, `GET /account/usage`, and any future list endpoint) is paginated the same way: a cursor, not a page number.

## The list envelope

Every list response has the same three top-level fields:

```json
{
  "data": [ /* ... */ ],
  "has_more": true,
  "next_page_token": "eyJpZCI6IDQyfQ"
}
```

- `data` — the array of results for this page.
- `has_more` — whether another page exists after this one.
- `next_page_token` — pass this back as `?page_token=` on your next request to get the next page. Always `null` when `has_more` is `false` — the two fields never disagree.

## Why a cursor, not a page number

There is no `?page=2` style pagination anywhere in v1, and no `offset` parameter. Lists like your batches or your usage history are constantly changing — new batches complete, new usage rows get written — so an offset-based "page 2" can silently skip or repeat rows if something is inserted between your requests. A cursor avoids that: each token points at an exact position in the underlying order, not a shifting numeric offset.

## The token is opaque

`next_page_token` is not a page number, and its internal encoding is not part of the contract — treat it strictly as an opaque string. Pass it back exactly as received; don't decode it, don't construct your own, and don't assume its format is stable across API versions. The only guarantee is: pass the token you were given, get the next page.

## Example: paging through your batches

First request, no token yet:

```bash
curl "https://imagetotable.ai/api/v1/batches?limit=20" \
  -H "Authorization: Bearer $API_KEY"
```

```json
{
  "data": [ { "batch_name": "260716-4K9P", "status": "succeeded", "document_count": 3, "created_at": "2026-07-16T09:12:03Z" } ],
  "has_more": true,
  "next_page_token": "eyJpZCI6IDQyfQ"
}
```

Next request, using the token from the previous response:

```bash
curl "https://imagetotable.ai/api/v1/batches?limit=20&page_token=eyJpZCI6IDQyfQ" \
  -H "Authorization: Bearer $API_KEY"
```

Keep repeating with each response's `next_page_token` until `has_more` comes back `false`. A malformed or expired token returns an `invalid_parameter` error (see [Error Handling](/developers/guides/errors)) rather than silently returning the first page again — so a garbled token surfaces immediately instead of quietly restarting your loop.

## The `limit` parameter

Every list endpoint accepts an optional `limit` query parameter to control page size, each with its own default and maximum (see the individual endpoint's page in [API Reference](/developers/reference/) for its exact bounds). Requesting a `limit` outside the allowed range returns `invalid_parameter`.

---

Source: https://imagetotable.ai/developers/guides/pagination
