Add to Watchlist
Move an item into one of the user’s Watchlist statuses. The body’s per-item to field selects the destination:
Most apps prefer POST /sync/history for sync flows. Use this endpoint (/sync/add-to-list) only when your app has explicit “Add to Plan to Watch” / “Move to Hold” UI buttons — i.e. setting watchlist status without recording a watch event. For backfill from another tracker, scrobbling, or marking-watched UI, send to /sync/history instead (which carries status, rating, memo, AND the watch event in one shape).
Don’t chain /sync/history then /sync/add-to-list — the history call already moves the item. POST /sync/history automatically places (and re-classifies) the item on the right Watchlist based on the watch event. Read added.statuses[].response.status in the history response to see the resolved status — e.g. a "completed" write on a still-airing show is silently downgraded to "watching" and reflected there. A follow-up /sync/add-to-list call is redundant and may overwrite the server’s smarter decision.
See the Sync guide for the two-phase pull/delta pattern.
to value | Destination |
|---|---|
watching | Currently watching. (For movies, automatically becomes completed since movies are atomic.) |
plantowatch | Plan to watch. |
hold | On hold. |
dropped | Dropped. |
completed | Completed. |
to is per-item (each entry in the array carries its own destination). The legacy top-level to shape is not accepted — the server returns 400 empty_field (Missed "to" parameter) when to only appears at the top level.
Optional per-item fields: watched_at, added_at.
Response: added and not_found
The response always returns 201 (even on partial failures) with two arrays per media-type:
Items the server’s resolver matched land in added. Items it couldn’t match (typos, fuzzy title misses, IDs not in Simkl’s catalog yet) land in not_found — verbatim copies of the input so you can show “we couldn’t add: …” in your UI. Always inspect both arrays after a bulk call.
Errors: 400 empty_field if to is missing on an item; 400 wrong_parameter if to is not one of the values above.
Silent to rewrites
The server may downgrade your requested to value when an item isn’t in a state where that status applies:
- Movies with
to: "watching"→ silently rewritten tocompleted(movies are atomic; you can’t “be watching” a movie). - Shows that aren’t ready for
completed(still airing, or pre-release) get rewritten towatchingorplantowatchrespectively, depending on whether any episode has aired.
The rewrites happen server-side; the consumer just sees the actual stored value in added.<type>[i].to. There is no error code surfaced for the rewrite — the only way to detect it is to compare the value you sent against the value that came back.
Note: this endpoint operates on the Simkl Watchlist (the five canonical statuses above). Custom user-created lists will get their own API in a future release.
Sync guide — full walkthrough
Two-phase model (initial pull → activities-checked delta loop), date_from semantics, deletion reconciliation, edge cases, and reference implementations in Node and Python.
Anime titles: can go in either the anime[] array OR the shows[] array — both are accepted. The server normalizes anime into the response’s shows array with "type": "show" per-item, since anime are TV-like in the cross-catalog data model. AniDB-specific IDs (mal, anidb, anilist, kitsu) belong inside each item’s ids object regardless of which array it lives in. See Anime under shows[].
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.
A user access_token, sent as Authorization: Bearer .... Required for endpoints that read or modify the user's library, scrobble session, ratings, settings, or playbacks. Every flow returns the same kind of token. See Set up 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).
Query Parameters
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.
Body
Body for POST /sync/add-to-list. Moves items into one of the user's Watchlist statuses. Items go under movies[], shows[], or anime[] — Simkl resolves anime titles correctly under either shows[] or anime[], so match the field to your data type when known.
Response
OK
Response from POST /sync/add-to-list.