Skip to content

Configuration Reference ​

Documentation home · User guide · FAQ

If you are unsure which settings to choose, start with Choose Your Processing Mode. This page is a field reference, not a checklist you need to fill out from top to bottom.

All settings can be changed in the web console and take effect in about 1 second after saving, except for the few marked as requiring a main-process restart. This is the full field reference; look up the relevant section when you need it rather than reading every field for everyday use. The console itself is currently in Chinese, so key UI labels are retained below with English explanations.

Settings fall into four categories:

CategoryLocationWhere to edit
System configurationsystem: in data/config.yamlThe web console's “设置” (Settings) pages
Plugin configurationplugins.<插件名> in data/config.yaml: the enabled switch and the plugin's own settings; <插件名> is the plugin nameThe console's “插件” (Plugins) page, with one card per plugin
Secretsdata/secrets.json, with mode 600 permissions; not included in the configuration fileThe console's “设置” (Settings) pages show only whether a secret is set; you can replace or clear it, but cannot read back its value
Fixed, not configurableCode constantsNo settings provided; see Runtime File Locations

Each settings page saves separately, writing data/config.yaml atomically. You can also edit this file directly; the running Worker adopts valid changes in about 1 second. Saving checks the configuration version loaded by the page. If another page or process changed it in the meantime, the save is rejected; reload before editing again. If the file becomes invalid, Reelay keeps using the last valid version and shows the faulty file and reason on the overview and settings pages. Saving through the console is blocked during this time, so it will not overwrite your file, and resumes once you fix it. See config.example.yaml for a complete example.

Every field has a default. The tables below list defaults and their meanings; entries in sources[] can override any field in defaults.

yaml
system:
  save_dirs: {电影: "123", 剧集: "456", 默认: "0"}
  defaults: {approval_mode: manual, save_to: 默认}
  sources: [{bot: "@some_bot"}]
  llm: {base_url: "", model: gpt-4o-mini}
  # …other system configuration
plugins:
  organizer: {enabled: true, conflict: manual, naming: {...}}
  daily_report: {enabled: true, narrative: true}
  # …other plugins

System Configuration (system) ​

Directories and Sources (save_dirs, sources, providers) ​

FieldDefaultDescription
save_dirs—Directory alias → 115 directory CID, as a decimal string. At least one is required; 0 is the root directory
sources[].bot—The @username or numeric ID to monitor, case-insensitive. It can also be a list, such as ["@a", "@b"]; all listed sources share the card's settings. Each source may appear in only one card
sources[].*Same as defaultsPer-source overrides for approval mode, destination directory, parser, filters, preferences, and other settings
providers.sourcetelegramMessage-source Provider
providers.notify[console]List of notification channels; console sends to Telegram when a control Bot is configured, otherwise to the log

Identification and Decisions (defaults, sources[]) ​

