Rules¶
Rules determine which media becomes a reclaim candidate or receives an automated protection. A rule has:
- a target scope
- one or more conditions
- nested
ANDorORgroups - an outcome: cleanup candidate or automated protection
- candidate action settings when the outcome is cleanup
Use rule preview before saving or running a cleanup scan. Preview shows the items that match and the actual values used for each matching condition.
Rule Outcomes¶
| Outcome | Behavior |
|---|---|
| Cleanup candidate | Matching media enters the normal review and deletion workflow |
| Automated protection | Matching media is protected from cleanup without creating a candidate |
Automated protections are reconciled on each cleanup scan. They are added when a rule starts matching and removed when that same rule no longer matches, is disabled, or is deleted. Manual protections are not changed by this process. Library Scope applies to both cleanup candidate and automated protection outcomes.
Each protection rule creates its own managed protection entry for a matching item. These entries are read-only on the Protected page because changing the rule is the source of truth. If a protection rule and a candidate rule match the same item, protection always takes precedence.
Cleanup-candidate rules can optionally enable automatic deletion. Rules that do not enable it still create candidates and can populate Leaving Soon collections, but the scheduled delete task skips them.
Cleanup-candidate rules can also enable Move Instead of Delete. Delete actions for candidates matched by those rules move media to the configured destination folder instead of deleting the file. Destination folders are configured in General Settings. If multiple matched cleanup rules disagree, move wins.
When automatic deletion is enabled for a rule, the rule can also override the
review period. Leave the override empty to inherit the default movie or TV
delay. Values from 0 through 3650 days are supported, with 0 meaning
immediately eligible. When multiple auto-delete-enabled cleanup rules match the
same item, Reclaimerr uses the longest applicable delay so a shorter rule
cannot reduce another rule's review period.
Target Scopes¶
Fields are limited to scopes where Reclaimerr has meaningful data.
| Scope | Evaluated item | Examples |
|---|---|---|
| Movie version | One physical movie file | Container, bitrate, codec, subtitles |
| Series | The complete local series | Status, year, season counts |
| Season | One local season | Season number, episode count, inherited series metadata |
| Episode | One local episode | Episode number, air date, inherited series metadata |
A movie-version rule evaluates each physical version independently. If a movie has multiple files, more than one version can become a candidate.
Condition Groups¶
An AND group matches only when every child condition matches. An OR group
matches when at least one child condition or child group matches.
For example, this identifies old, unwatched movies that are either large or have multiple versions:
21474836480 is 20 GiB expressed in bytes, which is the unit expected by the
size field.
Operators¶
List Operators¶
| Internal operator | UI label | Meaning |
|---|---|---|
contains_any |
matches any | At least one supplied value matches |
not_contains_any |
matches none | None of the supplied values match |
contains_all |
matches all | Every supplied value matches |
not_contains_all |
does not match all | At least one supplied value does not match |
Text and list comparisons are case-insensitive unless a field documents additional normalization.
Substring Operators (Arr tags)¶
The Arr tags field matches whole tag names with the list operators above. It
also supports substring matching, which matches a tag by a fragment of its
name. Each operator takes comma-separated terms with the same any/none
behavior as matches any and matches none.
| Internal operator | UI label | Meaning |
|---|---|---|
contains_substring |
contains | Some tag contains one of the terms |
not_contains_substring |
does not contain | No tag contains any of the terms |
For example, contains chart matches a tag such as weekly-chart-2024, and
contains chart, -best matches a tag containing either fragment. To require
several fragments at once, combine contains conditions with an AND group. A
blank term matches nothing.
Regex Operators (Arr tags)¶
The Arr tags field also matches tags with regular expressions. Each operator
takes one or more patterns; a pattern is applied with re.search and is
case-insensitive, so anchor with ^ and $ to match a whole tag. Patterns
within one operator combine with the same any/none behavior as the list
operators.
| Internal operator | UI label | Meaning |
|---|---|---|
matches_any_regex |
matches regex | Some tag matches one of the patterns |
not_matches_any_regex |
does not match regex | No tag matches any of the patterns |
matches_any_regex is also available on the path fields. A condition with no
valid pattern matches nothing, so not_matches_any_regex never matches an item
on an empty or invalid pattern.
For example, given tags that pair a base name with a -stale variant (such as
tag-1 and tag-1-stale), an AND group of matches_any_regex tag-.*-stale$
and not_matches_any_regex ^tag-.*(?<!-stale)$ selects items that carry a
-stale variant but no active base tag. An item still active under any tag keeps
a value matching the second pattern, so it is excluded.
Missing Values¶
exists matches populated metadata. does not exist matches missing or empty
metadata.
Missing metadata does not automatically prove a negative condition. Language
and origin-country rules therefore fail closed: if the item's value is unknown,
matches none and does not match all do not match it. Use a separate does
not exist condition when you specifically want to identify missing metadata.
Field Reference¶
The rule editor only displays fields valid for the selected scope. The following fields have behavior or units that are important when constructing a rule.
General Media Fields¶
| Field | Scope | Value |
|---|---|---|
| Title | All scopes | Movie title or parent series title |
| Year | All scopes | Movie year or the parent series year |
| Size | All scopes | Bytes for the evaluated file, series, season, or episode |
| Duration | Movie version | Media-server duration in milliseconds |
| Container | Movie version | File container such as mkv or mp4 |
| Path / Filename | All scopes | Local media-server path information |
| Days since added | All scopes | Age of the existing media-server added date |
| Days since latest Arr file added | All scopes | Age of Radarr/Sonarr's latest file-import date |
| Media server user rating | All scopes | User rating reported by Plex, Jellyfin, or Emby |
Size and disk-free conditions use an amount and unit selector in the editor. Rules continue to store integer byte values, using 1024-based KB, MB, GB, and TB conversions for compatibility with existing rules.
Arr file-added dates are populated during Radarr and Sonarr syncs. They remain empty when an item cannot be matched or an Arr service is not configured; the existing media-server added date is not replaced or backfilled.
Media-server user ratings are stored during media sync when the provider
reports a user-specific rating for the item. Missing ratings do not match
numeric comparisons; use does not exist to find unrated media.
Arr Identifiers¶
| Field | Scope | Value |
|---|---|---|
| Radarr movie IDs | Movie version | One or more Radarr IDs for the movie |
| Sonarr series IDs | Series, season, episode | One or more Sonarr IDs for the series |
Reclaimerr can map one local item to multiple Radarr or Sonarr instances, so
Arr ID fields are multi-value text fields. Use matches any for a precise
rule against one known Arr ID, or matches all when an item must be present in
several configured Arr instances.
Favorites and Watchlists¶
Favorite/watchlist rule fields use the same snapshot that powers favorites protection. Jellyfin and Emby favorites are included, and Plex watchlists are included for linked Plex users.
| Field | Scope | Value |
|---|---|---|
| Favorited or watchlisted | All scopes | Boolean, true when any known user has the item |
| Favorite/watchlist users | All scopes | Usernames from the favorite/watchlist snapshot |
| Favorite/watchlist user count | All scopes | Number of unique users with the item favorited |
For season and episode rules, favorite/watchlist state is inherited from the parent series TMDB ID.
Retention Position Fields¶
| Field | Scope | Value |
|---|---|---|
| Season position by air date | Season | Newest local regular season in the series is 1 |
| Episode position by air date | Episode | Newest local regular episode in the series is 1 |
Season 0 specials are excluded. Items without an air date or Arr file-added date have unknown rank and do not match numeric comparisons. These fields are intended for rules such as "keep the newest 2 seasons" or "keep the newest 10 episodes" by matching positions greater than the number you want to keep.
Collection Sibling Activity¶
Movie-version rules can check whether another movie in the same media-server collection has been watched recently.
| Field | Scope | Value |
|---|---|---|
| Collection sibling last watched | Movie version | Latest watch timestamp from another movie sibling |
| Days since collection sibling watched | Movie version | Whole days since that sibling watch timestamp |
The current movie is excluded from the sibling calculation. Reclaimerr-managed Leaving Soon collections are ignored so temporary cleanup collections do not affect rules.
TMDB Metadata¶
| Field | Scope | Value |
|---|---|---|
| Original language | All scopes | Canonical ISO 639-3 language code |
| Origin country | All scopes | Case-insensitive country code such as US or JP |
| Runtime | Movie version | TMDB movie runtime in minutes |
| Genres | All scopes | TMDB genre names |
| Rating / Votes / Popularity | All scopes | TMDB rating uses the raw 0-10 vote_average scale; votes and popularity use current stored TMDB metadata |
| Release date | Movie version | Movie release date |
| First / last air date | Series, season, episode | Dates inherited from the parent series |
Original-language values are normalized before comparison. For example, en,
eng, and English all compare as eng. The picker displays languages found
in the local database, but manual entry remains available.
Origin-country comparisons are case-insensitive. The country picker displays codes currently found in local TMDB metadata.
TMDB rating comparisons use the raw vote_average value from TMDB on a 0-10
scale. That is different from percentage-style ratings elsewhere in the app.
External Ratings¶
External rating fields are available to all scopes. Movie-version rules use the parent movie's cached values. Series, season, and episode rules use the parent series values.
| Field | Source | Value |
|---|---|---|
| Rotten Tomatoes Tomatometer | MDBList, fallback OMDb | Percent, 0-100 |
| Rotten Tomatoes Tomatometer votes | MDBList | Count |
| Rotten Tomatoes Popcornmeter | MDBList | Percent, 0-100 |
| Rotten Tomatoes Popcornmeter votes | MDBList | Count |
| Metacritic metascore | MDBList, fallback OMDb | Score, 0-100 |
| Metacritic critic count | MDBList | Count |
| Metacritic user score | MDBList | Score, 0-100 |
| Metacritic user votes | MDBList | Count |
| Trakt rating | MDBList | Percent, 0-100 |
| Trakt votes | MDBList | Count |
| Letterboxd score | MDBList | Percent, 0-100 |
| Letterboxd votes | MDBList | Count |
MDBList is preferred because it provides structured ratings[] entries for
Rotten Tomatoes, Metacritic, Trakt, and Letterboxd plus vote counts. OMDb is
used as a fallback for Tomatometer and Metacritic when an IMDb ID is available.
Direct Rotten Tomatoes and Metacritic scraping is intentionally not used.
Ratings are refreshed by the provider-specific Refresh MDBList Ratings and
Refresh OMDb Ratings tasks. They keep independent schedules and caches.
MDBList values remain authoritative, while OMDb fills missing Tomatometer and
Metacritic values. If a provider has not been configured, the media has no
matching provider ID, or the provider does not return a rating, that field is
missing. Numeric comparisons do not match missing ratings; use does not exist
when you specifically want to find media without a cached rating.
The Metadata Providers settings page shows per-refresh request usage and cached movie/series coverage for MDBList and OMDb. Provider rate-limit headers are tracked internally only to stop refresh work when a provider reports that its quota is exhausted.
MDBList requests are paced during external-rating refreshes. Standard mode uses a 1 second minimum delay between MDBList requests; MDBList supporter mode uses a 0.2 second delay.
Movie-Version Metadata¶
| Field | Unit or value |
|---|---|
| Video bitrate | Kilobits per second (kbps) |
| Audio bitrate | Kilobits per second (kbps) |
| Video bit depth | Bits, commonly 8, 10, or 12 |
| Subtitle track count | Number of subtitle streams |
| Has forced subtitles | Boolean |
| Movie version count | Number of physical versions stored for the movie |
Plex bitrate values are already stored as kbps. Jellyfin and Emby commonly
report bits per second, so Reclaimerr converts those values to kbps during
rule evaluation. This provides the same rule units across media servers without
rewriting stored metadata.
Movie version count is inherited by every version of the movie. A condition
such as Movie version count > 1 therefore selects every version of each
multi-version movie. Combine it with a distinguishing condition such as
quality, codec, resolution, size, bitrate, container, or path when you intend
to remove only one version.
Series Season Counts¶
| Field | Meaning |
|---|---|
| TMDB season count | Number of seasons reported by TMDB |
| Library season count | Number of locally stored seasons, excluding season 0 |
Season 0 is normally used for specials and is intentionally excluded from the library season count. Both count fields are available to series, season, and episode rules and are inherited from the parent series.
These values may differ when the local library contains only part of a series, TMDB metadata has changed, or specials are present.
Seerr Request Dates¶
Seerr request dates are available to movie-version, series, season, and episode rules:
| Field | Meaning |
|---|---|
| Seerr latest active request | Newest pending or approved request timestamp |
| Days since latest active Seerr request | Whole days since that request |
Declined and failed requests are excluded. Series rules use the latest request for the series. Season and episode rules use the request for their specific season, so requesting a later season does not reset the request age of an earlier season. Older Seerr responses that do not identify requested seasons fall back to the series request date. If Seerr is unavailable, these values are unknown and cannot create candidates.
Seerr Requester Watch State¶
Seerr requester has watched compares each requester's playback with the time
they requested the movie or TV season. Playback at or before the request does
not count. The meaning depends on the rule target:
| Scope | is true means |
|---|---|
| Movie version | A requester watched the movie after requesting it |
| Episode | A requester watched that episode after requesting its season |
| Season | One requester watched every local episode in that requested season |
| Series | One requester watched every regular local episode in the seasons they requested |
Season 0 specials are excluded from series completion. Progress from different requesters is never combined to complete a season or series. Seasons that were not requested do not inherit another season's requested or watched state.
Reclaimerr first matches Seerr users automatically using usernames, display names, and email addresses from Seerr's user directory. Explicit requester watch-user mappings are additive fallbacks for users whose identities differ between Seerr and the playback provider. Username comparisons are case-insensitive. Tautulli identities are treated as Plex identities when applying provider-scoped mappings.
Requester watch state combines completed per-user playback snapshots from
Plex, Jellyfin, and Emby with Tautulli events whose provider-native watched
status is complete. Each provider's configured watched threshold remains the
source of truth. Jellyfin and Emby Playback Reporting events describe activity
but do not expose a reliable completion signal, so they do not independently
satisfy this field. They remain available to the general playback.* fields.
When the same completed play is available from multiple sources, Reclaimerr
keeps the latest qualifying timestamp.
After configuring Seerr or changing identity mappings, run Sync Media before
previewing the rule. Plex can provide current completed-watch state directly;
durable completed Plex history requires Tautulli.
Sonarr Rule Data¶
Season fully watched and Season watched (%) use Sonarr's complete known
episode inventory as their denominator. Episodes Sonarr knows about still count
when they are unaired or do not have files, so six watched episodes out of seven
known episodes is 85.71%, not complete. Run Sync Media after upgrading or
after Sonarr discovers new episodes.
If a season has no successfully synchronized Sonarr episode inventory, its watch completion is unknown. Boolean and numeric completion conditions do not match that season; Reclaimerr does not fall back to treating the currently downloaded episodes as the complete season. Preview warnings count only seasons where missing inventory affects the current rule after its other conditions are applied, and show up to five example titles to aid troubleshooting.
Sonarr series status exposes Sonarr's canonical series status independently
from the TMDB-backed Series status field. It is available to series, season,
and episode rules with the values continuing, ended, upcoming, and
deleted.
Status is loaded from Sonarr's bulk series response and does not require episode requests. When a series maps to multiple Sonarr instances, every mapped and reachable instance must report the same status. Missing or conflicting values are unknown and fail closed.
The latest-season fields are available only to whole-series rules:
| Field | Meaning |
|---|---|
| Latest season has unaired episodes | The latest regular Sonarr season has an episode airing later |
| Latest season has finale | The latest regular season has a season or series finale tag |
Reclaimerr ignores season 0 and checks only the highest-numbered regular season. This keeps scans efficient while covering upcoming seasons and split cours. Episode monitoring status is not considered.
Sonarr's series statistics may provide a future nextAiring value. Reclaimerr
uses that value to prove that an unaired episode exists without requesting the
season's episodes. A missing nextAiring value cannot prove that no future
episode exists, so Reclaimerr requests only the latest season's episodes when
the rule result still depends on Sonarr data.
Episode-state data is loaded only when an enabled rule uses one of these fields. Requests are cached for the current preview or cleanup scan and are limited to eight concurrent episode requests per Sonarr instance.
Unavailable, empty, or malformed Sonarr data is treated as unknown. Unknown
values match neither is true, is false, exists, nor does not exist.
They cannot create a cleanup candidate. Existing automated protections are
preserved for the affected rule and series until Sonarr can be evaluated
again.
When a series is mapped to multiple Sonarr instances, true wins if any
instance proves it. false is returned only when every mapped instance
successfully reports false. Otherwise the value remains unknown.
Typical protection rules are:
The finale field depends on Sonarr's metadata and may remain false while a season is incomplete or its finale metadata has not been updated. Combine it with status, age, watch-history, or library conditions and inspect the preview before enabling the rule.
Playback Activity and History¶
Playback fields are available to movie-version, series, season, and episode rules. Reclaimerr stores current completed watch state directly from Jellyfin and Emby, then supplements it with compact events imported from the Jellyfin/Emby Playback Reporting plugin and Tautulli:
| Field | Meaning |
|---|---|
| Playback activity | Native completed watch state or a qualifying event |
| Playback plays | Highest native or imported play count |
| Playback duration | Total qualifying imported playback minutes |
| Longest playback | Longest qualifying imported playback in minutes |
| Playback user count | Current native watched users, or imported users when no native state exists |
| Playback users | Current native watched users, or imported users when no native state exists |
| Last playback activity | Most recent native or imported timestamp |
| Days since playback activity | Whole days since the most recent timestamp |
Movie events shorter than 15 seconds and episode events shorter than 7 seconds are ignored. These thresholds prevent brief scrubs from counting as activity.
Events are retained locally until their source service configuration is deleted. They are mapped by exact media-server IDs and stable TMDB, season-number, and episode-number identities, so imported history can survive provider retention cleanup and media deletion/re-addition. Title-only matching is never used.
The existing watch.* fields continue to describe the current library copy.
Native Jellyfin/Emby playback is current completed state and is refreshed by
the Refresh Playback Data task every 15 minutes by default as well as by
Sync Media. Imported plugin/Tautulli events are durable history and may include
activity from before the current copy was added. For Jellyfin and Emby, native
state is authoritative for Playback users and Playback user count: old
Playback Reporting events do not keep a user matched after the media server no
longer marks that user as watched. For a movie version or episode this is the
exact item; for a season or series it means the user has completed at least one
available local episode. This is not a per-user full-season/series completion
check.
Playback activity is either true or false when an applicable native snapshot
or imported-history provider can observe the media target. Targets outside that
coverage are unknown and match neither value. Marking an item watched without
playing it is captured by Jellyfin/Emby's native current state after the next
playback data refresh, but it does not create an imported playback event.
Playback data is loaded only when an enabled rule uses a playback.* field.
Native snapshots are read from the database. A preview refreshes them when they
are more than 15 minutes old, while cleanup scans require a current snapshot.
Tautulli history is fetched in one ungrouped paginated pass. Playback Reporting
and Tautulli imports use an overlap window and event keys to avoid duplicate
events during incremental refreshes.
Playback-user rules match usernames case-insensitively and can require any, none, or all selected users. Jellyfin and Emby resolve names from their native user APIs; Tautulli resolves only the Plex history it supplies. If a native Jellyfin/Emby snapshot is unavailable, user conditions are unknown rather than falling back to stale imported events. If any user on an item cannot be resolved, username conditions remain unavailable for that item while the other playback metrics remain usable.
If a native watched item has no usable last-played timestamp, activity and count remain available while the last-activity fields stay unknown.
Plex playback fields, including playback-user rules, require Tautulli. Jellyfin/Emby activity, count, users, and latest-watch fields work without the Playback Reporting plugin after a playback data refresh; duration fields still require imported plugin history. Reclaimerr does not currently import playback events directly from Plex.
If no applicable source is configured, a native snapshot refresh fails, an import request fails, or an item cannot be observed through an available source, playback values are unknown. Unknown values cannot create cleanup candidates. Existing automated protections are preserved until the affected playback rule can be evaluated again.
Immediately before automatic deletion, eligible candidates whose matched rules use playback fields are checked again against freshly refreshed data. An item that was watched after becoming a candidate, or whose playback state cannot be observed safely, is not authorized for deletion by that playback rule.
Validation and Editing¶
- Operator choices are limited to operators supported by the selected field.
- Field choices are limited to the selected target scope.
- Changing a field resets an incompatible operator to the field's default.
- Existing saved rules are not rewritten until they are edited and saved.
- Backend validation rejects unsupported field, operator, or scope combinations.
- Rule preview uses the same evaluation logic as cleanup candidate scans.
Recommended Workflow¶
- Choose whether the rule creates cleanup candidates or automated protections.
- Select the narrowest target scope that represents the intended item.
- Add positive conditions that identify the media.
- Add quality, age, watch-history, or metadata conditions to reduce broad matches.
- Preview the rule and inspect the displayed actual values.
- Save the rule only after the preview contains the intended files.
- Run a cleanup scan to reconcile candidates and automated protections.