Configuration (config.json)

Config file location, load rules, and key reference for config.json.

Use this as a reference for config.json.

Values come from defaults and normalization in cw_platform/config_base.py.

circle-exclamation
circle-info

Avoid editing config.json by hand.

Most settings are configurable in the UI.

At a glance

Topic
Where
Notes

Config file

<CONFIG_BASE>/config.json

Created if missing.

Docker default

/config/config.json

Used when /app exists.

Manual edits

Avoid

UI covers most settings.

Secrets

Tokens and password hashes

Redact before sharing.

Config file location

CrossWatch chooses the config base directory in this order.

Priority
Condition
Base path

1

CONFIG_BASE env var is set

CONFIG_BASE value

2

Running in Docker image (/app exists)

/config

3

Running from source

Project root (one level above cw_platform/)

The file path is always:

  • <CONFIG_BASE>/config.json

Load and save behavior

Behavior
What it means

Defaults + deep merge

Your config overlays DEFAULT_CFG. Missing keys are filled in.

Unknown keys preserved

Extra keys are kept. Useful for experiments.

Version stamping

version is rewritten on load/save.

Pair feature normalization

pairs[].features.* are coerced to a uniform shape.

Atomic saves

Writes use a temp file then replace config.json.

Redaction helper

Sensitive fields can be masked for UI/log output.

Defaults + deep merge

On startup, CrossWatch:

  • Loads config.json.

  • Deep-merges it over DEFAULT_CFG.

Merge rules:

  • Dict + dict merges recursively.

  • Any other type overrides the default.

Version stamping

On load/save:

  • version = app version (leading v removed)

Priority
Source

1

api.versionAPI.CURRENT_VERSION

2

APP_VERSION env var

3

Fallback v0.7.0

Pair feature normalization

Each feature becomes:

Input
Normalized result

true

Enabled, adds on, removes off

Missing keys

Defaults: enable:true, add:true, remove:false

Invalid values

Feature disabled

Ratings has extra fields.

See Ratings feature.

Redaction

redact_config(cfg) replaces sensitive values with ••••••••.

Path
Notes

app_auth.password.hash

Password hash

app_auth.password.salt

Password salt

app_auth.session.token_hash

Session token hash

Key reference

Top-level

Key
Type
Notes

version

string

Managed by the app.

pairs

array

Pair definitions created in the UI.

plex, trakt, …

object

Provider connection and tuning.

sync

object

Global orchestrator defaults.

runtime

object

Logging and guardrails.

scrobble

object

Real-time progress forwarding.

scheduling

object

Periodic runs.

ui

object

UI toggles.

app_auth

object

Optional UI login.

Providers

Provider
Stores
Used for

plex

server URL, token, tuning

Sync + scrobble source

jellyfin / emby

server URL, token, tuning

Sync + scrobble source

trakt / simkl / mdblist

OAuth/API keys

Tracker targets/sources

anilist

OAuth/API keys

Anime tracker

tmdb

API key

Matching support

tautulli

URL + API key

History import

crosswatch

local paths + snapshot rules

Local backup provider

chevron-rightPlexhashtag

Connection

Key
Type
Notes

plex.server_url

string

Example: http://192.168.1.10:32400

plex.verify_ssl

bool

Keep false for self-signed.

plex.account_token

string

Set via UI PIN login.

plex.client_id

string

Client identifier.

plex.machine_id

string

Targets a specific server.

plex.username

string

Plex Home profile name.

plex.account_id

string

Server-local account ID.

plex.home_pin

string

Optional Plex Home PIN.

plex.timeout

number

Seconds.

plex.max_retries

int

Retry budget.

plex.fallback_GUID

bool

Discover fallback for missing GUID mapping.

Scrobble filters

Key
Type
Notes

plex.scrobble.libraries

array

Empty means all libraries.

History

Key
Type
Notes

plex.history.libraries

array

Whitelist of library GUIDs. Empty = all.

plex.history.include_marked_watched

bool

Include Plex “marked watched” state (add-only behavior).

plex.history_workers

int

Parallel workers for history indexing. 12–16 is ideal on a local NAS.

Ratings

Key
Type
Notes

plex.ratings.libraries

array

Whitelist of library GUIDs. Empty = all.

plex.rating_workers

int

Parallel workers for ratings indexing. 12–16 is ideal on a local NAS.

Watchlist (Discover-driven)

Key
Type
Notes

plex.watchlist_allow_pms_fallback

bool

Allow PMS watchlist fallback when needed. Keep false for strict Discover-only behavior.

plex.watchlist_page_size

int

Discover page size (100–200). Higher is faster, but can trigger 504s.

plex.watchlist_query_limit

int

Max Discover search results per query (10–25).

