Skip to main content
Custom lists are user-curated collections — “Best of 2026”, “Comfort rewatches”, “Anime to show my sister”. This API reads them.
Custom lists requires AUTH V2, and is a PRO and VIP feature. It is the first API that V1 client_ids cannot reach. There is no anonymous access either. Every call needs an Authorization: Bearer ... token belonging to a Simkl PRO or VIP account. An anonymous caller counts as a free account, so calling without a token does not get you a public subset — it gets you the premium_only body described below.Users can upgrade at simkl.com/vip.
Beta. The response shape may still change. These pages are updated when it does, and the changelog records anything that would break a client.

What you can and cannot do

Writes are on the roadmap. Until they land, an app can display lists but not edit them.

A 200 does not always mean a list

A free or anonymous caller gets HTTP 200, not an error. The body carries premium_only rather than list data:
Check for an error key on a 200 before you read items. A client that branches only on the status code treats this as a successful list and renders the placeholder as real content — a user sees one fake entry titled “Upgrade to Simkl PRO/VIP” sitting in what looks like their list.Three details worth pinning down:
  • error is lowercase premium_only.
  • There is no items array and no pagination object here. This is a different shape, not a degraded one, so items is undefined rather than empty.
  • item is singular and renderable — real title, description and poster URL. Displaying it as-is is the simplest way to show the user why the list is empty.

Shared query parameters

Both endpoints accept the same paging controls. A non-numeric limit or page is normally a 400 naming the parameter, so out-of-range is silent while wrong-type is loud.
On GET /lists/{id} that validation is not guaranteed. That endpoint is served from an edge cache which coerces limit and page itself before deciding what to return. When the request hits a cached entry, a malformed limit=abc is silently replaced with the default and answered 200 rather than rejected — verified against production.So the same malformed request can return 400 or 200 depending only on whether that list happens to be cached. Validate your own paging input; do not rely on a 400 to catch it. direction is checked verbatim and always rejects, and GET /lists/user/{userId} is not edge-cached, so both of those behave predictably.
The two endpoints validate sort differently, on purpose.On GET /lists/user/{userId}, sort is a fixed set — updated, created, name, likes, followers, items, popularity — and anything else is a 400.On GET /lists/{id} it is free-form: an unrecognised value falls back to the list’s own stored order rather than erroring. Do not rely on a typo failing loudly there.

Account limits

These are limits on what a user can build, enforced when a list is saved on the website. The read API cannot return them, but they explain why a list stops accepting items. There are three separate ceilings, and a user can hit any of them independently: too many items in one list, too many lists, or too many items across everything.

See also

GET /lists/{id}

One list and its items, with sorting and paging.

GET /lists/user/{userId}

Every list belonging to one user.

Custom lists guide

What custom lists are, and how they fit alongside the watchlist.

AUTH V2

How to get the user token these endpoints require.