Skip to main content
POST

Authorizations

client_id
string
query
default:YOUR_CLIENT_ID
required

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.

Authorization
string
header
default:YOUR_ACCESS_TOKEN
required

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

User-Agent
string
required

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

client_id
string
required

Your client_id from your Simkl developer settings. Required on every request.

app-name
string
required

Short, lowercase identifier for your app (e.g. plex-scrobbler, kodi-bridge). Helps Simkl identify which apps are using the API.

app-version
string
required

Your app's current version (e.g. 1.0, 2.4.1). Helps Simkl debug issues you report.

allow_rewatch
enum<string>
default:no

Opt into rewatch tracking. When yes and the account is Simkl PRO or VIP, a /scrobble/stop with progress ≥ 80 on an already-completed item records a separate rewatch session instead of being a no-op, and the response gains rewatch_id + rewatch_status. Below 80 the stop is a pause, so nothing is marked and no rewatch fields are returned.

Send this on /scrobble/stop only. The flag is accepted here for consistency, but on /scrobble/start and /scrobble/checkin it applies to the user's previous outstanding playback rather than the item in this request, and nothing in the response reports that. See the /scrobble/stop description for the full rule.

Also supported on POST /scrobble/checkin, where the opt-in is stored on the check-in and applied later, when the check-in matures into a watch. The check-in response carries no rewatch fields because nothing has happened yet.

Read the Rewatches guide before enabling this. Gate it behind explicit user intent, a dedicated "Rewatch" button, never on automatic scrobble events, and expose a per-user Track rewatches toggle in your app settings that defaults to off. Used carelessly it pollutes the user's history stats and rewatches panel with phantom sessions.

Available options:
yes,
no

Body

application/json

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
object
required

Movie reference. Use ids (any one external ID) and optionally title / year. Movies have no episode block.

progress
number<float>

Playback percentage 0-100. Up to 2 decimals. Required for /scrobble/start, /scrobble/pause, /scrobble/stop. Optional (and ignored) for /scrobble/checkin.

Required range: 0 <= x <= 100
show
object

TV show reference (must be paired with episode).

anime
object

Anime reference. Pair with episode for series; an anime alone (no episode) is treated as an anime movie / OVA.

episode
By season + number · object

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).

Response

Created

Response for /scrobble/start, /scrobble/pause, /scrobble/stop and /scrobble/checkin.

rewatch_id and rewatch_status are present only on a scrobble action (a /scrobble/stop with progress >= 80) that was sent with ?allow_rewatch=yes. On every other call they are absent entirely.

id
integer

Playback event id for this call. 0 on /scrobble/start (the handler only assigns an id once the session is no longer just opening). Pass it to the playback-removal endpoint to undo a stop.

action
enum<string>

start for /start, pause for /pause and for /stop with progress<80, scrobble for /stop with progress≥80 (item marked watched).

Available options:
start,
pause,
scrobble
progress
number

Echo of the request progress, normalized.

movie
object

Standard movie object. See the Standard Media Objects guide.

show
object

Standard show object. May include nested seasons/episodes for partial sync.

anime
object

Standard anime object. Like Show, but may include anime_type. Episode numbering follows AniDB.

episode
object

Episode object returned by the /scrobble/* endpoints. This is not the same shape as the Episode object accepted in sync request bodies: it carries a resolved title, and it has no ids map.

rewatch_id
integer | null

Type 4 null — the watch did not land on a rewatch session. See Null and missing values.

The rewatch session this watch was recorded on. Present only when ?allow_rewatch=yes was sent and action is scrobble — otherwise the key is absent entirely.

A session that is already running reports its id even when it rejected this watch (for example inside the 2-day gap), so this field alone does not tell you the watch was recorded. Read rewatch_status for that.

rewatch_status
enum<string> | null

Type 4 null — the watch itself failed to record, so no rewatch was attempted. See Null and missing values.

What happened to this watch. Present only when ?allow_rewatch=yes was sent and action is scrobble — otherwise the key is absent entirely.

The first three values are session states, and mean the watch was recorded on a session of that state. The rest explain why no session took it. Note this is a superset of the three-value rewatch_status returned by GET /sync/all-items — do not reuse that enum here.

active — recorded on a session still in progress (typical for TV / anime). completed — recorded on a session that is now complete; movie sessions are created complete. closed — recorded on a session that was manually closed or left partial. first_watch — not a re-viewing; this is the original watch. too_soon — rejected by the 2-day gap between two watches of the same item. not_eligible — the item's watchlist status is plan-to-watch. pro_required — the account is not Simkl PRO or VIP.

Available options:
active,
completed,
closed,
first_watch,
too_soon,
not_eligible,
pro_required,
null