Release history

What's new.

Every release of LetterboxdSync, newest first. Each entry covers the user-facing changes. Backwards through the project history, all the way to v1.0.0.

40 releases
1.18.5 latest
June 29, 2026 shipped
v1.18.5 Latest

No functional changes to syncing. This release adds an anonymous, privacy-preserving install counter so the developer can see roughly how many Jellyfin servers run the plugin. No personal data is collected: your IP address is never stored, and the anonymous weekly fingerprint used to avoid double-counting cannot be traced back to you or linked across weeks.

Fixes a sync failure introduced when Letterboxd changed their website. Films stopped logging to your diary because the plugin could no longer read each film's identifier from its Letterboxd page. The plugin now reads the new page format, so watched films sync again.

More precise error reporting in telemetry

If you have opted in to the anonymous telemetry, plugin errors are now sorted into more specific categories instead of a single generic "other" bucket. Rate-limiting, Letterboxd server outages, failed writes back to Letterboxd, and page-parsing problems are each labelled distinctly. This is purely a labelling improvement: no behaviour changes, and nothing new about you or your library is collected.

Improvements
  • Anonymous telemetry now distinguishes four previously-uncategorised error types: rate-limiting (being throttled by Letterboxd), server errors (Letterboxd returning a 5xx), write failures (a watch or review that could not be logged after retries), and parsing errors (a Letterboxd page that no longer matches what the plugin expects). Previously these all counted as "other".
Fixes
  • Fixed the error-state recovery so that, after a successful sync, every error category is cleared. One category was previously skipped, which could leave a stale "still failing" flag set.

Jellyseerr is now called Seerr

Jellyseerr and Overseerr have merged into a single project called Seerr. The plugin now uses the new name everywhere you see it, in the settings page, your personal account page, and the documentation, so the labels match what you see in the app you are connecting to. Nothing about the integration changes: your existing Seerr URL, API key, and per-account settings are kept, and there is nothing to reconfigure.

Improvements
  • The "Jellyseerr integration" settings, the auto-request and watchlist-mirror options, and the connection-test messages now all read "Seerr" to match the renamed project. Your saved URL, API key, and account settings carry over untouched.

Internal: test analytics in CI

No functional changes. CI now uploads JUnit test results to Codecov Test Analytics so flaky tests and failures are tracked across releases. Nothing in the plugin itself changes.

Improvements
  • CI emits a JUnit test report and uploads it to Codecov Test Analytics for flaky-test detection and failure reporting. Developer-facing only; no change to plugin behaviour.

Clearer guidance when Letterboxd login fails

Letterboxd often blocks plain username/password login with a Cloudflare or reCAPTCHA challenge, and accounts with two-factor authentication can never log in that way at all. Telemetry showed this is the single most common reason a sync fails on a fresh install. This release makes raw cookies the clearly recommended way to authenticate, warns you when you save an account without them, and turns the cryptic two-factor login failure into a message that tells you exactly what to do.

Improvements
  • Raw Cookies are now presented as the recommended way to authenticate, on both the admin settings page and your personal account page, with a short explanation of why password-only login is unreliable (Cloudflare/reCAPTCHA challenges, and two-factor accounts that cannot use it at all).
  • Saving an enabled account that has a password but no raw cookies now shows a non-blocking warning, so you find out before the first sync fails rather than after. The save still goes through.
Fixes
  • Accounts with two-factor authentication enabled now fail login with a clear, actionable message ("this account has two-factor authentication enabled, add raw cookies including cf_clearance, or disable 2FA") instead of a vague generic login error. Password login genuinely cannot complete a 2FA challenge, so the plugin now says so and points you at the fix.
Upgrade notes: If your syncs have been failing with auth errors, open your Letterboxd Sync account settings and paste Raw Cookies (including cf_clearance) from a browser already signed in to Letterboxd. This is now the recommended setup, especially for accounts with two-factor authentication.

Send your logs to the developer in one click

Reporting a problem used to mean digging through Jellyfin log files and pasting the right lines into a GitHub issue. Now there is a "Send logs to developer" button on the Logs tab: it packages your recent Letterboxd Sync activity, uploads it privately, and hands you a short reference code to quote in your bug report. It is opt-in every single time you use it, shows you exactly what will be sent before anything leaves your server, and is upfront that logs, unlike the anonymous telemetry, can identify you. This release also tightens who on your server is allowed to read those logs.