plex.watchlist_write_delay_ms

int

Optional pacing between Discover writes. Set 50–150 if you hit 429/5xx.

plex.watchlist_title_query

bool

Use title/slug tokens for Discover candidate fetching.

plex.watchlist_use_metadata_match

bool

Try PMS /library/metadata/matches first, then fallback to Discover.

plex.watchlist_guid_priority

array

GUID resolution order (first match wins).

chevron-rightTMDbhashtag
Key
Type
Notes

tmdb.api_key

string

TMDb API key used for metadata lookup and ID bridging.

chevron-rightTrakthashtag

OAuth

Key
Type
Notes

trakt.client_id

string

From your Trakt app.

trakt.client_secret

string

From your Trakt app.

trakt.access_token

string

OAuth2 access token.

trakt.refresh_token

string

OAuth2 refresh token.

trakt.scope

string

Usually public or private.

trakt.token_type

string

Usually Bearer.

trakt.expires_at

int

Epoch seconds.

trakt._pending_device

object

Temporary device code state (PIN flow).

HTTP

Key
Type
Notes

trakt.timeout

int

HTTP timeout (seconds).

trakt.max_retries

int

Retry budget (429/5xx backoff).

Watchlist

Key
Type
Notes

trakt.watchlist_use_etag

bool

Use ETag + local shadow to skip unchanged lists.

trakt.watchlist_shadow_ttl_hours

int

Refresh ETag baseline periodically even if 304s keep coming.

trakt.watchlist_batch_size

int

Chunk size for add/remove to reduce rate spikes.

trakt.watchlist_log_rate_limits

bool

Log X-RateLimit-* and Retry-After when present.

trakt.watchlist_freeze_details

bool

Persist last status & ids for debugging.

Ratings

Key
Type
Notes

trakt.ratings_per_page

int

Items per page when indexing (10–100).

trakt.ratings_max_pages

int

Safety cap per type.

trakt.ratings_chunk_size

int

Batch size for POST/REMOVE.

History

Key
Type
Notes

trakt.history_per_page

int

Max allowed by Trakt (100).

trakt.history_max_pages

int

Safety cap for large histories.

trakt.history_unresolved

bool

Enable unresolved “freeze” files.

trakt.history_number_fallback

bool

Episode number fallback if episode IDs are missing.

trakt.history_collection

bool

Mirror history adds into your Trakt Collection.

chevron-rightSIMKLhashtag
Key
Type
Notes

simkl.access_token

string

OAuth2 access token.

simkl.refresh_token

string

OAuth2 refresh token.

simkl.token_expires_at

int

Epoch seconds.

simkl.client_id

string

From your SIMKL app.

simkl.client_secret

string

From your SIMKL app.

simkl.date_from

string

YYYY-MM-DD (optional backfill start).

chevron-rightAniListhashtag
Key
Type
Notes

anilist.client_id

string

From your AniList app.

anilist.client_secret

string

From your AniList app.

anilist.access_token

string

OAuth access token.

anilist.user

object

Cached viewer object (id/name).

chevron-rightMDBListhashtag

Connection

Key
Type
Notes

mdblist.api_key

string

Your MDBList API key.

mdblist.timeout

int

HTTP timeout (seconds).

mdblist.max_retries

int

Retry budget.

Watchlist

Key
Type
Notes

mdblist.watchlist_shadow_ttl_hours

int

Shadow TTL (hours). 0 disables.

mdblist.watchlist_shadow_validate

bool

Validate shadow on every run.

mdblist.watchlist_page_size

int

GET page size for /watchlist/items.

mdblist.watchlist_batch_size

int

Batch size for add/remove writes.

mdblist.watchlist_freeze_details

bool

Store extra details for “not_found” freezes.

Ratings

Key
Type
Notes

mdblist.ratings_per_page

int

Items per page when indexing.

mdblist.ratings_max_pages

int

Max pages to fetch (safety cap).

mdblist.ratings_chunk_size

int

Batch size for POST/REMOVE.

mdblist.ratings_write_delay_ms

int

Optional pacing between writes.

mdblist.ratings_max_backoff_ms

int

Max backoff time for retries.

mdblist.ratings_since

string

First-run baseline; watermark overrides after.

History

Key
Type
Notes

mdblist.history_per_page

int

Items per page for watched delta.

mdblist.history_max_pages

int

Max pages to fetch (safety cap).

mdblist.history_chunk_size

int

Batch size for watched/unwatched writes.

mdblist.history_write_delay_ms

int

Optional pacing between writes.

mdblist.history_max_backoff_ms

int

Max backoff time for retries.

mdblist.history_since

string

First-run baseline; watermark overrides after.

chevron-rightTautullihashtag

Connection

Key
Type
Notes

