> For the complete documentation index, see [llms.txt](https://portavi.gitbook.io/portavi-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://portavi.gitbook.io/portavi-docs/developers/paging-and-incremental-loads.md).

# Paging and incremental loads

## Reading every row

Lists come a page at a time, 100 items unless you ask for another `limit` between 1 and 500. Each page has a `next_cursor`. To get the next page, send it back as `cursor`, with the same filters:

```bash
curl "https://app.portavipmo.com/api/v1/tasks?limit=500&cursor=WyIyMDI2LTExLTEy..." \
  -H "Authorization: Bearer <token>"
```

Keep going until `next_cursor` is `null`; that is the last page.

Treat the cursor as opaque: don't build or change one. A cursor Portavi didn't issue is refused with `invalid_value`.

## Order

Items come oldest change first: by when they were last updated, then by id. That order is stable. An item that changes while you page through moves to the end, so you'll see it again later in the same run rather than missing it.

Health history is ordered by when each change happened, and budget entries by when they were recorded: an entry is added or removed, never edited.

## Loading only what changed

After a full load, ask for what changed since: pass `updated_since` with the time your last run **started**, as an ISO 8601 time with a zone.

```bash
curl "https://app.portavipmo.com/api/v1/projects?updated_since=2026-11-12T06:00:00Z" \
  -H "Authorization: Bearer <token>"
```

You get every item changed at or after that time, paged as above. Store each one by its `id`, replacing what you had.

* **Use the start of the last run**, not its end, so nothing that changed while it ran falls between the two.
* **Deletions don't appear.** An item that's deleted, or that the token's owner can no longer see, simply stops being returned. Run a full load now and then, such as weekly, to clear those out.
* **Programme health isn't a change.** A programme's `health_status` is rolled up from its projects when you read it, so it can change without the programme's `updated_at` changing. Programmes are few: reload them in full each run, or work their health out from the projects you've loaded.
* **Embedded items count as a change.** Editing a key result changes its objective's `updated_at`, and the same goes for a benefit's projects and a measurement's values.
* **A cleared flag is removed**, like any other deletion: reload `/flagged-items` in full, it's short.
* **Archived projects** stay in the list with `lifecycle_status` set to `archived`. Filter them out with `lifecycle_status=active`.

## Tasks

Tasks come from the project management tools a workspace connects, and Portavi brings in changes when it syncs. A task's `updated_at` is when Portavi last saw it change, which can be a little after it changed in the tool.
