Watcher
Real-time scrobbling from Plex/Emby/Jellyfin to Trakt, SIMKL and MDBList.
Watcher does real-time scrobbling in CrossWatch (CW).
It reads playback from your media server.
It pushes progress to trackers.
Watcher uses routes mode (starting in v0.9.0).
Routes are many-to-many mappings.
You can run multiple media servers and trackers together.
What it supports
Sources (providers):
Plex
Emby
Jellyfin
Targets (sinks):
Trakt
SIMKL
MDBList
Events:
now playing (progress)
pause/stop
completion (after thresholds)
Routes mode (the important part)
Each route is:
provider(profile) → sink(profile)
That unlocks:
Plex + Jellyfin + Emby in parallel.
Trakt + SIMKL + MDBList at the same time.
Multiple accounts per provider via profiles.
Profiles are called Profiles in the UI.
Profiles are documented here:

How sources are read (high level)
Watcher reads sources like this:
Plex: connects via
AlertListenerand consumes “Playing” alerts.Emby: polls
/Sessions?ActiveWithinSeconds=15(every ~15s).Jellyfin: polls
/Sessions?ActiveWithinSeconds=15(every ~15s).
Prerequisites
Connect your media server in Settings → Authentication.
Connect at least one target tracker in Settings → Authentication.
Tip: If you use Emby or Jellyfin, connect Trakt too. Even if you don’t scrobble to Trakt, CW can use it as an ID fallback.
Quick start (recommended)
Scrobbler / Watcher quick guide
For most users
If you just want CrossWatch to scrobble playback, keep it simple:
Create a route from your media server to your tracker.
Set Filters so the route only matches the users or server you actually want.
Use Options if that route should behave differently from the global Watcher defaults.
In short:
Global settings = default behavior for all routes
Route filters = who or what a route should match
Route options = route-specific overrides
For power users
Routes are where advanced setups happen.
Use separate routes when you want:
different users scrobbled to different sink accounts
different server profiles going to different tracker profiles
route-specific auto-remove behavior
Plex-specific custom ratings webhooks on one route but not another
How it works:
Each route has its own provider, provider profile, sink, sink profile, filters, and options.
Global Watcher settings still exist, but they are only the defaults.
If a route needs special behavior, open that route’s Options and override the global default there.
A good example:
one route for your own Plex account to Trakt
one route for a family Jellyfin profile to SIMKL
one route with auto-remove enabled
another route with auto-remove disabled
Tips
Avoid creating two identical routes.
Be careful sending multiple providers to the same tracker profile at the same time. Most trackers do not handle simultaneous playback well.
If you want one route to behave differently, change that route’s Options instead of changing the global defaults for everything.
Global settings vs route settings
Global Watcher settings apply to all routes by default.
That is the best place for behavior you want everywhere.
Route Filters decide whether a route matches a playback event.
Without filters, a route can scrobble all playback it sees from that source/profile.
Route Options override the global defaults for that route only.
Most users can leave the global settings as they are.
Create routes first.
Set Filters early if you do not want the route to catch everything from that source/profile.
Change Options only when you actually need per-route behavior.
Route fields (what they mean)
Routes usually include:
Enabled: turns a route on/off.
Provider: Plex, Emby, Jellyfin.
Provider profile:
defaultorPLEX-P01, etc.Sink: Trakt, SIMKL, MDBList.
Sink profile:
defaultorTRAKT-P01, etc.Filters: per-route scrobble restrictions.
Options: per-route overrides for Watcher defaults.
A route is identified by:
provider + provider_instance + sink + sink_instance
Avoid duplicates unless you want double-scrobbles.
Common route options
Auto-remove from Watchlist: removes completed movies from watchlists.
Ratings (Plex only): require ratings webhook helper added in Plex.
Webhook tokens (helper endpoints)
Watcher itself does not need inbound webhooks.
One exception is Plex ratings, which uses:
POST /webhook/plexwatcher?uniqueID
This URL token is generated by CrossWatch.
If you rotate tokens in Settings → Scrobble → Watcher, the old URL stops working.
Update the webhook URL in Plex after rotating.
Filters
Username whitelist: only scrobble listed users.
Supports
id:<accountID>oruuid:<accountUUID>.
Server UUID (Plex only): restrict to one server.
User UUID (Emby/Jellyfin): restrict to one user.
Migration from legacy Watcher config
Before v0.9.0, Watcher used scrobble.watch.provider + scrobble.watch.sink.
As of v0.9.15, CrossWatch does not auto-migrate legacy Watcher config anymore.
If you still have an old Watcher config, create routes yourself.
Starting with a clean config.json is usually the best path.
Use this checklist:
Advanced

Playback event tuning
Pause debounce (sec) (default 5)
Ignores rapid duplicate pause events.
Config:
scrobble.watch.pause_debounce_seconds
Suppress start @ (%) (default 99)
Skips “start” events near the end of a title.
Config:
scrobble.watch.suppress_start_at
Regress tolerance (%) (default 5)
Clamps progress backwards jumps (seek glitches).
Config:
scrobble.trakt.regress_tolerance_percent
Progress step (%) (default 25, range 1–25)
Minimum progress delta before CW sends an update to sinks (trackers).
Higher values = fewer progress updates, thus fewer API calls.
Lower values = frequent progress updates, higher API calls.
Example: a 60 min movie.
1%≈ 100 API calls5%≈ 20 API calls25%≈ 4 API calls
Stop pause threshold (%) (default 80)
Treat STOP below this threshold as PAUSE.
Config:
scrobble.trakt.stop_pause_threshold
Force stop @ (%) (default 80)
Treat STOP at/above this as completed.
Config:
scrobble.trakt.force_stop_at
Troubleshooting quick checks
Nothing scrobbles: confirm Watcher is enabled and you clicked Save.
Wrong user: tighten Username whitelist / User UUID filters.
Wrong server (Plex): set Server UUID.
Missing matches: add TMDb metadata: Metadata
Slow updates: lower progress step, but expect more API calls.
Related topics
Scrobble overview: Scrobble
Pick Watcher vs legacy webhooks: Webhook or Watcher
Improve matching quality: Metadata
Legacy inbound endpoints: Webhooks (legacy)
Summary
Watcher scrobbles in real time.
Routes mode supports multiple sources and sinks.
Global settings are the defaults.
Use route filters so the route does not catch unwanted playback.
Use route options when one route needs different behavior.
Use profiles to scrobble multiple accounts or servers.
Next steps
Decide Watcher vs legacy webhook mode: Webhook or Watcher
Limit which libraries generate scrobbles: Library Whitelisting
Put CW behind TLS and a proxy (recommended for remote): Reverse proxies
Show “Now Playing” in the footer: Playing Card
Last updated
Was this helpful?