New
  • Send logs to developer: open Dashboard, then Letterboxd Sync, then the Logs tab, and click "Send logs to developer". The plugin bundles the recent Letterboxd Sync log lines (the same ones already shown on that tab) and uploads them, then gives you a short reference code like LBX-7Q2F9K. Quote that code when you open a GitHub issue and the developer can pull your exact logs to diagnose the problem, no more copy-pasting walls of text.
  • See exactly what is sent, before it is sent. The confirmation step has a "Preview exactly what is sent" view that renders the real log lines and the telemetry snapshot, byte for byte what gets uploaded. You can also add a short note describing what went wrong, which is often the single most useful thing for diagnosis.
  • Honest about privacy. Unlike the anonymous weekly telemetry, logs are NOT anonymous: they can contain a Letterboxd username or film titles, and the bundle is linked to the telemetry ID for that install. The dialog says this plainly, nothing is sent until you confirm, passwords and cookies and auth tokens are never logged, and it works whether or not anonymous telemetry is turned on.
  • Your logs are not kept forever. Uploaded bundles are stored privately and automatically deleted after 90 days.
Improvements
  • Stronger log access control. The plugin log endpoint now requires administrator access. Previously any signed-in Jellyfin user on the server could read the Letterboxd Sync logs, which name every linked Letterboxd account and watched film. On shared or family servers this is now admin-only.
  • Better diagnostics when you do send logs: full multi-line error traces are now captured intact (they were previously cut into fragments), log text is cleaned of stray terminal control codes, and the bundle always records your Jellyfin version.
Upgrade notes: Nothing changes unless you choose to use the new button. To send logs, go to Dashboard, then Letterboxd Sync, then the Logs tab, and click "Send logs to developer" (admin only). Anonymous telemetry, if you enabled it in 1.16.0, is unaffected.

Anonymous opt-in telemetry

Entirely opt-in and off by default. If you enable it, one small anonymous ping a week tells the project which features are actually used, so roadmap decisions stop being guesses. Nothing else in the plugin changes.

New
  • Anonymous usage telemetry, opt-in via a one-time dashboard banner or the Settings checkbox. The payload is minimal and bucketed: version numbers, which features are enabled, and rough size buckets. Never film titles, usernames, IPs, or exact numbers. A "Preview exact JSON" button in Settings shows precisely what would be sent, and the full payload is documented in the README.
  • Identified only by a random instance ID generated when you opt in, with a one-click Regenerate button that unlinks future pings. The preview doubles as a diagnostic bundle for bug reports, with an honest warning about what pasting it publicly reveals.
  • An extra anonymous ping fires when sync errors start occurring (capped at one per day), powering an automated canary that compares error rates across releases and catches fleet-wide breakage, like a Letterboxd endpoint change, before bug reports arrive.

Required update for Jellyfin 10.11.9 and 10.11.10 servers

Fixes releases v1.14.1 through v1.15.3 failing to load on Jellyfin 10.11.9/10.11.10 (the plugin was compiled against a newer Jellyfin SDK than those servers ship). If your plugin recently showed as disabled or "malfunctioned", update to this version. No feature changes.

Fixes
  • Jellyfin assemblies carry full per-patch versions, so a plugin compiled against the 10.11.11 SDK silently fails to load on 10.11.10 and older, while the catalog still offered those releases to 10.11.9+ servers. This release is compiled against the 10.11.9 SDK, matching the advertised minimum for the first time, and the catalog metadata for the affected versions has been corrected.
  • New build policy, enforced by CI: the plugin is always compiled against the oldest supported Jellyfin SDK, and the minimum only rises deliberately when a newer Jellyfin API is genuinely needed, never via a routine dependency update.
Upgrade notes: If the plugin is currently disabled on your server: update to v1.15.4 in the catalog (or reinstall), then restart Jellyfin.

Maintenance: telemetry design spec

No plugin behaviour changes.

Improvements
  • Adds the OpenSpec change proposal for upcoming anonymous, opt-in usage telemetry: minimal bucketed payload, default off with a one-time prompt, full payload preview in settings, and a fleet canary that auto-detects regressions. Spec only; no telemetry code ships in this release.

Maintenance: deterministic test teardown for manual-sync endpoints

No plugin behaviour changes.

