# Pagination and sync

Page through lists with a cursor, and keep a copy of your data up to date with updatedSince.

- HTML docs: https://www.invunion.com/knowledge-base/api/pagination/
- Markdown docs: https://www.invunion.com/knowledge-base/api/pagination.md

## Cursor pagination

List counterparties, List payment methods, List transactions, List invoices, and List matches use keyset pagination. Ask for the first page without `cursor`. Each response has `hasMore` and `nextCursor`. While `hasMore` is true, send the same request again with `cursor` set to `nextCursor`. Keep `sortBy`, `sortOrder`, and every filter identical between pages: a cursor from another sort returns 400.

```bash
curl --request GET \
  --url 'https://api.invunion.com/api/v1/transactions?pageSize=100&cursor=NEXT_CURSOR' \
  --header 'authorization: Bearer uk_live_YOUR_API_KEY'
```

```json
{
  "success": true,
  "data": {
    "items": [
      "…"
    ],
    "page": 1,
    "pageSize": 100,
    "hasMore": true,
    "nextCursor": "Y3JlYXRlZF9hdDpkZXNjfDIwMjYtMDktMDhUMTQ6MTA6MDAuMDAwWnw3ZDljMTNlNA"
  }
}
```

- `pageSize` defaults to 20, maximum 100.
- `total` is counted on the first page only. Send `includeTotal=false` to skip it, or `includeTotal=true` to get it on later pages too. Counting is slower on large tenants.
- A cursor points after the last row you received, so rows added while you page do not shift the next page, unlike offset paging.
- `page` is deprecated. It still works for page numbers above 1 when no cursor is sent, but it slows down on deep pages and can skip or repeat rows when data changes.

Related invoices and Related transactions of a counterparty also use `cursor` and `nextCursor`, with a page size of 50 by default and 200 at most.

## Lists with pagination next to data

List import jobs and List events return the page as `data` (an array) and the paging fields in a separate `pagination` object. List import jobs uses `limit` and `pagination.nextCursor`. List events uses `since` and `pagination.nextSince`.

## Incremental sync

To keep a copy of counterparties, payment methods, transactions, or invoices up to date, store the time you started the last sync and pass it as `updatedSince` (ISO 8601) next time. The list returns only rows modified strictly after it, paged with `cursor` as usual.

- Take the timestamp before the first request of a run, not after the last one, so changes made during the run are picked up next time.
- Deleted rows are not returned. Subscribe to the delete webhooks (for example `counterparty.deleted`) or compare a full list now and then.
- For matches and settlements, follow webhooks or the Events API: they carry each change, and the Events API keeps them for at least 45 days.
