> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.lucanto.eu/llms.txt.
> For full documentation content, see https://docs.lucanto.eu/llms-full.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.lucanto.eu/_mcp/server.

# Pagination

Every list endpoint returns a cursor-paginated envelope:

```json
{
  "data": [ /* ... */ ],
  "next_cursor": "eyJpZCI6MTIzfQ==",
  "has_more": true
}
```

* **`data`** — the page of records.
* **`next_cursor`** — an opaque base64 cursor for the next page (`null` on the last page).
* **`has_more`** — `true` when more pages exist after this one.

## Walking the pages

Call without a cursor to start, then pass the previous response's
`next_cursor` as the `cursor` query parameter until `has_more` is `false`:

```bash
# First page
curl "https://app.lucanto.eu/api/v1/accounts/{account_id}/invoices?limit=25" \
  -H "Authorization: Bearer lct_pat_xxx"

# Next page
curl "https://app.lucanto.eu/api/v1/accounts/{account_id}/invoices?limit=25&cursor=eyJpZCI6MTIzfQ==" \
  -H "Authorization: Bearer lct_pat_xxx"
```

## Parameters

| Param    | Default | Max | Notes                                            |
| -------- | ------- | --- | ------------------------------------------------ |
| `limit`  | 25      | 100 | Items per page                                   |
| `cursor` | —       | —   | Opaque; pass the previous `next_cursor` verbatim |

Cursors are keyset-based (stable under inserts), so paging never skips or
duplicates rows the way offset paging can. Treat the cursor as opaque —
don't decode or construct it yourself.

## Filtering

Some list endpoints accept filters that compose with pagination, e.g.
`GET /contacts?q=acme` (name search) and
`GET /expenses?extraction_status=completed`.