FieldDefaultDescription
approval_modemanualApproval mode: manual requires your confirmation for every eligible resource; auto (“AI 处理”, AI processing) saves directly when identification and rules pass. Uncertain cases, including low confidence, no TMDB match, or LLM fallback, still require manual review
bot_notifytrueBot notifications, independent of approval mode: send approval cards that can be acted on in Telegram, plus library-addition notifications. When disabled, handle approvals under “待审批” (Pending approvals) in the console. Transfer and organization problem alerts are still sent
subscriptions_onlyfalse“仅处理订阅” (Subscriptions only): ignore resources that do not match an active subscription instead of sending them to pending approvals. Set the global default under “基础 → 默认处理方式” (Basics → Default processing mode); source cards can override it. An unset source value inherits the global setting
save_to默认Default destination-directory alias; 默认 means Default
parserllmllm or regex. llm supplies rule-based identification results to AI as reference. If the LLM is unavailable, still fails after timeout retries, or returns invalid output, fall back to regex and force manual confirmation
parse_rulesNonePer-source Python regular expressions, in multiline mode, for title, year, season, episodes, resolution, and size, using the first capture group. episodes combines all matches: use one capture group for a single episode, or named groups start and end for a range; end alone means episode 1 through end. Missing or unmatched fields use the generic rules. “识别规则” (Identification rules) on a source card can read recent channel messages for AI-assisted drafting and test runs
llm_response_formatjson_schemaUse json_object for compatible APIs without structured-output support; strict local validation still applies
decisionsubscriptionDecision strategy: default uses rules only; subscription adds automatic approval for new episodes of subscribed series; llm additionally uses the natural-language preferences, with recent approvals and ignores from the same source, to decide whether to save. All three decide only whether to proceed; destinations are determined by save_to and category rules. Reliably identified, TMDB-matched messages whose episodes are all in the library are skipped directly
preferences""For example, “Only Chinese TV series and Japanese anime in 4K or 1080p; no variety shows.” To turn this into deterministic rules, use “用一句话生成规则” (Generate rules from one sentence) in the console
confidence_threshold0.5Below this value, request manual review. Confidence is calculated from the presence of title, type, and year and whether TMDB matched, not from the LLM's self-reported score
episodes_fromshareshare: use filenames in the share and save all episodes not already in the library; message: save only episodes stated in the message
filters.must_have[]The text or links must contain at least one listed term; otherwise skip without calling the LLM
filters.block_keywords[]Skip if the text contains any listed term, without calling the LLM
filters.allow[]List of conditions; at least one must match. Empty means unrestricted. Fields are media_type (movie/tv/anime), genre_ids (TMDB genre IDs), and origin_country (two-letter codes). Syntax matches category rules: fields within one condition are ANDed, comma-separated values are ORed
filters.deny[]List of conditions; skip if any matches
filters.min_resolutionUnrestricted480p / 720p / 1080p / 2160p; skip lower resolutions and request manual review if resolution is unknown
forwardInherit globalPer-source forwarding override; see below

After passing ignored-title and filter checks, resources with low confidence, no trustworthy match when TMDB is enabled, or an LLM fallback require manual review regardless of approval mode. allow, deny, and min_resolution evaluate fields after identification and TMDB enrichment. The console's “用一句话生成规则” (Generate rules from one sentence) drafts these rules from a natural-language preference and saves them only after your confirmation.

Version note: “仅处理订阅” (Subscriptions only) is supported from v1.5.0 onward. Earlier versions do not have this setting. See the User guide for examples and the Changelog for release history.

Subscriptions only differs from “规则 + 订阅放行” (Rules + subscription auto-approval): the latter makes new subscribed episodes easier to save automatically but does not exclude unsubscribed titles. subscriptions_only: true instead applies a hard filter first, regardless of approval mode or decision strategy.

  • The work must be identified through TMDB and match a subscribed season. Resources with no subscription, a canceled or completed subscription, or no confirmed match to an active subscription are ignored directly. If TMDB is not configured or matching fails, they do not enter pending approvals either.
  • A subscription set to “仅提醒、不自动放行” (Reminders only, no automatic approval) is still active. After a match, the existing filters, confidence checks, deduplication, and approval rules continue to apply; matching does not mean automatic saving in every case.
  • A multi-season collection not narrowed to one season requires an active subscription for every season, or the whole message is ignored. If only one season is confirmed, transfers are limited to that season.
  • Reelay still needs to identify the message and perform configured TMDB matching and share probing before it can determine whether the resource is subscribed. Ignored messages retain their task records and reasons but are not forwarded and do not produce identification or approval notifications.
  • Omitting the field on a source inherits the global value; explicit false overrides global true. Changes affect newly received tasks only: they do not clear existing pending approvals or stop transfers already underway. Adding a subscription does not automatically replay previously ignored messages.

AI Capabilities (ai) ​

FieldDefaultDescription
ai.examples3Number of recent manual corrections from the same source to include as identification prompt examples, from 0–10; 0 disables this
ai.history20For decision: llm, number of recent manual approvals and ignores from the same source to include, from 0–100; 0 disables this. Ignores due to expired shares or all stated episodes already being in the library are excluded. The AI's decision and reason appear in the task trace
ai.assisttrueWhen rules cannot determine which share files to save—unrecognized episode or season numbers, multiple files for the same episode, multiple main-feature candidates, or a message with only episode numbers and a multi-season share—ask AI for a proposal first. Validate it with the same rules, and request manual intervention only if it fails
ai.advicetrueAttach a suggested action—approve, ignore, or review—and reason to pending approvals. Rules choose the action; AI supplies only the wording
ai.suggest_auto.min_decisions20Minimum manual decisions for a source before assessing whether to suggest “改为 AI 处理” (Switch to AI processing)
ai.suggest_auto.approve_rate0.9Approval rate must be at least this value
ai.suggest_auto.max_correct_rate0.1Fraction of identification results corrected must be no higher than this value

