# Pagination

> Cursor iteration and updated_since for incremental sync.

Source: https://invoia.io/developers/api/pagination

Every list endpoint (`GET /customers`, `GET /invoices`, …) returns a
cursor-paginated envelope:

```json
{
  "object": "list",
  "data": [ … ],
  "has_more": true,
  "next_cursor": "eyJpZCI6…"
}
```

## Reading a full list [#reading-a-full-list]

Loop until `has_more` is `false`:

```js
let cursor = null
const all = []
do {
  const url = new URL('https://invoia.io/api/v1/customers')
  if (cursor) url.searchParams.set('cursor', cursor)
  const res = await fetch(url, {
    headers: { Authorization: `Bearer ${process.env.INVOIA_API_KEY}` },
  })
  const page = await res.json()
  all.push(...page.data)
  cursor = page.has_more ? page.next_cursor : null
} while (cursor)
```

Cursors are opaque and stable across mutations — a new item inserted
mid-iteration will not throw off your loop or cause duplicates.

## Incremental sync with `updated_since` [#incremental-sync-with-updated_since]

Pass `updated_since=<ISO timestamp>` to fetch only what changed after
a given point:

```bash
curl "https://invoia.io/api/v1/customers?updated_since=2026-07-01T00:00:00Z" \
  -H "Authorization: Bearer $INVOIA_API_KEY"
```

Persist the maximum `updated_at` you observed in each page and pass
it back on the next poll. Combine with `cursor` if a page-size
crossing is possible: `updated_since` narrows the working set,
`cursor` walks it.

## Common filters [#common-filters]

| Filter          | Endpoints              | Meaning                    |
| --------------- | ---------------------- | -------------------------- |
| `external_id`   | most                   | Exact match on your ext id |
| `customer`      | invoices, recognition  | Filter by customer ref     |
| `status`        | invoices, credit notes | e.g. `issued`, `draft`     |
| `updated_since` | all lists              | ISO 8601 timestamp         |

Filters and cursor may be combined freely.

## Page size [#page-size]

Default page size is 25; the maximum is 100. Pass `limit=<n>`:

```bash
curl "https://invoia.io/api/v1/customers?limit=100" \
  -H "Authorization: Bearer $INVOIA_API_KEY"
```
