A compact, self-hosted release dashboard for a Yamtrack + Sonarr + Radarr + Jellyfin stack. It recreates the useful density of the MyEpisodes private show list while adding movies, acquisition state and direct links to each service.
- Shows Yamtrack, Sonarr and Radarr releases in one chronological list.
- Defaults to the previous 30 days and next 90 days.
- Hides watched entries by default, with a filter to include them.
- Gets episode watched state in batches of one Yamtrack API request per season.
- Matches movies by TMDB ID.
- Matches episodes by TMDB series ID + season number + episode number.
- Shows Sonarr/Radarr file state as Acquired.
- Optionally checks whether the item exists in Jellyfin.
- Can mark a movie watched in Yamtrack.
- Links directly to Yamtrack, Sonarr, Radarr and Jellyfin.
The episode checkbox is disabled in this version. The current Yamtrack API
branch has read endpoints for episode state, but its generic provider-backed
POST /api/v1/media/episode/ path does not create the required parent season or
correctly use episode_number. See
docs/Yamtrack-episode-write-gap.md.
Movie writes use the supported endpoint:
POST /api/v1/media/movie/with status: 3 and the current watch time.
-
Copy the environment file:
cp .env.example .env
-
Add the API keys.
-
Edit
docker-compose.example.ymlso the service URLs and external Docker network match your installation. Set eachPublicBaseUrlto the URL your browser can reach if the API uses internal Docker hostnames. -
Start it:
docker compose -f docker-compose.example.yml up -d --build
The example binds to 127.0.0.1:8095. Publish it through Caddy or access it over
Tailscale rather than exposing it directly to the internet. The dashboard has no
login system of its own; all upstream credentials remain server-side.
The project targets .NET 10 and has no third-party NuGet dependencies:
dotnet run --project src/Arrivals/Arrivals.csprojUse user secrets for local development:
dotnet user-secrets set Yamtrack:BaseUrl "http://yamtrack.lan/" \
--project src/Arrivals/Arrivals.csproj
dotnet user-secrets set Yamtrack:ApiKey "..." \
--project src/Arrivals/Arrivals.csprojEnvironment variables use the normal ASP.NET Core double-underscore notation,
for example Yamtrack__ApiKey.
| Setting | Purpose |
|---|---|
Dashboard:PastDays |
Default lookback, 30 |
Dashboard:FutureDays |
Default lookahead, 90 |
Dashboard:CacheMinutes |
In-memory API cache lifetime |
Dashboard:TimeZoneId |
Display and date-filter timezone |
Dashboard:MovieDatePreference |
DigitalThenCinema, CinemaThenDigital, or Earliest |
Dashboard:IncludeUnmonitored |
Include unmonitored Sonarr/Radarr entries |
Dashboard:EnableMovieMarkWatched |
Enables the movie write button |
Yamtrack:BaseUrl / ApiKey |
Required; target the :api image |
*:PublicBaseUrl |
Optional browser-facing URL when the API URL uses an internal Docker hostname |
Sonarr:BaseUrl / ApiKey |
Optional but needed for TV acquisition state |
Radarr:BaseUrl / ApiKey |
Optional but needed for movie acquisition state |
Jellyfin:Enabled |
Enables Jellyfin lookup |
Jellyfin:BaseUrl / ApiKey / UserId |
Required when Jellyfin lookup is enabled |
Yamtrack calendar ─┐
Sonarr calendar ├─> canonical movie/episode keys ─> one release list
Radarr calendar ┘
movie key = movie:tmdb:{tmdbId}
episode key = episode:tmdb:{seriesTmdbId}:S{season}:E{episode}
- Watched comes from Yamtrack.
- Acquired comes from Sonarr/Radarr
hasFile/file IDs. - In Jellyfin is a separate optional check.
- Release rows are the union of all configured calendars, so an item can appear even if only Sonarr or Radarr currently knows about it.
For known numbering disagreements, do not add fuzzy matching silently. Add an explicit mapping layer later so MythBusters-style cases remain inspectable.
curl -H "X-API-Key: $YAMTRACK_API_KEY" \
http://yamtrack.lan/api/v1/info/
curl -H "X-API-Key: $YAMTRACK_API_KEY" \
"http://yamtrack.lan/api/v1/calendar/?start_date=2026-07-01&end_date=2026-08-31&limit=5"Swagger should remain available from the API image at /api/docs/.
- Run against the cloned Yamtrack data and inspect unmatched rows.
- Enable Jellyfin only after the core view is stable; it adds per-show library queries and is not required for the acquired indicator.
- Add a small explicit override store for rare Sonarr/TMDB numbering conflicts.
- Add the Yamtrack episode history POST endpoint, then enable episode writes.
- Add authentication in front of Arrivals if it is reachable beyond the LAN.