Skip to content

Recyclarr Config Generator

Generates a recyclarr configuration from live Sonarr and Radarr instances, instead of hand-writing one and syncing it the other way.

Point it at each *arr, and it reads what is already configured — quality profiles, custom format scores, quality definition sizes, naming formats — and renders the equivalent recyclarr.yml. Custom formats are matched back to their TRaSH Guides trash_id by name, so the output is guide-backed and safe to recyclarr sync.

This is a one-way snapshot tool. Once the config exists, recyclarr becomes the source of truth and you edit the YAML, not the UI.

  • Python 3.9+
  • pip install -r requirements.txt (requests, PyYAML)
  • Network access to each *arr, and to GitHub once (the TRaSH Guides tarball is cached under ~/.cache/recyclarr-config-generator/ and refreshed daily)

Only Sonarr and Radarr are supported. recyclarr does not manage Prowlarr, Lidarr, Readarr or Bazarr, so those stacks have no config to generate.

Terminal window
cd utils/recyclarr-config-generator
pip install -r requirements.txt
cp instances.example.yml instances.yml # then edit: one entry per *arr
python generate_recyclarr_config.py # writes recyclarr.yml + secrets.yml

Preview without writing anything:

Terminal window
python generate_recyclarr_config.py --stdout

Each *arr’s key is under Settings → General → API Key.

Keys should not live in instances.yml. Leave api_key out and the generator reads an environment variable — api_key_env if set, otherwise <KEY>_API_KEY derived from the instance key. That fits the repo’s BWS convention:

Terminal window
bws run --access-token "$BWS_ACCESS_TOKEN" -- python generate_recyclarr_config.py

--api-key-mode controls how the key is referenced in the output:

ModeOutputNotes
secret (default)api_key: !secret sonarr_...also writes secrets.yml (mode 600)
envapi_key: !env_var SONARR_..recyclarr reads it from its own environment
inlineapi_key: "abc123..."plain text in the config — avoid committing

instances.yml, secrets.yml, recyclarr.yml and configs/ are all gitignored here.

FlagEffect
--splitone file per instance in --output dir, for recyclarr’s configs
--reset-unmatched-scoresadd reset_unmatched_scores.enabled to every profile
--include-zero-scoresalso emit custom formats currently scored 0
--no-modernizekeep retired formats as comments instead of migrating them
--no-quality-definitionskip the quality_definition block
--no-media-namingskip the media_naming block
--insecureskip TLS verification (internal Step CA certs)
--refresh-guidesforce a re-download of the TRaSH Guides
--guides-tarball PATHuse a local Guides tarball; no network needed

Per-instance, verify_ssl: false does the same as --insecure for one entry.

From the APIInto the config
qualityprofilequality_profiles — upgrade/cutoff, min scores, enabled qualities and groups (top-first)
qualityprofilecustom_formatstrash_ids grouped by identical per-profile score assignments
qualitydefinitionquality_definition — closest guide size set, plus per-quality overrides where the instance differs
config/namingmedia_naming — the guide key whose format string matches exactly

Every emitted trash_id carries the custom format’s name as a trailing comment, matching the convention in the recyclarr docs.

Custom formats you invented yourself are skipped. recyclarr only syncs formats that exist in the TRaSH Guides, so anything with no counterpart is listed as a comment at the end of that instance’s block and stays hand-managed in the UI. The same applies to naming formats you customised — the guide key cannot be inferred, so the raw format is left as a comment.

Profiles are emitted with the qualities that are currently enabled, highest-first. Anything not listed gets disabled by recyclarr on sync, which reproduces the profile as it stands.

Instances keep whatever name a format was imported under, while the guide renames things over time, so matching runs in three stages and stops at the first hit:

  1. Exact name, case- and punctuation-insensitive — DTS-X finds the guide’s DTS X.
  2. Identical specifications — the matching rules themselves fingerprint the format, so it is found however far the name has drifted. This is what recognises DV (WEBDL) as the guide’s DV (w/o HDR fallback).
  3. Normalized name — a trailing parenthetical is dropped and v2 reads as 2, which recovers Anime BD Tier 01 (Top SeaDex Muxers)Anime BD Tier 01 and Repack v2Repack2.

Stage 3 alone is not trustworthy: the guide retires names that unrelated formats later sit close to. So a stage-3 hit is only accepted when both formats are built from the same kinds of rules. HDR (undefined) matches release groups while the guide’s HDR matches title tags — near-identical names, different formats — so that one is rejected and reported rather than silently mis-scored.

Anything matched by stage 2 or 3 is printed as it happens, so a rename is never applied without telling you.

TRaSH replaced the per-flavour HDR formats (DV, DV HDR10, DV HLG, DV SDR, HDR10, HDR10+, PQ, HDR (undefined)) with a single HDR format that matches any HDR release, plus additive boost formats for the flavours worth paying extra for.

Rather than emitting those as dead comments, the generator rewrites them into the current model. A boost is scored at the difference between the old flavour’s score and the score the profile gives plain HDR, so the totals a profile was tuned around survive the migration:

DV, DV HDR10, DV HDR10+, DV HLG, DV SDR at 1500 -> HDR 500 + DV Boost 1000
HDR10+ at 600 -> HDR 500 + HDR10+ Boost 100
HDR10, PQ, HDR (undefined) at 500 -> dropped, already covered by HDR 500

An existing HDR score always wins as the base, since that is what the profile already asks for. If a flavour scored no higher than HDR did, no boost applies and it is simply dropped. Every substitution is printed while it runs and recorded as a comment block in the config, so the change is auditable after the fact. --no-modernize turns the whole pass off and reverts to listing them as unmatched.

Formats with no clean equivalent are never guessed at. Sonarr’s retired UHD Streaming Cut looks like the current UHD Streaming Boost, but it covers a different set of services (AMZN/HMAX/Stan vs DSNP/HMAX/NF) and the guide scores it positively where the old one was usually negative — so it is reported for you to decide, not migrated.

Always preview before the first sync — it shows exactly what recyclarr would change:

Terminal window
recyclarr sync --preview

Expect small diffs on the first run: scores the guide has but your instance never set, and qualities whose sizes were left at *arr defaults. Review them, then sync for real.