Remove from History
Removes items from the user’s watched history. Body shape is identical to POST /sync/history — the same movies[], shows[], and granularity rules apply.
Granularity
What you send determines what gets removed.
Movie or show with no seasons and no episodes — the item is removed from the user’s library entirely (any watch history AND the watchlist entry). Equivalent to the user clicking “Remove from list” on the title page.
{ "shows": [{ "ids": {...} }] }
Show with seasons[] entries that omit episodes — every episode in those seasons is unmarked as watched. The show stays in the user’s library.
{ "shows": [{ "ids": {...}, "seasons": [{ "number": 2 }] }] }
Show with seasons[].episodes[] — only the listed episodes are unmarked. The show stays in the user’s library.
{
"shows": [{
"ids": {...},
"seasons": [{
"number": 1,
"episodes": [{ "number": 1 }, { "number": 2 }]
}]
}]
}
Show with top-level episodes[] shorthand — treated as seasons: [{ number: 1, episodes: [...] }]. Convenient for single-season shows; otherwise prefer the explicit form.
{ "shows": [{ "ids": {...}, "episodes": [{ "number": 1 }] }] }
Response shape
Status: 201 Created.
{
"deleted": {
"movies": <number of movies removed>,
"shows": <number of shows removed from library>,
"episodes": <number of episodes unmarked>
},
"not_found": {
"movies": [<items Simkl could not match>],
"shows": [<items Simkl could not match>]
}
}
not_found only has movies and shows — there’s no not_found.episodes array even when you tried to remove specific episodes. If the parent show isn’t matchable, the show object lands in not_found.shows and no episodes are touched. If the show is matchable but a specific episode number doesn’t exist, the call still counts as success and episodes in deleted reflects only the episodes that were actually unmarked.
Anime titles go in shows[] (with anime-only IDs like anidb / mal / anilist inside each item’s ids object). There is no top-level anime[] array on this endpoint — items sent under one are silently ignored. See Anime under shows[].
POST /sync/history
The mirror endpoint that adds history. Same body shape; this page is the removal side.
Sync guide — full walkthrough
Two-phase model (initial pull → activities-checked delta loop), deletion reconciliation, and reference implementations.
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).
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 /sync/history and /sync/history/remove. 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.
Top-level convenience array for marking episode-level history without nesting. The server wraps each entry into a synthetic single-season show. Each item carries the same shape as items under shows[].seasons[].episodes[] plus the parent show reference.
Array of anime entries (same shape as shows[]).
Response
Counts of items affected, plus any IDs Simkl could not match.
Counts of items removed plus any IDs Simkl could not match.