---
title: Pagination
description: Cursor-based pagination on all FHIR list endpoints — how _count, _cursor, and the next link work.
nav: Concepts / Pagination
order: 2
version: v1
source: handwritten
updated: 2026-06-01
---

# Pagination

All FHIR search endpoints return a `Bundle` of type `searchset`. Navigation through
large result sets uses cursor-based pagination — not page numbers or offsets.

## Parameters

| Parameter | Type    | Default | Max | Notes                                                  |
| --------- | ------- | ------- | --- | ------------------------------------------------------ |
| `_count`  | integer | 20      | 100 | Number of entries per page                             |
| `_cursor` | string  | —       | —   | Opaque cursor from the previous response's `next` link |

Request the first page:

```bash
curl "https://api.huli.ai/fhir/R4/Patient?_count=50" \
  -H "Authorization: Bearer $HULI_API_KEY" \
  -H "Accept: application/fhir+json"
```

## Response structure

```json
{
  "resourceType": "Bundle",
  "type": "searchset",
  "total": 847,
  "link": [
    {
      "relation": "self",
      "url": "https://api.huli.ai/fhir/R4/Patient?_count=50"
    },
    {
      "relation": "next",
      "url": "https://api.huli.ai/fhir/R4/Patient?_count=50&_cursor=eyJ0IjoiMjAyNi0wNi0wMVQxNDozMjowMC4wMDAtMDY6MDAiLCJpZCI6IjAxOTY1ZTJhLThjNGQtNzAwMC05MDAxLTAwMDAwMDAwMDAwMiJ9"
    }
  ],
  "entry": [...]
}
```

- **`total`** — the total number of matching resources at the time the first page was
  queried. It is advisory. For large sets it may become inaccurate as records are added
  or updated while you paginate. Do not use `total` as a loop terminator.
- **`link[relation=next]`** — present when there are more results. Absent on the last
  page.
- **`link[relation=self]`** — the canonical URL for the current page.

## Iterating all pages

Pass the full `next` URL as-is to retrieve the next batch. The cursor encodes a
time+UUID position. Do not parse or construct cursor strings manually — the format may
change.

```bash
NEXT_URL="https://api.huli.ai/fhir/R4/Patient?_count=50&_cursor=eyJ0IjoiMj..."

curl "$NEXT_URL" \
  -H "Authorization: Bearer $HULI_API_KEY" \
  -H "Accept: application/fhir+json"
```

Stop when the response has no `link` with `relation: "next"`.

## Stable iteration

The cursor is time+UUID ordered. Pages are stable within a single pagination session —
new records created after the first request will not appear in subsequent pages of that
session, and deleted records will not cause gaps. This makes the API safe for full patient-list
syncs that span multiple pages.

## Combining with filters

Search parameters combine with pagination. All parameters carry forward in the `next`
link — you do not need to re-specify them:

```bash
curl "https://api.huli.ai/fhir/R4/Patient?name=Fernández&active=true&_count=25" \
  -H "Authorization: Bearer $HULI_API_KEY" \
  -H "Accept: application/fhir+json"
```

The `next` link for this response will include `name=Fernández&active=true&_count=25`
alongside the cursor.

## Empty result sets

When no resources match, the response is still a valid `Bundle`:

```json
{
  "resourceType": "Bundle",
  "type": "searchset",
  "total": 0,
  "link": [
    {
      "relation": "self",
      "url": "https://api.huli.ai/fhir/R4/Patient?name=DoesNotExist"
    }
  ],
  "entry": []
}
```

`entry` is an empty array. There is no `next` link.