tautulli.server_url

string

Example: http://host:8181

tautulli.api_key

string

Tautulli API key.

tautulli.verify_ssl

bool

Verify TLS certificates.

tautulli.timeout

number

HTTP timeout (seconds).

tautulli.max_retries

int

Retry budget.

History import

Key
Type
Notes

tautulli.history.user_id

string

Optional user filter.

tautulli.history.per_page

int

Tautulli history page size.

tautulli.history.max_pages

int

Safety cap.

chevron-rightJellyfin / Embyhashtag

Same structure.

Connection

Key
Type
Notes

*.server

string

Base URL.

*.access_token

string

Auth token.

*.user_id

string

Active user.

*.device_id

string

Client device id.

*.username

string

Optional login username.

*.user

string

Optional display name (hydrated after auth).

*.verify_ssl

bool

TLS verification.

*.timeout

number

Seconds.

*.max_retries

int

Retry budget.

Scrobble filters

Key
Type
Notes

*.scrobble.libraries

array

Whitelist of library GUIDs. Empty = all.

Watchlist (emulated)

Key
Type
Notes

*.watchlist.mode

string

favorites | playlist | collections

*.watchlist.playlist_name

string

Used when mode is playlist.

*.watchlist.watchlist_query_limit

int

Batch size.

*.watchlist.watchlist_write_delay_ms

int

Delay between writes.

*.watchlist.watchlist_guid_priority

array

ID match order.

History

Key
Type
Notes

*.history.history_query_limit

int

Batch size.

*.history.history_write_delay_ms

int

Delay between writes.

*.history.history_guid_priority

array

ID match order.

*.history.libraries

array

Whitelist of library GUIDs. Empty = all.

Ratings

Key
Type
Notes

*.ratings.ratings_query_limit

int

Ratings query limit (default 2000).

*.ratings.libraries

array

Whitelist of library GUIDs. Empty = all.

chevron-rightCrossWatch (local provider)hashtag
Key
Type
Notes

crosswatch.root_dir

string

Local provider folder.

crosswatch.enabled

bool

Enables provider.

crosswatch.auto_snapshot

bool

Snapshot before writes.

crosswatch.retention_days

int

0 keeps forever.

crosswatch.max_snapshots

int

0 unlimited.

crosswatch.restore_watchlist

string

latest, empty, or a specific snapshot stem.

crosswatch.restore_history

string

latest, empty, or a specific snapshot stem.

crosswatch.restore_ratings

string

latest, empty, or a specific snapshot stem.

Sync (sync)

Global defaults. Pair-level settings override these by design.

Key
Type
Notes

sync.enable_add

bool

Allow additions by default.

sync.enable_remove

bool

Safer default: disabled unless you opt in.

sync.verify_after_write

bool

When supported, re-check destination after writes.

sync.dry_run

bool

Plan and log only. No writes.

sync.drop_guard

bool

Guard against empty/suspect snapshots.

sync.allow_mass_delete

bool

If false, block large delete plans.

sync.tombstone_ttl_days

int

How long “observed deletes” stay valid.

sync.include_observed_deletes

bool

If false, skip processing observed deletes for the run.

Two-way defaults (optional)

Key
Type
Notes

sync.bidirectional.enabled

bool

Default off. Pairs still decide final mode.

sync.bidirectional.mode

string

Placeholder default (usually two-way).

sync.bidirectional.source_of_truth

string

Optional tie-breaker if you enforce strict authority.

Blackbox (including flapper protection)

Key
Type
Notes

sync.blackbox.enabled

bool

Turn off to fully disable blackbox logic.

sync.blackbox.promote_after

int

Promote after N consecutive unresolved/fail events.

sync.blackbox.unresolved_days

int

Minimum unresolved age before it counts (0 = immediate).

sync.blackbox.pair_scoped

bool

Track per pair to avoid blocking the same title elsewhere.

sync.blackbox.cooldown_days

int

Auto-prune after cooldown.

sync.blackbox.block_adds

bool

Block planned ADDs while blackboxed.

sync.blackbox.block_removes

bool

Block planned REMOVEs while blackboxed.

Runtime (runtime)

Key
Type
Notes

runtime.debug

bool

Extra verbose logging (debug level).

runtime.debug_http

bool

Extra verbose HTTP logging.

runtime.debug_mods

bool

Extra verbose MOD logs for Synchronization Providers.

runtime.state_dir

string

Optional override for state dir. Avoid for containers.

runtime.telemetry.enabled

bool

Usage stats.

runtime.snapshot_ttl_sec

int

Reuse snapshots within this window.

runtime.apply_chunk_size

int

Batch size for apply.

runtime.apply_chunk_pause_ms

int

Pause between chunks.

