Skip to main content
Some Simkl endpoints return many items and are paginated. Paginated endpoints are marked with 📄 Pagination in the API Reference. Every paginated endpoint takes the same page and limit query parameters. Where they differ is how they report the totals back, and there are two styles: The caps differ too, so don’t carry an assumption from one family to another. Check the table below before hardcoding a value.
A paginator written for one style silently breaks on the other. Custom Lists sends no X-Pagination-* headers at all, so a loop that reads X-Pagination-Page-Count gets null, computes NaN, and stops after page one without raising anything. If you share a paging helper across endpoints, branch on whether the header is present.

Per-endpoint defaults

page defaults to 1 on every paginated endpoint. Custom Lists cap page differently. Instead of a flat ceiling, page × limit cannot exceed 10,000, so the last reachable page depends on the page size you chose: 200 at the default limit=50, 20 at limit=500, 10,000 at limit=1. Larger pages buy you fewer of them.
Endpoints not listed here either don’t paginate (they use a different model — GET /sync/all-items uses date_from for incremental sync) or accept a much larger fixed window (e.g. GET /sync/playback returns up to 10,000 items in one shot). When in doubt, check the endpoint’s own reference page.

Query parameters

If you pass a limit above the endpoint’s cap, the server silently clamps it down — no error, no warning, just fewer items than you asked for. Same for a page above the ceiling. Read back what you actually got rather than assuming your request was honoured. Clamping only applies to values that are numbers. On Custom Lists a non-numeric page or limit is rejected outright with 400 wrong_parameter — and because -1 isn’t a digit string, negative values are rejected rather than clamped.

Response headers

Header-paginated responses include:
Stop on X-Pagination-Page-Count. When X-Pagination-Page equals X-Pagination-Page-Count, you’ve fetched the last accessible page. The Item-Count can exceed Page-Count × Limit if the underlying result set is larger than the 20-page cap allows — Page-Count is the practical ceiling.
Custom Lists send none of these headers. Read the pagination object in the body instead.

The pagination object

Custom Lists carry their totals inline:
The four fields mean the same things as the headers, under different names: page and limit report what the server actually used after clamping, so compare them against what you sent to find out whether your request was adjusted.
On GET /lists/{id}, don’t confuse pagination.total_items with counts.items. counts.items is how many titles the list holds; pagination.total_items is how many the current query matched. They usually agree, but only counts.items is the list’s real size.

A simple paginator

These snippets default to a conservative limit=50 that fits inside every paginated endpoint’s cap. Bump to 60 if you’re hitting a genre or premieres endpoint and want bigger pages. They read the headers, so they work on every endpoint except Custom Lists — for those, read total_pages out of the body instead.
On header-paginated endpoints the hard page cap is 20. No matter how many results match, you can never fetch beyond page 20 — that’s 20 × max_limit = 1,200 items in the best case. If you need to walk a larger result set, narrow the query with the endpoint’s own filter parameters (genre, year, country, network, sort) rather than paging deeper.Custom Lists cap the product instead: page × limit ≤ 10,000, so you can reach up to 10,000 titles in one list however you slice the pages. Beyond that the page number is clamped and you’ll get an empty items array with total_items: 0 rather than an error — a silent end-of-road, so stop on total_pages rather than paging until something breaks.