A Jellyfin plugin that surfaces scheduled-deletion media ("leaving soon") as
symlink-backed libraries, e.g. Movies - Leaving Soon and Shows - Leaving Soon.
The plugin uses a provider-pull model: it polls one or more configured provider apps for media that is scheduled for deletion, then manages the symlinks, the Jellyfin virtual folders, and the library refreshes itself. No push integration is needed on the provider side.
| Provider | Endpoint polled | Notes |
|---|---|---|
| Maintainerr | GET /api/collections/overlay-data |
Maintainerr's released overlay/helper-integration endpoint; the plugin filters for active, deletion-scheduling collections (has a deletion window and a disk-freeing action: DELETE, UNMONITOR_DELETE_ALL, UNMONITOR_DELETE_EXISTING, DELETE_SHOW_IF_EMPTY) |
| OxiCleanarr | GET /api/media/leaving-soon |
Normalized leaving-soon contract |
Both are normalized by the plugin into the same internal item contract:
The plugin mirrors whatever the providers list. It does not interpret deletion timing itself: an item stays in the leaving-soon libraries as long as its provider still returns it, and is removed automatically on the next sync once the provider stops (e.g. after the scheduled deletion is carried out).
The plugin resolves each item's on-disk path from Jellyfin's own metadata
(ILibraryManager.GetItemById), so providers do not need to expose file paths.
- On the configured interval (
SyncIntervalMinutes, default 15) the plugin polls every enabled provider. - Items are deduped by
mediaServerId; a provider that fails contributes nothing and is logged (it never aborts the sync). - Movies and shows are reconciled separately:
- ensure the host directory exists under
BasePath, - ensure the Jellyfin virtual folder exists (create or add path),
- create symlinks for newly-scheduled items,
- remove stale symlinks no longer scheduled,
- trigger a library refresh,
- regenerate the library cover so it reflects the current leaving-soon set.
- ensure the host directory exists under
HideWhenEmpty: when a library has zero items it is disabled (hidden from all user views) instead of deleted — its metadata rows and symlinks are kept intact, so re-enabling on the next sync with items is instant with zero rescan. When the library comes back from the empty period its cover is force-regenerated so the previous leaving set's collage does not linger.
Uninstalling the plugin cleans up after itself:
- removes every symlink it created under
<BasePath>/moviesand<BasePath>/tv, and deletes those subdirectories once empty (never recursive — real content or a real library at the base path always survives), - disables and removes the leaving-soon libraries, purging their orphaned metadata rows.
Cleanup is guarded: a library is only removed when every one of its locations points under the plugin's own base path, so a real (admin-created) library that happens to share a configured name is never touched.
Edit config.xml in the plugin's config directory and restart Jellyfin.
| Setting | Default | Description |
|---|---|---|
BasePath |
/config/leaving-soon |
Host directory for symlinks; movies/ and tv/ subdirectories. Defaults to the Jellyfin config volume so the container user can always write it (no chown needed) |
MoviesLibraryName |
Movies - Leaving Soon |
Jellyfin library name for movies |
TvLibraryName |
Shows - Leaving Soon |
Jellyfin library name for TV |
HideWhenEmpty |
true |
Hide empty leaving-soon libraries from the sidebar instead of showing them empty |
SyncIntervalMinutes |
15 |
Poll interval |
ForceEmptyAfterFailureCount |
3 |
Consecutive provider failures tolerated before an empty result is trusted |
Providers |
[] |
List of provider configs (Type, Name, Enabled, Url, ApiKey, IncludeCollections) |
Example provider configs:
<Providers>
<ProviderConfig>
<Type>maintainerr</Type>
<Name>maintainerr</Name>
<Enabled>true</Enabled>
<Url>http://maintainerr:6246</Url>
<ApiKey></ApiKey>
<IncludeCollections></IncludeCollections>
</ProviderConfig>
<ProviderConfig>
<Type>oxicleanarr</Type>
<Name>oxicleanarr</Name>
<Enabled>true</Enabled>
<Url>http://oxicleanarr:9709</Url>
<ApiKey></ApiKey>
<IncludeCollections></IncludeCollections>
</ProviderConfig>
</Providers>Note on auth:
- Maintainerr's collections API currently has no enforced auth.
- OxiCleanarr's
/api/media/leaving-soonsits behind JWT auth; the plugin works withadmin.disable_auth: true, or you may add API-key support later and send it viaApiKey(sent as a Bearer token).
Note on Maintainerr collections:
- The plugin polls
/api/collections/overlay-dataand surfaces members of every active collection that schedules deletion of its files (has a deletion window and a disk-freeing action: DELETE, UNMONITOR_DELETE_ALL, UNMONITOR_DELETE_EXISTING or DELETE_SHOW_IF_EMPTY). Collections that only unmonitor or change quality leave the files in place, so their members are not "leaving soon" and are not mirrored. - Use Maintainerr's per-collection Keep in Maintainerr only option (Settings -> Collections) on your leaving-soon collections: Maintainerr then creates no Jellyfin BoxSet for them, so the leaving-soon library is the single place those items surface.
GET /api/leaving-soon/status- plugin status and configuration summary (admin auth)GET /api/leaving-soon/debug- diagnostic snapshot of the current sync inputs: configured providers and per-item path resolution (admin auth). Helps trace why a sync reconciled to an empty library.POST /api/leaving-soon/sync- trigger an immediate sync (admin auth)POST /api/leaving-soon/test-connection- test a provider's URL/auth against its leaving-soon endpoint (admin auth). Accepts unsaved provider settings (Type,Name,Url,ApiKey,IncludeCollections); the config page's per-provider Test button uses it.
The default BasePath is /config/leaving-soon (inside the Jellyfin config volume),
so the container user can always create the symlink directories — no permission setup
needed. If you prefer the leaving-soon libraries to live on the media mount instead,
set BasePath to e.g. /data/leaving-soon and pre-create it with the container's
UID/GID:
mkdir -p /data/leaving-soon/movies /data/leaving-soon/tv
chown -R 1000:1000 /data/leaving-soon./build.sh 1.0.0The plugin DLL is produced under build/; a release zip and md5 are generated at
the repo root.
{ "items": [ { "mediaServerId": "jellyfin-item-guid", "type": "movie" | "show", "title": "The Matrix" } ] }