Suggestions are advisory only. Changing the approval mode requires your confirmation in the console.

Release Preferences (release) ​

When multiple versions of an episode or movie exist, both pending-approval recommendations and upgrades (plugins.organizer.conflict: upgrade) compare them in this order: preferred subtitles → resolution → HDR → preferred audio → preferred source → size. List order determines priority.

FieldDefaultDescription
release.prefer_subtitles[chs, cht]chs Simplified Chinese / cht Traditional Chinese / eng / jpn / kor; an empty list ignores subtitles
release.prefer_audio[]mandarin / cantonese / english / japanese / korean
release.hdranyany: no preference; prefer: favor HDR and Dolby Vision; avoid: avoid them
release.prefer_sources[]remux / bluray / web-dl / webrip / hdtv / dvd

For recommendations, information missing from the message counts as not meeting a preference. Upgrades delete old files, so their comparison is stricter: if the library file is known to meet a preference but the new file does not state that information, it will not replace the old one.

Forwarding, Approval Reminders, and Scheduling ​

FieldDefaultDescription
forward.enabledfalseForward successfully identified resources using a template
forward.target""Forwarding destination; the control Bot must be able to send messages there
forward.templateSee exampleAvailable fields: {title} {year} {resolution} {size} {link}
approval.timeout_hours24Pending approvals older than this many hours are considered overdue
approval.on_timeoutremindremind: send reminders; skip: ignore overdue tasks directly
approval.reminderdigestdigest: combine all overdue tasks into one summary; card: resend individual confirmation cards
approval.max_reminders3Maximum reminders per task. Afterward, the task stays pending but receives no further reminders; 0 means unlimited
schedule.daily_hour9Local hour for daily system events, such as reports and episode inspections. At startup, wait for parsing of downtime-backfilled messages first, for up to 15 minutes

AI Services and TMDB (llm, tmdb) ​

FieldDefaultDescription
llm.base_urlEmptyOpenAI-compatible API endpoint; leave empty for the official OpenAI endpoint
llm.modelgpt-4o-miniModel name. On opening the console, it fetches the API's model list using the saved key, and only listed models can be selected. Direct configuration-file edits are not restricted by this list
llm.reasoning_effortEmptyReasoning effort, sent as reasoning_effort with every request: none / minimal / low / medium / high / xhigh / max. Empty omits the parameter and lets the model decide. Providers support different values; for example, DeepSeek accepts only low / high / xhigh / max. The console detects the current model's supported values and disables the others. If a request is rejected because of this parameter, retry automatically without it rather than failing identification
tmdb.base_urlEmptyEmpty uses https://api.themoviedb.org/3. DNS interference with this domain is common on networks in China; configure a network proxy, use the official alternative https://api.tmdb.org/3, or use your own reverse proxy
tmdb.language / tmdb.timeoutzh-CN / 10TMDB matching language and timeout in seconds

AI API keys and TMDB keys are secrets; changes take effect immediately. Under “设置 → AI 与 TMDB” (Settings → AI and TMDB), you can fetch models from the endpoint currently entered in the form using OpenAI-compatible GET /models, and test connectivity with a very short message using the current endpoint, model, and reasoning effort, without saving first.

Saved keys are sent only to saved endpoints. If the endpoint in the form differs from the saved one, you must also enter a key for that endpoint before fetching models or testing. Saving a change to llm.base_url or tmdb.base_url clears the corresponding old key, which must be entered again.

Telegram (telegram) ​

