Skip to main content

Documentation Index

Fetch the complete documentation index at: https://api.simkl.org/llms.txt

Use this file to discover all available pages before exploring further.

Every item in a user’s library lives in exactly one status bucket. The set of valid statuses is not the same across types — movies are restricted to three statuses, while TV shows and anime get all five.

Per-type matrix

StatusMoviesTVAnimeDisplay name
watchingWatching
plantowatchPlan to Watch
holdOn Hold
droppedDropped
completedCompleted
TV and anime accept the same five statuses. The difference that matters in code is movies vs everything else — movies skip watching and hold.

Why movies are different

Movies are single-session content — there’s no progress to “pause” the way a 10-episode TV season has. Simkl reflects this in the API in four concrete ways: 1. POST /sync/add-to-list silently upgrades watching to completed for movies. Posting to: "watching" for a movie is not an error — the API quietly converts it to completed and records the watch. Posting to: "hold" for a movie has no defined behavior; don’t rely on it. 2. GET /sync/all-items/movies/watching and /movies/hold return empty. The URL is accepted (won’t 404), but no movie can be in those states, so the response is always empty. Don’t paginate these endpoints — there’s nothing to fetch. 3. GET /sync/activities strips watching and hold from the movies block. Build your client around this shape — don’t expect movies.watching or movies.hold keys. 4. POST /users/USER_ID/stats skips watching and hold for movies. Stats responses don’t include those buckets for movies. Plan-to-watch movies show up; “in progress” / “on hold” never do.

Where statuses appear

Read a watchlist

GET /sync/all-items/:type/:status — read items in one bucket. Use all for everything.

Move an item

POST /sync/add-to-list — set to to one of the five statuses to move the item between buckets.

Remove from history

POST /sync/history/remove — the canonical way to remove a watched item from the user’s history.

Detect changes

GET /sync/activities returns timestamps per status bucket — only re-sync the watchlists whose timestamp moved.
To remove an item, use POST /sync/history/remove — not POST /sync/add-to-list with to: "remove". The history endpoint is the canonical removal path; it cleanly un-marks the item watched and clears it from the user’s library.Removing also clears the rating. If the user had rated the item, Simkl wipes the rating along with the watch record — you’ll see both removed_from_list and rated_at move on the next /sync/activities call.

Status vs. progress

status says where in the library an item lives. The watched_episodes_count, total_episodes_count, and last_watched_at fields say how far the user is. A TV show in status: watching with 3 of 10 episodes watched is normal. A show in status: completed should always have watched_episodes_count equal to total_episodes_count. The two evolve together but they’re separate concepts. For movies, status: completed simply means the user marked the movie watched — there’s no episode count to track.

Quick examples

Read all anime
curl "https://api.simkl.com/sync/all-items/anime/watching?client_id=YOUR_CLIENT_ID&app-name=my-app-name&app-version=1.0" \
  -H "User-Agent: my-app-name/1.0" \
  -H "Authorization: Bearer ACCESS_TOKEN"
Mark a movie completed
curl -X POST "https://api.simkl.com/sync/add-to-list?client_id=YOUR_CLIENT_ID&app-name=my-app-name&app-version=1.0" \
  -H "User-Agent: my-app-name/1.0" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "to": "completed", "movies": [{ "ids": { "simkl": 53536 } }] }'
Drop a TV show
curl -X POST "https://api.simkl.com/sync/add-to-list?client_id=YOUR_CLIENT_ID&app-name=my-app-name&app-version=1.0" \
  -H "User-Agent: my-app-name/1.0" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "to": "dropped", "shows": [{ "ids": { "tmdb": "1399" } }] }'
Pause an anime ("on hold")
curl -X POST "https://api.simkl.com/sync/add-to-list?client_id=YOUR_CLIENT_ID&app-name=my-app-name&app-version=1.0" \
  -H "User-Agent: my-app-name/1.0" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "to": "hold", "anime": [{ "ids": { "mal": "11757" } }] }'
Remove a show from the user's library
curl -X POST "https://api.simkl.com/sync/history/remove?client_id=YOUR_CLIENT_ID&app-name=my-app-name&app-version=1.0" \
  -H "User-Agent: my-app-name/1.0" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "shows": [{ "ids": { "tmdb": "1399" } }] }'

Sync guide

Read and write watchlists, history, and ratings.

Mark as watched

POST /sync/history recipes that don’t go through scrobble.

Standard media objects

The shared shape every watchlist endpoint returns.