---
title: Pagination
description: How to page through list results using page and limit and the X-FlickList response headers.
section: Core concepts
order: 2
---

# Pagination

Endpoints that can return unbounded result sets serve them in pages. Three different behaviors exist on the API, so check which one your endpoint uses:

- **Header pagination** (this page): the Trakt-shaped endpoints with open-ended results, `GET /v3/sync/history`, `GET /v3/lists/{id}/items`, `GET /v3/lists/community`, `GET /v3/lists/search`, and `GET /v3/users/{username}/lists`. `page`/`limit` params, state in `X-FlickList-*` response headers.
- **TMDB body pagination**: [catalog](/dev/catalog) endpoints like discover and search keep TMDB's own shape, `page` in the query and `page`, `total_pages`, `total_results` in the response body, exactly as your existing TMDB client expects.
- **No pagination**: personal collection snapshots (`watched`, `ratings`, `watchlist`, `favorites`, `playback`, `up_next`) return the complete array in one response.

:::tabs
```bash
curl "https://flicklist.tv/api/v3/lists/community?page=1&limit=50"
```
```javascript
const res = await fetch('https://flicklist.tv/api/v3/lists/community?page=1&limit=50');
const lists = await res.json();
```
```python
import requests
r = requests.get(
    "https://flicklist.tv/api/v3/lists/community",
    params={"page": 1, "limit": 50},
)
lists = r.json()
```
:::

For the header-paginated endpoints, pagination state lives in response headers, not the response body:

```
X-FlickList-Page: 1
X-FlickList-Limit: 50
X-FlickList-Page-Count: 14
X-FlickList-Item-Count: 683
```

| Attribute | Type | Description | Default |
| --- | --- | --- | --- |
| `page` | integer | Which page of results to return. | `1` |
| `limit` | integer | Items per page, up to `100`. | `50` |

| Header | Description |
| --- | --- |
| `X-FlickList-Page` | The page number this response represents. |
| `X-FlickList-Limit` | The `limit` value used for this response. |
| `X-FlickList-Page-Count` | Total number of pages for this query. |
| `X-FlickList-Item-Count` | Total number of items across every page. |

## Walking every page

Read `X-FlickList-Page-Count` after your first request and keep incrementing `page` until you pass it:

:::tabs
```bash
page=1
page_count=1
while [ "$page" -le "$page_count" ]; do
  headers=$(curl -sD - -o page.json \
    "https://flicklist.tv/api/v3/lists/community?page=$page&limit=100")
  page_count=$(echo "$headers" | grep -i 'x-flicklist-page-count:' | tr -dc '0-9')
  # ...process page.json here...
  page=$((page + 1))
done
```
```javascript
let page = 1;
let pageCount = 1;

while (page <= pageCount) {
  const res = await fetch(
    `https://flicklist.tv/api/v3/lists/community?page=${page}&limit=100`
  );
  pageCount = Number(res.headers.get('x-flicklist-page-count'));
  const lists = await res.json();
  // ...process lists here...
  page += 1;
}
```
```python
import requests
page = 1
page_count = 1
while page <= page_count:
    r = requests.get(
        "https://flicklist.tv/api/v3/lists/community",
        params={"page": page, "limit": 100},
    )
    page_count = int(r.headers["X-FlickList-Page-Count"])
    lists = r.json()
    # ...process lists here...
    page += 1
```
:::

> [!TIP]
> Walking every page on every request is wasteful for collections that don't change often. See [Rate limits & fair use](/dev/rate-limits) for the recommended pattern.