FieldDefaultDescription
telegram.owner_idEmptyYour numeric Telegram ID. The control Bot serves only this ID; leave empty to disable it. Requires a main-process restart
telegram.backfill_limit / backfill_max_days200 / 7Maximum messages per source to backfill after startup or reconnection, and maximum message age in days; 0 disables backfilling. A newly monitored source does not import its history
telegram.alert_after_sec120How long the message source must be disconnected before an alert, including when Telegram is not yet configured or logged in; measured from the moment of disconnection

115 Request Limits (p115) ​

FieldDefaultDescription
p115.open_qps / cookie_qps / share_qps3 / 2 / 1Maximum requests per second for open-platform, web, and share/transfer APIs, respectively
p115.risk_cooldown_sec3600Seconds to pause all APIs after 115 protection is triggered by access limits or excessive operations. Transfers and organization pause during the cooldown and resume automatically afterward, without failures or retry consumption. The cooldown survives main-process restarts. If 115 says a previous operation is still running, such as permitting only one deletion at a time, this is not treated as a protection cooldown; only that operation retries automatically after 30 seconds

Obtain a 115 login by scanning the QR code under “设置 → 115 网盘” (Settings → 115 Drive). Credentials are stored in data/115_credentials.json.

Network Proxy (proxy) ​

If your network cannot reach Telegram, TMDB, or the AI service, connect them through an HTTP or SOCKS5 proxy. HTTP or mixed ports from clients such as Clash, mihomo, or v2rayN work. 115 servers are in China and always use a direct connection.

FieldDefaultDescription
proxy.urlEmptyProxy URL, such as http://192.168.1.2:7890 or socks5://127.0.0.1:1080; empty disables the proxy. For authentication, use http://用户名@地址:端口, replacing the placeholders with username, address, and port. Store the password in the proxy_password secret, not in the URL. In Docker, 127.0.0.1 is the container itself; if the proxy runs on the host or another LAN device, use that device's LAN address
proxy.telegramtrueProxy the listener, control Bot, and terminal login (python -m reelay.login)
proxy.tmdbtrueProxy TMDB
proxy.aitrueProxy the AI service; can be disabled for a locally reachable provider or local model

TMDB and AI changes take effect immediately after saving. Telegram requires a main-process restart; if it is not connected yet, the next retry, every 30 seconds, uses the new settings. Services not using this proxy retain their previous connection behavior: TMDB and AI still honor HTTP_PROXY / HTTPS_PROXY environment variables, while Telegram connects directly.

“测试代理” (Test proxy) under “设置 → 网络代理” (Settings → Network proxy) uses the form's current address to connect once through the proxy to each enabled service, without saving first. For Telegram it only connects to a data center and does not log in; any response from TMDB or the AI service counts as reachable. As with AI keys, a saved proxy password is sent only to the saved address, and saving a different proxy.url clears the password.

Runtime Settings (runtime) ​

FieldDefaultDescription
runtime.concurrency3Number of tasks processed concurrently; requires a main-process restart
runtime.log_levelINFODEBUG / INFO / WARNING / ERROR; requires a main-process restart

Plugin Configuration (plugins) ​

Each plugin's settings live under plugins.<插件名>, where <插件名> is its name. enabled is its switch; if omitted, the plugin's declared default is used. All built-in plugins are enabled by default. Plugins without other settings, such as tmdb_enrich, share_probe, and failure_explainer, have only this switch. External plugins store their settings here too; see the Plugin development guide.

Library Organization (plugins.organizer) ​

Before transfer, the directory layout determines the destination. After transfer, naming templates drive directory creation, renaming, and moving, followed by read-back verification. Both steps share one switch.