runtime.apply_chunk_size_by_provider

object

Per-provider overrides (example: SIMKL).

runtime.suspect_min_prev

int

Minimum previous size to enable suspect guard.

runtime.suspect_shrink_ratio

number

Shrink ratio to trigger suspect guard.

Metadata (metadata)

Key
Type
Notes

metadata.locale

string

Example: en-US.

metadata.ttl_hours

int

Coarse resolver cache TTL.

Scrobble (scrobble)

Key
Type
Notes

scrobble.enabled

bool

Master toggle.

scrobble.mode

string

watch or webhook.

scrobble.delete_plex

bool

Legacy name but still valid. Auto-remove movies from watchlists.

scrobble.delete_plex_types

array

Legacy name but still valid. Types: movie, show, episode.

Watcher mode (scrobble.watch)

Key
Type
Notes

scrobble.watch.autostart

bool

Start watcher on boot if enabled + mode=watch.

scrobble.watch.provider

string

plex | emby | jellyfin.

scrobble.watch.sink

string

trakt | simkl | mdblist.

scrobble.watch.plex_simkl_ratings

bool

Forward Plex ratings to SIMKL.

scrobble.watch.plex_trakt_ratings

bool

Forward Plex ratings to Trakt.

scrobble.watch.plex_mdblist_ratings

bool

Forward Plex ratings to MDBList.

scrobble.watch.pause_debounce_seconds

int

Ignore micro-pauses just after start.

scrobble.watch.suppress_start_at

int

Kill near-end start flaps (credits).

scrobble.watch.filters.username_whitelist

array

["name", "id:123", "uuid:abcd…"]

scrobble.watch.filters.server_uuid

string

Restrict to a specific server (Plex).

Webhook mode (scrobble.webhook)

Key
Type
Notes

scrobble.webhook.pause_debounce_seconds

int

Ignore micro-pauses.

scrobble.webhook.suppress_start_at

int

Suppress near-end start flaps.

scrobble.webhook.suppress_autoplay_seconds

int

Plex autoplay suppression window.

scrobble.webhook.probe_session_progress

bool

Probe Plex sessions to match item by ratingKey/sessionKey.

scrobble.webhook.plex_trakt_ratings

bool

Forward Plex ratings to Trakt in webhook mode.

scrobble.webhook.filters_plex.username_whitelist

array

Accepted Account.title values. Empty = allow all.

scrobble.webhook.filters_plex.server_uuid

string

Restrict to a specific Plex server.

Progress rules (scrobble.trakt)

Used by Trakt, SIMKL, and MDBList sinks.

Key
Type
Notes

scrobble.trakt.progress_step

int

Send progress in % steps.

scrobble.trakt.stop_pause_threshold

int

STOP below this becomes PAUSE.

scrobble.trakt.force_stop_at

int

STOP at/above this is forced.

scrobble.trakt.regress_tolerance_percent

int

Clamp small backwards jumps.

Scheduling (scheduling)

Key
Type
Notes

scheduling.enabled

bool

Master toggle for periodic runs.

scheduling.mode

string

hourly or daily.

scheduling.every_n_hours

int

When mode=hourly, run every N hours (1–12).

scheduling.daily_time

string

When mode=daily, run at HH:MM (24h).

UI (ui)

Key
Type
Notes

ui.show_watchlist_preview

bool

Show Watchlist Preview on Main tab.

ui.show_playingcard

bool

Show Now Playing card on Main tab.

ui.show_AI

bool

Show ASK AI (GitBook) in UI.

ui.protocol

string

http or https.

TLS (ui.tls)

Key
Type
Notes

ui.tls.self_signed

bool

Auto-generate a self-signed certificate when missing.

ui.tls.hostname

string

Used for certificate CN/SAN.

ui.tls.valid_days

int

Certificate validity (days).

ui.tls.cert_file

string

Optional override path to a PEM cert.

ui.tls.key_file

string

Optional override path to a PEM key.

UI auth (app_auth)

Key
Type
Notes

app_auth.enabled

bool

Enables login.

app_auth.username

string

Required when enabled.

Pairs (pairs[])

Each entry is one sync connection.

Field
Type
Notes

id

string

Generated by UI/API.

enabled

bool

Master switch.

source

string

Provider name.

target

string

Provider name.

mode

string

one-way or two-way.

features

object

Per-feature rules.

Feature format

Field
Type
Meaning

enable

bool

Run feature at all.

add

bool

Allow adds to target.

remove

bool

Allow removes on target.

Example:

Special: pairs[].features.ratings

Key
Type
Notes

types

array

movies, shows, seasons, episodes. all expands.

mode

string

only_new or from_date.

from_date

string

Used only when mode = "from_date".

Last updated