"intro":"Operational settings stored in the database — these override the file/env defaults and take effect without a redeploy. Leave a field empty (or reset it) to fall back to the default.",
"hint":"e.g. Siftlode <addr@gmail.com>. Defaults to the username."
},
"smtp_password":{
"label":"SMTP password",
"hint":"App password. Stored encrypted; write-only — it's never shown back."
},
"quota_daily_budget":{
"label":"Daily quota budget",
"hint":"Total YouTube Data API units to spend per day (free tier is 10,000). Default 9000 leaves headroom."
},
"backfill_quota_reserve":{
"label":"Backfill quota reserve",
"hint":"Units kept in reserve so scheduled backfill never starves interactive syncs / enrichment."
},
"search_daily_limit_per_user":{
"label":"Live search — daily limit per user",
"hint":"Max live YouTube searches per user per day. With the API source each search costs 100 units (so the shared budget affords only ~80-90/day total); with the scrape source it's a pure anti-abuse limit. Set 0 to disable live search."
},
"search_source":{
"label":"Live search source",
"hint":"Where live YouTube search results come from. \"scrape\" uses YouTube's internal endpoint and spends no API quota (recommended). \"api\" uses the official search.list (100 units/page). Switch to \"api\" if scraping ever breaks or is blocked."
},
"backfill_recent_max_videos":{
"label":"Recent backfill — max videos",
"hint":"Newest videos fetched per channel on the first pass."
},
"backfill_recent_max_days":{
"label":"Recent backfill — max age (days)",
"hint":"How far back the first pass reaches per channel."
},
"shorts_probe_max_seconds":{
"label":"Shorts probe — max duration (s)",
"hint":"Only videos at or below this length are probed as possible Shorts."
},
"shorts_probe_batch":{
"label":"Shorts probe — batch size",
"hint":"How many videos to classify per run."
},
"enrich_batch_size":{
"label":"Enrichment batch size",
"hint":"videos.list ids per call (YouTube caps this at 50)."
},
"autotag_title_sample":{
"label":"Auto-tag title sample",
"hint":"Recent video titles sampled per channel for language detection."
},
"youtube_api_key":{
"label":"YouTube API key",
"hint":"Optional. Used for public reads (channels/videos) so shared backfill doesn't depend on a user's OAuth. Stored encrypted; write-only."
},
"youtube_api_proxy":{
"label":"YouTube API egress proxy",
"hint":"Optional. HTTP(S) proxy URL for outbound YouTube API calls — route them through a fixed-IP host so an IP-restricted key keeps working from a dynamic-IP server. Leave empty for direct."
},
"google_client_id":{
"label":"Google client ID",
"hint":"OAuth 2.0 client ID for Sign in with Google. Stored encrypted; write-only. Leave both Google fields empty to disable Google sign-in (email+password still works)."
"hint":"When on, anyone can submit an email+password registration. They still need to verify their email and be approved by an admin before they can sign in."
},
"explore_grace_days":{
"label":"Explore — grace period (days)",
"hint":"How long an explored-but-unsubscribed channel (and its ephemeral videos) is kept before the cleanup job removes it. Subscribing keeps it permanently."
"hint":"Expose the Plex library as a feed source with a rich player. Requires the Plex server to be reachable from this host and its media on a local mount (see the path map)."
"hint":"The server admin X-Plex-Token. Used server-side only (metadata + images); never sent to the browser. Stored encrypted; write-only."
},
"plex_path_map":{
"label":"Media path map",
"hint":"Maps Plex's on-disk paths to this host's local mount so Siftlode can play the physical file. Newline/comma-separated plexPrefix=localPrefix pairs, e.g. /data=/plex-media. Empty = identical on both sides."
},
"plex_libraries":{
"label":"Exposed libraries",
"hint":"Comma-separated Plex section keys to expose. Empty = all sections. Use the library picker below after testing the connection."
},
"plex_sync_interval_min":{
"label":"Sync interval (minutes)",
"hint":"How often the catalog sync job mirrors Plex metadata."
},
"plex_max_transcodes":{
"label":"Max concurrent transcodes",
"hint":"Cap on simultaneous CPU transcodes for incompatible files (a later fallback). Direct-playable files aren't limited."
"plexMediaOk":"Media mount OK — a sample file was found on disk.",
"plexMediaMissing":"Media not readable at {{path}} — check that the Plex media is bind-mounted into the container and that the path map is correct. Playback will fail until this is fixed.",