FieldDefaultDescription
plugins.organizer.layoutcategoryDirectory layout: category uses two-level category rules, described below; media_type groups by media type using type_dirs; none skips classification and stores directly in the source's destination directory
plugins.organizer.type_dirs{movie: 电影, tv: 剧集, anime: 动漫}Single-level folder names for media-type layout. Titles identified as anime or with the Animation genre (16) go into anime. If anime is empty, do not separate them; place them under movie or TV instead. The defaults mean Movies, TV series, and Anime
plugins.organizer.naming.movie / tvSee exampleRestricted Jinja2 path templates, with variables matching MoviePilot's renaming format: title original_title name en_name year tmdbid season episode season_episode part videoFormat videoCodec audioCodec resourceType effect edition releaseGroup fileExt (including the dot) original_name (original filename). Season and episode fields are empty for movies. en_title season_year imdbid doubanid episode_title episode_date customization are currently empty. Filters: default lower upper replace trim join length pad2
plugins.organizer.conflictmanualWhen a file for the same episode or movie already exists: manual requests intervention so you can delete this transfer's files or overwrite and save in the console; skip keeps the old files and sends the new ones to the recycle bin; suffix keeps both by appending “ (2)” to the new name; upgrade compares using release preferences, replacing old files with better new versions and moving old files to the recycle bin, or behaving like skip otherwise

Two-level category rules ship with the plugin in reelay/plugins/organizer/category.yaml, not in the configuration file; the console displays them read-only. Matching follows MoviePilot: use movie for TMDB movies and tv for series, including anime, documentaries, and variety shows. Take the first category, from top to bottom, whose conditions all match. Condition fields are genre_ids (TMDB genre IDs), origin_country (two-letter country/region codes), and release_year (a year or range such as 2000-2010). Comma-separated values mean OR. A category without conditions always matches and serves as a fallback when placed last. A category does not match if the work lacks data required by its conditions. If no category matches, store directly in the save directory.

If the classification result—the first level of a two-level category, or the media-type folder—matches a save_dirs alias, that alias determines the transfer root. Otherwise, create the full path below the source's configured directory. A directory manually selected during approval in the console or MCP takes precedence: if it differs from the classification result, store directly there without adding category subdirectories. If no directory is selected manually, classification applies automatically. Pending-approval cards and Telegram approval cards show the actual drive path, such as /测试/剧集/国产剧集; before the main process has read the directory path, they show “alias/category” instead.

Other Plugins ​

FieldDefaultDescription
plugins.share_probe.enabledtrueMessages with only ed2k links do not access 115; infer seasons, episodes, sizes, and releases from the links' filenames and sizes. After identification, inspect 115 shares read-only: expired, canceled, or policy-violating shares are marked “分享无法访问” (Share inaccessible) in pending approvals with a suggestion to ignore. For series whose message omits episode numbers, list share contents to show actual seasons, episodes, and size, for example “S01–S03 · 30 集” (30 episodes), and flag issues likely to require manual intervention during transfer, such as unrecognizable season/episode filenames. Read one share at a time, at least 2 seconds apart, listing at most 20 directories per share; do not read during 115 protection cooldowns. If the message omits resolution, source, or size, the same query supplements them from root-directory videos using filenames or 115's detected resolution
plugins.tmdb_enrich.enabledtrueMatch TMDB after identification to fill in normalized metadata and posters. TMDB endpoint, language, and key are system-level settings
plugins.episode_tracker.track_alltrueAutomatically track series with recently added episodes; report only gaps and episodes aired according to TMDB but not yet in the library
plugins.episode_tracker.lookback_days30Lookback window for automatic tracking
plugins.daily_report.narrativetrueWhen AI is configured, prepend a short AI-written reminder based on the report's factual statistics; keep the numerical report too

Subscriptions and Ignored Titles ​

Subscriptions and titles marked “不再接收” (Stop receiving) are user data in the database (data/reelay.db), not configuration. Manage them through “追剧订阅” (Series subscriptions) in the console, Telegram approval-card actions “追剧并转存” (Subscribe and save) and “不再接收” (Stop receiving), the /subs and /ignored commands, or MCP. Changes do not alter the configuration version.

  • Series subscriptions: title, season, optional total episode count, optional TMDB ID, and whether to auto-approve. Missing-episode inspections start at episode 1. With auto-approval enabled, new episodes of the same tmdbid, or TMDB-normalized title when no ID is present, and the same season save directly from sources using decision: subscription or llm. A TMDB match, sufficient confidence, unambiguous filter results, and at least one message episode not already in the library are still required. If the message omits season/episode information, confirm the season by inspecting the share (share_probe); multi-season collections are not auto-approved. If the message omits a season number, transfer only the subscribed season. A subscription ends automatically once airing is complete and all episodes are in the library.
  • Ignored titles: title, optional TMDB ID, and media type (movie / TV). After identification, messages with the same tmdbid and type, or the TMDB-normalized title if there is no tmdbid, are ignored directly.