Improvements
  • Fixes an intermittent CI failure: the manual sync endpoints return 202 and run in the background, and a background sync from one test could still hold the shared sync gate when the next test ran, turning an expected 400 into a 409. The test harness now waits for the spawned sync to finish before the next test starts.

Maintenance: letterboxdsync.dev release notes backfill

No plugin behaviour changes.

Improvements
  • The Releases page on letterboxdsync.dev now has structured highlights for v1.13.4 through v1.15.0, which had shipped without entries.

Jellyseerr request backfill for already-available watchlist films

New opt-in per-account setting "Also backfill requests for already-available watchlist films" (off by default; requires Auto-request). Default behaviour is unchanged for everyone who leaves the box off.

New
  • Watchlist auto-request already creates attributed Jellyseerr requests for films missing from the library, but a film that is on a watchlist and entered the library through another path (manual Radarr add, an import list, or a deleted request) ended up Available with no request record, untraceable. With backfill on, the whole watchlist is considered and available-but-unrequested titles still get an attributed request, so "who requested this?" is always answerable.
  • Per-user dedup: a backfill request is skipped only when the title is blocklisted or this user already has a request for it. Verified against Jellyseerr 3.2.0 that a backfill request on available media succeeds without triggering a re-download.

Maintenance: Jellyfin SDK 10.11.11

No plugin behaviour changes.

Improvements
  • Jellyfin.Controller and Jellyfin.Model updated from 10.11.10 to 10.11.11 (a one-change upstream patch release; no ABI impact, targetAbi unchanged). First update delivered by the Dependabot watch introduced in v1.13.3.

Stops phantom daily rewatches and endless retries of permanently-failing films

Fixes two scheduled-sync dedup bugs reported by a plugin user, one of which re-logged the same film to Letterboxd roughly every other day.

Fixes
  • Films marked played on Jellyfin with no last-played date (marked watched manually, or before Jellyfin tracked dates) defaulted their viewing date to "today", which drifted every run and slipped past all duplicate checks, posting a phantom rewatch to the Letterboxd diary on a rolling basis. Scheduled sync now skips these films entirely until a real play date exists.
  • A film whose sync always fails (for example one Letterboxd cannot match) was re-queued at the head of the queue on every run, forever. Sync now abandons a film after 3 consecutive failures and a successful sync resets the counter.

Maintenance: test coverage expansion

No plugin behaviour changes.

Improvements
  • Test suite expanded to 89.8% line / 81.4% branch coverage, adding coverage for sync-gate contention, named-account targeting, skip-previously-synced filtering, stop-on-failure, and the local-history duplicate backstop.

Maintenance: Dependabot watches the Jellyfin SDK, version-gate links targetAbi to minor bumps

Two preventative measures aimed at the next ABI surprise. No plugin behaviour changes.

