# Pagination and response conventions

Lists use cursor pagination. Request a page, read `next_cursor`, then pass it back to the same endpoint with the same filters.

## List and detail envelopes

A list response has `data` and `pagination`. This example is an empty final page:

```json
{
  "data": [],
  "pagination": {
    "limit": 20,
    "has_more": false,
    "next_cursor": null
  }
}
```

A detail response has a `data` object instead. Unknown fields may be `null`; do not assume every image, external ID, date, or link exists.

## Request the next page

The default `limit` is **20**, with an allowed range of **1–100**. A response can contain fewer items than requested. Use `next_cursor` to decide whether to continue; do not infer completion from the array length alone.

After setting `ATM_NEXT_CURSOR` to the exact cursor returned by a search:

```sh
curl --get "$ATM_API_BASE_URL/movies" \
  --header "Authorization: Bearer $ATM_API_KEY" \
  --data-urlencode 'genre=Drama' \
  --data-urlencode 'limit=20' \
  --data-urlencode "cursor=$ATM_NEXT_CURSOR"
```

This example assumes the original search also used `genre=Drama`. Keep the endpoint, filters, and sort order unchanged. To change the search, start again without a cursor.

Cursors are opaque strings and expire after **24 hours**. Do not decode, edit, or construct them. An invalid, expired, or mismatched cursor returns `400`. Restart the search without it.

## Nested lists

Some detail responses contain a paginated list inside the resource:

| Detail endpoint                    | Page location      |
| ---------------------------------- | ------------------ |
| `/concerts/{concert}`              | `data.events`      |
| `/awards/{award}`                  | `data.nominations` |
| `/books/{book}`                    | `data.adaptations` |
| `/collections/{type}/{collection}` | `data.movies`      |

Read the nested object's `data` and `pagination` fields, then send `cursor` to the original detail URL. For example, the next concert schedule cursor is at `data.events.pagination.next_cursor`.

Recommendation threads also include movie previews. Use the [thread-specific request](/recommendations#open-one-thread) to browse a thread's full movie list.

## Query conventions

- Dates use `YYYY-MM-DD`; date and year range boundaries are inclusive.
- Boolean filters use the literal strings `true` and `false`.
- Send each parameter once. Unknown or repeated parameters return `400`.
- Use URL encoding for titles, tags, and cursors; cURL's `--data-urlencode` and JavaScript's `URLSearchParams` handle this.
- List envelopes do not include a total count or numbered pages.

**Next:** [Errors and limits →](/errors-and-limits)