Secrets ​

Enter secrets on the console's “设置” (Settings) pages; they apply when saved. Pages display only “已设置 / 未设置” (Set / Not set). Changing the control Bot token requires a main-process restart. Telegram API ID / Hash changes are adopted automatically if the listener has not connected yet; changing them after it connects requires a restart.

NamePageDescription
llm_api_key“AI 与 TMDB” (AI and TMDB)AI API key. Without it, identification falls back to rules and every item requires manual review. Cleared automatically when llm.base_url changes
tmdb_api_key“AI 与 TMDB” (AI and TMDB)TMDB v3 API Key or v4 Read Access Token. Cleared automatically when tmdb.base_url changes
telegram_api_id / telegram_api_hashTelegramTelegram API credentials for your personal account
control_bot_tokenTelegramControl Bot token
proxy_password“网络代理” (Network proxy)Proxy authentication password, used only when proxy.url includes a username. Cleared automatically when proxy.url changes
web_password“运行与安全” (Runtime and security)Console login password, at least 8 characters, stored only as a PBKDF2 hash. Set it the first time you open the console; a LAN device opening it by IP can also do this. Before it is set, endpoints other than initial setup accept only local addresses. Changing or clearing it requires the current password first; changing it forces other logged-in pages to sign in again. Sessions are stored in the database, last 7 days, and survive Web restarts. If you forget the password, delete only the web_password entry from data/secrets.json, then reopen the console to set a new one
mcp_token / mcp_readonly_token“运行与安全” (Runtime and security)MCP access tokens, read-write / read-only. External agents access /mcp with Authorization: Bearer <令牌>, replacing <令牌> with their token. Read-only tokens do not expose write tools. Tokens must be at least 24 characters and distinct; the console can generate them randomly. If neither is set, /mcp is disabled. Independent of the Web login password

Runtime File Locations ​

These locations are fixed and have no configuration options. For backups or migration, copy all of data/ together; in Docker it is the volume mounted at /app/data.

FileDescription
data/config.yamlSystem and plugin configuration
data/secrets.jsonSecrets
data/reelay.dbSQLite database; do not place it on a network filesystem
data/userbot.session / data/controlbot.sessionTelegram sessions for the personal account and control Bot
data/115_credentials.json115 cookies and open-platform tokens
data/reelay.logMain-process log, read by “运行日志” (Runtime logs) in the console; rotates above 10 MB into reelay.log.1 through .5
data/plugins/External extensions directory
data/eval/Local evaluation samples and reports

These parameters are fixed too: 2 retries for transient LLM errors, starting with a 2-second delay; 115 credential health checks every 5 minutes, or every 30 seconds while paused due to invalid credentials; hourly approval-timeout scans; 115 QR login binds a TV-device session; and OAuth tokens with a 2-hour lifetime refresh 15 minutes before expiry.

Environment Variables ​

Only a few values need to be known before startup or depend on the deployment method. Put them in .env; see .env.example.

VariableDefaultDescription
REELAY_VERSIONlatestDocker Compose only: image version, such as 1.0.0
REELAY_WEB_HOST / REELAY_WEB_PORT127.0.0.1 / 28080Console bind address for local execution. For Docker, change ports in compose.yaml
REELAY_FORWARDED_ALLOW_IPS127.0.0.1Reverse proxies whose forwarded client addresses (X-Forwarded-For) the console trusts. Comma-separated; * trusts all. Failed-login rate limits use the real client address. In Docker, use the reverse proxy's address on the container network
REELAY_MCP_READONLYEmptySet to 1 to expose only MCP query tools, for both stdio and HTTP; the HTTP read-write token becomes read-only too
REELAY_LOG_LEVELWARNINGMCP stdio only (python -m reelay.mcp_server): log level for stderr. The main process uses runtime.log_level in system configuration
VITE_BASE_PATH/Frontend subpath prefix at build time, for reverse proxies serving a subpath