Improvements
  • Dependabot now opens a PR the day Jellyfin ships a new Jellyfin.Controller / Jellyfin.Model patch, so the next 10.11.x ABI break is caught by CI on our timeline rather than via a user report (incident: v1.13.0 only existed because 10.11.9's silent IUserManager.Users removal surfaced as a bigrichwood bug report).
  • version-gate now refuses a patch-only bump when targetAbi.txt changes in the same PR. Moving the Jellyfin compatibility floor stops a cohort of users from being offered the next plugin update; that warrants at least a minor version bump so the change is visible in the release notes.

Release notes pipeline: prose-style changelogs back, sourced from the PR body

Restores the v1.0–v1.12 manifest-changelog tone after v1.13.0 and v1.13.1 drifted into incident-report prose and a conventional-commit subject line respectively. Backfills both on letterboxdsync.dev's Releases page.

Improvements
  • release.yml now fetches the merged PR's body via the GitHub API and extracts text between a '## Release notes' header and the next H2 as the manifest changelog. Falls back to the PR title only if the section is missing.
  • New .github/pull_request_template.md primes every PR with the section so it's the path of least resistance.
  • Backfills the manifest changelog for v1.13.0 and v1.13.1 to match the single-paragraph user-facing prose of v1.0 through v1.12.
  • Backfills letterboxdsync.dev with structured Release notes entries for v1.13.0 and v1.13.1 (previously missing).

Maintenance: stronger release pipeline

No plugin behaviour changes.

Improvements
  • Every PR now bumps the version (gated by a required CI check) and auto-ships on merge to main, replacing the manual `git tag` step.
  • PR titles must follow Conventional Commits (`feat:`, `fix:`, `chore:`, `docs:`, `ci:`, `refactor:`, `test:`, `perf:`, `build:`, `style:`). Enforced by CI on every PR.
  • letterboxdsync.dev rebuilds on every release via a `workflow_run` trigger, so the Releases page is never stale (the manifest auto-commit otherwise cannot fire push-based workflows).

Required update for Jellyfin 10.11.9 and newer

Fixes #46. Restores sync on the new SDK ABI; no other plugin behaviour changes.

Breaking
  • `targetAbi` is now `10.11.9.0`. The Jellyfin plugin catalog will only offer this release to servers running 10.11.9 or newer; Jellyfin 10.11.0 through 10.11.8 servers stay on v1.12.0 (which still works for them).
Fixes
  • Jellyfin 10.11.9 removed the `Users` property from `IUserManager` and replaced it with a `GetUsers()` method. The plugin was compiled against the 10.11.0 SDK, so on Jellyfin 10.11.9 and 10.11.10 every read of the user list threw `MissingMethodException`: the dashboard Stats and History endpoints returned 500, and both scheduled sync tasks failed immediately. Recompiled against 10.11.10 and rewrote all seven `_userManager.Users` call sites to use `GetUsers()`.
Upgrade notes: If your Jellyfin server is on 10.11.0 through 10.11.8 the catalog will not offer v1.13.0 by design; upgrade Jellyfin to 10.11.9 or newer to receive this and future plugin updates.

Multi-account support: one Jellyfin user, many Letterboxd accounts

Shared TV logins (e.g. two people on the same family Jellyfin profile) can now each have their own Letterboxd diary, ratings, and watchlist.

Breaking
  • Single-account users will see a new 'Letterboxd Watchlist (yourusername)' playlist created on the next watchlist sync. The old 'Letterboxd Watchlist' playlist is left untouched so you can delete or migrate at your leisure.
New
  • A Jellyfin user can link multiple Letterboxd accounts. Auto-sync (real-time and scheduled) fans out across every enabled account; one failing account never blocks the others.
  • The sidebar "My Letterboxd" page now has feature parity with the admin plugin page for per-account management: add, remove, reorder, test, and configure every account that belongs to your Jellyfin user, without needing admin access. (Admin-only things like the Jellyseerr server URL and editing other users' accounts stay in the admin page.)
  • Per-account watchlist playlists. Default name is 'Letterboxd Watchlist ({letterboxdUsername})' so two accounts on one Jellyfin user get two separate playlists, with an optional per-account name override.
  • Review modal has a 'Post as' account selector when more than one account is enabled, defaulting to posting on all of them.
  • New IsPrimary flag on each account: used to break rating conflicts on diary import and as the preselected option in the review modal.
Improvements
  • Manual API endpoints (/Sync, /SyncWatchlist, /Review) accept an optional letterboxdUsername selector. Omit it to fan out across all enabled accounts.
  • Diary import unions played-state across all linked accounts and merges ratings with the primary account winning conflicts. Existing Jellyfin ratings are still preserved.

Plain-English error and docs when Cloudflare 403s with cookies already set

Improvements
  • The TMDb-lookup 403 exception now names the three real causes (cf_clearance expired, often around 30 minutes; pinned to a different IP than the Jellyfin server; or rejected by Cloudflare's TLS fingerprinting) and points at the README, instead of suggesting raw cookies that the user has already pasted.
  • README has a new 'Still 403ing after pasting Raw Cookies and a matching User-Agent' subsection under 'Cloudflare issues' with a concrete fix per cause. Addresses the dead-end case reported in #34.

Stop phantom rewatches on diary-imported films

Improvements
  • Install instructions now call out the File Transformation plugin as a prerequisite for the in-sidebar Letterboxd link.
Fixes
  • With diary-import enabled, the daily sync was posting phantom rewatch entries to Letterboxd for films you'd only marked played via diary import (never actually watched on Jellyfin). The runner now waits for a real Jellyfin playback before logging the rewatch.

Don't request the wrong movie when watchlisting a TV show

Fixes
  • Watchlisting a TV show on Letterboxd no longer auto-requests an unrelated movie in Jellyseerr. TMDb has independent ID namespaces for movies and TV (e.g. tv/198102 = Hijack, movie/198102 = Cutie Honey Flash); the link extractor was treating every tmdb link as a movie ID. Now skips /tv/ links, with regression coverage.

Bidirectional rating sync and in-dashboard logs

New
  • Bidirectional rating sync. Dashboard reviews mirror their star rating into Jellyfin (always overwrites), and the daily diary import seeds Jellyfin ratings from Letterboxd for films that don't yet have a Jellyfin rating (anti-clobber).
  • In-dashboard Logs tab with per-user and free-text filters, copy-to-clipboard, and download-as-.log for support requests.
Improvements
  • Diary import switched from /log-entries to /films?memberRelationship=Watched so films you rated on Letterboxd without logging a watch now sync too.
  • Privacy hardening: review text is no longer logged.

Maintenance: bump GitHub Actions runtime

Improvements
  • Bumped GitHub Actions versions (checkout v6, setup-dotnet v5, action-gh-release v3) to remain on a supported Node version. No plugin behaviour changes.

Watchlist mirroring into Jellyseerr

New
  • Mirror Letterboxd watchlist into Jellyseerr's user watchlist. Per-account toggle, two-way sync, movies-only so manually-added Jellyseerr TV is safe.
  • On-demand 'Sync Watchlist Now' button on the plugin dashboard so you don't have to wait for the daily run.
Improvements
  • Pre-flight check against Jellyseerr's media status eliminates duplicate requests for already-pending/processing/available titles.
  • Per-user watchlist sync runner extracted with a shared SyncGate so diary and watchlist syncs serialise.

Local-history backstop against Cloudflare-induced duplicates

Addresses #21.

Improvements
  • Paginated dashboard history table (100 per page) now that the 500-entry cap is gone.
Fixes
  • Refuse to MarkAsWatched when sync history shows a recent successful sync that does not pass the rewatch threshold. Fixes the Cloudflare-failed-validator path that was creating real Letterboxd diary duplicates.

Skip already-synced films and let non-admins Run Sync Now

Fixes #20.

New
  • Non-admin users can now Run Sync Now (triggers their own account only).
  • Per-account stop-on-failure toggle to halt the moment Letterboxd anti-flooding triggers.
Improvements
  • Skip already-synced films using local sync history so we don't burn Cloudflare quota on duplicate checks.
  • Prioritise previously-failed and skipped films first.
  • Explicit info-level logging for every skip with a reason.

Jellyseerr auto-request for unmatched watchlist films

New
  • Jellyseerr auto-request for unmatched watchlist films, with per-user attribution via Jellyfin User ID.
Fixes
  • Dedup fix: the watchlist playlist no longer accumulates duplicate entries on each run.

Per-account User-Agent override

New
  • Per-account User-Agent override so Cloudflare cookies copied from any browser (Chrome, Safari, etc.) work without UA mismatch.

Official Letterboxd API integration with scraping fallback

New
  • Official Letterboxd API is now the primary path, with web scraping as a fallback. Eliminates the Cloudflare 403 errors that were blocking syncs.

User self-service account setup and standalone user page

New
  • User self-service account setup — users link their own Letterboxd account without admin help.
  • Sidebar link for all users.
  • Test connection button on the account form.
  • Standalone user page via File Transformation injection.

Architecture refactor, TMDb cache, progress dashboard

New
  • Progress dashboard showing sync state at a glance.
  • TMDb cache for repeated lookups.
Improvements
  • Architecture refactor for clearer separation of HTTP, auth, scraping, and diary writes.
  • Cloudflare resilience improvements.
  • Watchlist cleanup pass.
Fixes
  • Diary import fix.

Real-time playback sync

New
  • Real-time playback sync via PlaybackHandler — diary entries land within seconds of credits rolling.
Improvements
  • Automatic session re-auth on 401.

Star ratings in reviews and rewatch date picker

New
  • Star ratings in reviews.
  • Rewatch date picker.
  • Better error display in the dashboard.
Improvements
  • Cloudflare retry on review posting.
Fixes
  • Sync history persistence fix.

Dashboard, watchlist sync, diary import, reviews

New
  • Dashboard with sync history.
  • Watchlist sync.
  • Diary import.
  • Reviews from the dashboard.
  • Rating sync.
  • Rewatch detection.
Improvements
  • Cloudflare backoff.