Check-in
A fire-and-forget version of /scrobble/start. Same effect on the user’s dashboard — the title appears in the “Watching now” widget with an animated, runtime-extrapolated progress bar — but you don’t need to follow up with pause / stop events. Simkl computes progress server-side from (now − checkin time) ÷ runtime; when that reaches 100%, the title is auto-marked watched.
Auto-completion timing: Once the computed progress reaches 100%, marking the item as watched can take anywhere from 0 to 2 minutes. Some check-ins finalize instantly; others sit at 100% briefly while the background worker picks them up. Don’t treat the delay as a failure — if you need to know exactly when it lands, check
GET /sync/activitiesafter the runtime expires; when the relevantcompleted/watchingtimestamp bumps, refresh viaGET /sync/all-items/{type}/{status}?date_from=…. That’s the same incremental loop documented in the Sync guide — no extra calls beyond what a normal sync would already do.
The user can browse and clean up active check-ins at the Playback progress manager.
When to use checkin vs the start / pause / stop loop
| Situation | Use |
|---|---|
| You have real player events (play / pause / stop) and want exact progress | /scrobble/start → /pause → /stop loop |
| You can’t reliably hook into pause / stop (some embedded players, casting flows, hardware AV-out, social “I’m watching this” buttons) | checkin |
| You just want to record a watch after the fact, no live status | POST /sync/history |
Seek and scrub behavior
No progress to update — the user can scrub or seek freely after check-in. The server’s runtime extrapolation doesn’t track real player position, so a user who checks in and then walks away is also auto-marked watched at the calculated runtime expiry. That’s a feature, not a bug, for fire-and-forget integrations.
Note: A 20-second per-user lock collision returns HTTP
400withRATE_LIMIT, not429— the lock failure is treated as a malformed request from a duplicate-fire client.
Scrobble guide — full walkthrough
Real-time playback tracking — /start, /pause, /stop lifecycle, paused-playback resumption across devices, when scrobble auto-completes, and the difference between /scrobble/checkin (fire-and-forget) and /scrobble/start (active tracking).
Alternative to episode.season + episode.number: pass episode.ids with tvdb or anidb to identify the exact episode by external episode ID. Useful for media-server integrations that have a TVDB or AniDB episode ID but not the season/number mapping. (Episode-level imdb and tmdb IDs are not accepted — those exist only at the show/movie level. Use the show/anime object’s ids for those.) If both forms are sent, episode.ids takes precedence.
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
- Movie
- TV episode
- Anime episode
Request body for the four scrobble endpoints. Send exactly one of movie, show+episode, or anime+episode — all keys are singular objects (one item per request). For batch sync writes the keys are plural arrays: see /sync/history etc. progress is required for /scrobble/start, /scrobble/pause, and /scrobble/stop; on /scrobble/checkin it is optional and ignored server-side.
Anime under show? Yes — if you don't know whether a title is anime (e.g. you only have TMDB/TVDB data), send it under show and Simkl resolves it to the correct catalog automatically. The anime key is only needed when you want to pass anidb / mal / anilist IDs that don't exist at the TV-show level.
Movie reference. Use ids (any one external ID) and optionally title / year. Movies have no episode block.
Playback percentage 0-100. Up to 2 decimals. Required for /scrobble/start, /scrobble/pause, /scrobble/stop. Optional (and ignored) for /scrobble/checkin.
0 <= x <= 100TV show reference (must be paired with episode).
Anime reference. Pair with episode for series; an anime alone (no episode) is treated as an anime movie / OVA.
Episode identifier. Use season + number, OR ids with a tvdb / anidb episode ID. If both are sent, episode.ids takes precedence (matches Plex-style integrations that have an episode ID but no season/number mapping).
- By season + number
- By episode ID
Response
Created
Response for /scrobble/start, /scrobble/pause, and /scrobble/stop.
start for /start, pause for /pause and for /stop with progress<80, scrobble for /stop with progress≥80 (item marked watched).
start, pause, scrobble Echo of the request progress, normalized.
Internal session ID.
Standard movie object. See the Standard Media Objects guide.
Standard show object. May include nested seasons/episodes for partial sync.
Standard anime object. Like Show, but may include anime_type. Episode numbering follows AniDB.
Episode reference. Use season + number, or ids.
For anime: original TVDB season number when AniDB mapping differs.
For anime: original TVDB episode number when AniDB mapping differs.