# Pagination

> How every list endpoint pages through results with an opaque cursor.



Every paginated list endpoint takes the same three parameters and returns the same envelope. Two lists are the exception: [`GET /v1/availability`](/api-reference/availability/list-availability) takes a date window (`from`, `to`) instead, and [`GET /v1/webhooks`](/api-reference/webhooks/list-webhooks) returns every endpoint on one page.

## Parameters

| Parameter        | Default | Notes                                    |
| ---------------- | ------- | ---------------------------------------- |
| `limit`          | `25`    | 1–100                                    |
| `order`          | `desc`  | `asc` or `desc`, by creation time        |
| `starting_after` | —       | The `next_cursor` from the previous page |

Many lists also take their own filters (for example `status` or `updated_since`); those are listed per endpoint in the [API reference](/api-reference).

## The envelope

```json
{
  "data": [],
  "has_more": true,
  "next_cursor": "eyJ2IjoxLCJjIjoiMjAyNi0wOS0xMVQyMDowMDowMCswMjowMCIsImkiOiI5ZTNmMmM0OC02YTFiLTRkNTUtYjBjMi03YzlmMWE0ZThkMzEiLCJzIjoiSnAza1E3eFcybVZiOXNMZDRoTmY2dFJ6OHlDZTF1R2E1b0tpMHdQcSJ9"
}
```

`data` holds the resources of this page. Stop when `has_more` is `false`; `next_cursor` is `null` then.

## Walking a list

Pass `next_cursor` back unchanged as `starting_after`:

```bash
curl -H "Authorization: Bearer aur_YOUR_KEY" \
  "https://your-site.awrora.app/api/v1/bookings?limit=100&order=asc"
# → next_cursor: "eyJjcmVhdGVkX2F0Ijoi…"

curl -H "Authorization: Bearer aur_YOUR_KEY" \
  "https://your-site.awrora.app/api/v1/bookings?limit=100&order=asc&starting_after=eyJjcmVhdGVkX2F0Ijoi…"
```

## The cursor is opaque

Do not parse the cursor, build it, or store it as anything but a string. It encodes a keyset, not an offset, which is why a row inserted mid-walk cannot make you skip or repeat one.

Cursors are also **signed**. A cursor you did not get from us — or one that was modified — answers `400` `validation_failed`.

<Callout type="tip" title="Catching up on changes">
  To follow what has changed rather than re-reading a whole list, walk [`GET /v1/events`](/api-reference/events/list-events) forward with `starting_after`. It returns changes, including ones with no list of their own such as `booking.cancelled`. Events are kept for 90 days.
</Callout>

## Date windows

Some list filters take a date range with an upper bound. `GET /v1/availability` and the `departure_from` / `departure_to` filter on bookings both span at most **92 days**; a wider window answers `422` `validation_failed` rather than a silently truncated result. Page through a year a quarter at a time.
