Get all items of one type in one status bucket
⚠️ For continuous sync, do NOT call
/sync/all-itemson a timerThe correct loop, every time you want to check for changes:
- Call
GET /sync/activitiesfirst. It returns a tiny JSON oflast-modifiedtimestamps per category — costs almost nothing.- Compare those timestamps to the ones you saved on your last sync. If nothing changed, stop here. Do not call
/sync/all-items.- Only if a timestamp changed, call
/sync/all-items?date_from=<your-last-sync-timestamp>. Thedate_frommakes the server return only the small delta of items that actually changed, not the user’s entire library.Polling
/sync/all-itemsdirectly on a timer (without checking/sync/activitiesand withoutdate_from) downloads the user’s whole library every call. It overloads the API server and hurts every other client.Apps that do this will have their
client_idsuspended. No warning, no appeal — we see the traffic pattern and turn the key off.Read the Sync guide end-to-end before shipping anything that calls this endpoint. The full two-phase model (initial full sync → activities-checked delta loop) is documented there with reference implementations in Node and Python.
Sync guide
The two-phase model (initial pull → activities-checked delta loop), date_from semantics, deletion reconciliation, edge cases, and reference implementations in Node and Python. Required reading before shipping anything that polls this endpoint.
Rewatches guide
Session lifecycle (active / completed / closed), per-item rewatch fields, episode-level tracking, flag combinations for reading sessions back, and ready-made code for the UI patterns simkl.com uses on every detail page. Required if you set ?allow_rewatch=yes.
The single endpoint that powers watchlist reads. Both {type} and {status} are optional path segments, and any combination is valid:
| Path | Returns |
|---|---|
/sync/all-items | Every type, every status. The full library. |
/sync/all-items/{type} | A single type (shows, movies, or anime), every status. |
/sync/all-items/{type}/{status} | One type, one status bucket. |
The response shape is the same across all three forms: a top-level object keyed by shows, movies, and anime. Filtered calls just include fewer top-level keys; an empty result returns {}. See Per-endpoint shape matrix.
Pair this endpoint with GET /sync/activities and the date_from query parameter for incremental sync — see the Sync guide for the two-phase model.
Watchlist statuses by type:
| Type | watching | plantowatch | hold | dropped | completed |
|---|---|---|---|---|---|
shows | ✅ | ✅ | ✅ | ✅ | ✅ |
anime | ✅ | ✅ | ✅ | ✅ | ✅ |
movies | — | ✅ | — | ✅ | ✅ |
Movies skip watching and hold — see Watchlist statuses.
Useful query parameters
A quick map of the params below — see each parameter’s full schema later on this page.
| Param | What it does |
|---|---|
date_from | Required on every continuous-sync call. Returns only items modified since this ISO-8601 timestamp. |
extended=simkl_ids_only / =ids_only / =full / =full_anime_seasons | Controls response richness — from just ids.simkl (smallest) up to per-episode breakdowns. =full is required for seasons[].episodes[] and is the only value that adds runtime; it does not add overview / fanart / genres / ratings (use the detail endpoints for catalog metadata). Pair =full and =full_anime_seasons with date_from — they’re significantly larger payloads. |
include_all_episodes=yes / =original | Requires extended=full (no effect on its own). Loads seasons[].episodes[] for items in completed and dropped too (which skip episode load by default). yes fills in virtual episode rows — stamped with the show’s last-watched time — where per-episode data is missing; original returns only the episodes the user actually recorded, which can be fewer than watched_episodes_count for a show marked complete in one action. |
episode_watched_at=yes | Adds per-episode watched_at timestamps to every loaded episode. Requires extended=full — episodes must be loaded first, so on its own it does nothing. |
episode_tvdb_id=yes | Adds ids.tvdb_id per episode. |
next_watch_info=yes | On watching items with a next episode, attaches next_to_watch_info (title, season, episode, date). |
memos=yes | Includes the user’s per-item memo object (text capped at 140 chars). |
anime_type=movies | Restrict the anime results to the anime-movie subtype. movies is the only accepted value — it’s a subtype filter, not a full type selector. (The per-item anime_type response field still carries the full vocabulary: tv, movie, ova, ona, special, music video.) |
language=en | Force English titles instead of the user’s profile language. |
allow_rewatch=yes | Synthesize one extra entry per rewatch session alongside the canonical row. Simkl Pro / VIP only — gate the flag on account.type from POST /users/settings (cache it; refetch only when activities.settings.all bumps — see Rewatches guide → Pro / VIP gate). Free-tier callers get a silent no-op that still consumes a rate-limit slot. See the Rewatches guide for the full pattern. |
Rewatches (Simkl Pro / VIP). Without the flag, each item — movie, show, or anime — appears once in the response, reflecting the user’s current watch state. Set ?allow_rewatch=yes and any item with saved rewatch sessions appears multiple times: the normal entry, plus one extra entry per rewatch session. The extra entries carry is_rewatch: true, rewatch_id, rewatch_status (active / completed / closed), last_watched_at, and watched_episodes_count, so you can tell them apart from the main entry and from each other.
Authorizations
Preferred form: your client_id as a URL query parameter on every request. Self-describing in logs and curl commands. See Headers and required parameters.
OAuth 2.0 or PIN-flow access_token. Required for endpoints that read or modify the user's library, scrobble session, ratings, settings, or playbacks. See Authentication.
Headers
Descriptive identifier for your app, ideally name/version. Examples: PlexMediaServer/1.43.1.10540, kodi-simkl/0.9.2, MyApp/2.4.1 (https://myapp.com).
Path Parameters
One of shows, movies, anime, or all. Pass all to skip filtering on type even when the runtime accepts the segment-less form, so for spec strictness this is true. To call without it in practice, just drop the segment from the URL.
movies, shows, anime, all "all"
One of watching, plantowatch, hold, completed, dropped, or all. Movies accept only plantowatch, completed, dropped, and all; TV and anime accept all six. Pass all to skip filtering on status — /sync/all-items/{type}/all returns every status for that type.
User watchlist status. Movies skip watching and hold — see /conventions/list-statuses.
watching, plantowatch, hold, completed, dropped, all "all"
Query Parameters
Opt into rewatch tracking. When yes, POST /sync/history records an additional rewatch session instead of being a no-op for already-watched items, and GET /sync/all-items returns one extra entry per saved rewatch session alongside the item's normal entry. Available to Simkl Pro and VIP users — non-Pro callers see no effect even with the flag set.
⚠️ Do not enable this flag until you've read the Rewatches guide end-to-end and implemented the precautions. Used carelessly (on retries, on every scrobble event, on importer re-runs, without pinning rewatch_id after the first write), it will pollute the user's history stats and rewatches panel with phantom sessions. The flag should be gated behind explicit user intent — a dedicated "Rewatch" button — never on background or automated flows. Also expose a per-user Track rewatches toggle in your app's settings (default off) — not every user wants the rewatch-session complexity.
Limits: up to 50 rewatches per item (movie, show, or anime), and any two watch events on the same item (movie or episode) must be at least 2 days apart — a new rewatch within 48 hours of the previous watch of that same item collapses into the same session (it's a rewatch, not a rewind 😄). Full walkthrough — session lifecycle (active / completed / closed with bidirectional transitions), episode-level tracking, reading sessions back from GET /sync/all-items, and ready-made code for simkl.com-style UI patterns — in the Rewatches guide.
yes, no ISO-8601 timestamp. Returns only items updated since this time. Use the value saved from /sync/activities.
Controls response richness. Omit for the default (summary fields only — status, counters, last_watched / next_to_watch markers, no episode arrays).
simkl_ids_only— smallest payload: justids.simklper item. Ideal for the deletion-reconciliation diff in continuous sync.ids_only— same, plus external IDs (imdb,tmdb,tvdb,mal, …).full— required to get the per-episodeseasons[].episodes[]arrays; without it,episode_watched_atandinclude_all_episodesdo nothing. Necessary but not always sufficient: on its own it loads episodes forwatching/hold/plantowatchitems only —completedanddroppedadditionally needinclude_all_episodes. The only extra metadata field it adds isruntime.full_anime_seasons— likefull, plus TVDB season/episode mapping on anime (mapped_tvdb_seasonsat the show level, atvdbblock per episode).
This endpoint does not return overview, fanart, genres, or ratings at any extended value — it returns watch state plus a compact item stub (title, poster, year, ids, and runtime on full). For catalog metadata, call the detail endpoints (/movies/{id}, /tv/{id}, /anime/{id}).
Large payload on full / full_anime_seasons — pair with date_from for continuous sync. The one expected full-library use is a one-time episode baseline on first sync (see the Sync guide → Phase 1).
full, full_anime_seasons, simkl_ids_only, ids_only When yes, attaches a next_to_watch_info object to each watched item, indicating the next episode to watch.
yes When yes, includes TVDB IDs on each episode in episode-bearing responses.
yes en forces English titles. It's the only accepted value — any other value is ignored and titles fall back to the user's profile language.
en When movies, restricts the anime results to anime-movie subtype only.
movies yes adds per-episode watched_at timestamps to every loaded episode. Requires extended=full (or extended=full_anime_seasons) — it's a modifier on already-loaded episodes, so on its own it does nothing. To also cover completed / dropped items, combine with include_all_episodes (which itself also requires extended=full). Pair with date_from for continuous sync — significantly larger response.
"yes"Three-value flag that controls per-episode loading on canonical entries. Requires extended=full — it has no effect on its own.
no(default) — Episode lists are loaded only for items inwatching,plantowatch, andholdstatuses. Items incompletedanddroppedskip episode loading entirely (you get onlywatched_episodes_count).yes— Load episode lists for every status. For completed entries with no per-episode data recorded, synthesizes virtual episode rows stamped with the item's last-watched time (the same timestamp is shared across all synthesized rows). Complete coverage, approximate dates.original— Load episode lists for every status, but skip virtual-episode synthesis. Completed entries get only their real recorded rows with real dates — which can be fewer thanwatched_episodes_countfor an item the user marked complete in a single action. Treat the count as authoritative for how many episodes are watched, and the rows for which ones and when.
Independent of allow_rewatch=yes — combine the two when you need both canonical episode lists AND rewatch session episode lists in one response. Pair with date_from for continuous sync since the response can be much larger when episodes load for completed-bucket items.
yes, original, no yes includes the user's per-item memo object (text capped at 140 chars, plus is_private) in addition to all other data. Field name is singular memo; empty memos render as {}.
"yes"Your client_id from your Simkl developer settings. Required on every request.
Short, lowercase identifier for your app (e.g. plex-scrobbler, kodi-bridge). Helps Simkl identify which apps are using the API.
Your app's current version (e.g. 1.0, 2.4.1). Helps Simkl debug issues you report.
Response
Top-level dict keyed by shows, movies, and anime. Keys are present only when there's at least one item in that bucket — filtered calls (/movies/completed) return just that key; an empty library returns {}.
The per-item shape is AllItemsEntry — its fields are gated on the query parameters (extended, memos, next_watch_info, episode_watched_at, episode_tvdb_id, allow_rewatch, etc.). See the schema and the examples below for what each modifier adds.
Top-level dict keyed by shows, movies, and anime. Each key is an array of AllItemsEntry objects. Keys are present only when there's at least one item in that bucket — an empty library returns {}; a library with only movies returns { movies: [...] } with no shows or anime keys.