[!IMPORTANT]
If you use Soulseek, share files in slskd (http://localhost:5030/shares). Leechers get banned by the network.
Contents
Why SoulSync
Most self-hosted media setups are a relay race: one app wants things, another searches, a third downloads, a fourth tags, a fifth tells the server, and when a handoff fails nobody notices. SoulSync runs the whole race itself and keeps the receipts.
- It knows what you own. Every search, playlist and recommendation is checked against your real library, so "missing" means missing.
- It checks its work. Downloads are fingerprinted, sanity checked, quality ranked and quarantined when they don't hold up. Nothing lands in your library on faith.
- It explains itself. Stuck wishlist rows show exactly which releases were refused and why. Every download has an audit trail.
- It's one app for the whole house. Music, movies, TV, YouTube, podcasts and audiobooks, with profiles so everyone gets their own taste, playlists and history.
At a glance
| |
|---|
| Download sources | Soulseek (slskd), Tidal, Qobuz, Deezer, HiFi, YouTube, SoundCloud, Lidarr, Torrent and Usenet (via Prowlarr). One source or a drag-ordered hybrid chain. |
| Metadata | Spotify (with or without an account), Apple Music / iTunes, Deezer, Discogs, MusicBrainz, plus 14 background enrichment workers |
| Media servers | Plex, Jellyfin, Navidrome, or SoulSync Standalone (no server needed) |
| Playlist sources | Spotify, Tidal, Qobuz, Deezer, YouTube, YouTube Music, Apple Music links, ListenBrainz, Last.fm, Beatport, SoulSync's own mixes, CSV / TSV / TXT / M3U files, and NewPipe backups |
| Video | Movies, TV and YouTube channels with TMDB / TVDB, Prowlarr, qBittorrent / Transmission / Deluge / SABnzbd / NZBGet, Plex and Jellyfin |
| Automation | Visual WHEN → DO → THEN builder, 60+ triggers and actions, Discord / Telegram / Pushbullet / webhook notifications |
| Network (optional) | MetaSync companion: share anonymous weekly taste signals with other SoulSync installs through SIN and get SoulSync Charts back as ready-to-sync playlists |
| Runs on | Docker (amd64 + arm64), Unraid, or plain Python 3.11 |
Music
Dashboard
The home screen is split in two: your music on the left, the machine on the right.
- Hero with a greeting, your library size, one-click Quick Scan and a menu for deep scans, match verification, repair and database backups.
- Worker orbs: every enrichment worker lives on its own animated stage. They drift while resting, pulse when busy, turn red on errors, and fly home into a grid of controls when you hover.
- Library Radio and Your Mixes, Recently Added / Fresh Releases / SoulSync Charts (when MetaSync is connected), and Recently Played (tap a song to play it again; repeats fold into one card).
- Playlist sync health: one honest number for how much of your playlists you own, the playlists missing the most, sorting by missing / last synced / next run / name, and running syncs pinned to the top.
- Up next: the next automations to fire, with run and pause on hover.
- An alerts band that stays invisible until a connection actually breaks.
Playlist sync
Bring a playlist in from anywhere, keep a mirror of it, and keep your media server's copy in step on a schedule.
- Add playlist: paste any link and SoulSync works out the service and imports it, or open a connected account and press Import on the playlists you want (or Import all), or drop a CSV / TSV / TXT / M3U file and map its columns, or a NewPipe backup to bring its playlists over. Either way you land on the imported playlist under Mirrored, already identifying itself in the background.
- Mirrored library: every playlist as a card whose artwork carries its state (a coverage ring, a pulse while syncing, desaturated when something's wrong). Filter by Needs attention / Working / Discovered / Scheduled, search, sort, bulk delete.
- Discovery: matches each source track to real metadata with live progress. Fix any match by hand (including by MusicBrainz ID), retry the failures, or let Wing It make best-effort guesses that you can review later in the Wing It Pool.
- Sync modes: Replace, Reconcile (edit in place, keep the server playlist's image and description) or Append.
- Schedules: per playlist, from hourly to weekly, or on a drag-and-drop Auto-Sync board with a live pipeline monitor and run history. A scheduled pipeline does refresh → discover → sync → download missing, unattended.
- Server playlists: a side-by-side compare editor for Plex / Jellyfin / Navidrome (matched, missing, extra), swap versions, find & add, unmatch a wrong pairing while keeping the track, reorder to match the source, export M3U.
- Export any playlist to Spotify, Deezer, ListenBrainz or a JSPF file.
- Beatport: Top 100, Hype 100, top 10 lists and releases, and a full genre browser.
- Organize by playlist: optionally download a playlist into its own folder.
- Cover art: Generate cover art in any playlist's ⋯ menu (on the card or inside the playlist) paints a cover from its genres, mood and era with Pollinations. Preview it with the playlist's name across the top (or without), try another style, keep the one you like; it survives refreshes and syncs to your server. Free with no key (one image every 45s, small Pollinations mark), or add a key in Settings to lift both.
Search & downloads
One search box with three modes.
- Catalog: search Spotify, Apple Music, Deezer, Discogs, MusicBrainz or Amazon. Results show In library and In wishlist; albums open a download-missing view, artists and labels open their pages.
- Videos: official music videos from YouTube, downloaded straight into your library.
- Files: search a download source directly (like classic Soulseek), filter by format and quality, then choose how it comes in:
- Download as-is — untouched, into Transfer.
- Enriched download (recommended) — each file is matched to a real release, tagged, given cover art and filed.
- Tag it yourself — for bootlegs, live sets and mixtapes.
Sources. Use one, or build a hybrid chain in the order you prefer. If a source can't meet your quality profile, SoulSync falls through to the next.
| Source | Notes |
|---|
| Soulseek | via slskd. Whole-album grabs from one peer, peer quality scoring, search throttling, free-disk guard |
| Tidal | device-flow login, up to FLAC 24-bit Hi-Res |
| Qobuz | up to Hi-Res Max (24-bit/192 kHz) |
| Deezer | ARL token, FLAC → MP3 320 → MP3 128 fallback |
| HiFi | free lossless via public instances, no account, automatic failover |
| Amazon Music | RETIRED — the public proxy it relied on is gone; saved chains silently drop it |
| YouTube | yt-dlp, cookies supported |
| SoundCloud | anonymous |
| Lidarr | hand an album to Lidarr's indexers, import only the tracks you need |
| Torrent | Prowlarr search; qBittorrent, Transmission, Deluge or aria2; seeding goals; archive extraction |
| Usenet | Prowlarr search; SABnzbd or NZBGet; remote path mappings |
Downloads page. Live batches with speed and ETA, "download this next", a step-by-step detail sheet on every download (found, downloaded, verified, imported), manual search on failed tracks, play straight from finished ones, per-track audit trails (lifecycle, embedded tags, lyrics), a Review queue for anything that needs a human, and a Clients pane that manages slskd, your torrent client and your usenet client from one place.
Quality, verification & tagging
- Quality profiles: named profiles built from a ranked ladder of formats, bit depths, sample rates and bitrates, with a cutoff. Start from Audiophile, Balanced or Space Saver, then assign profiles per playlist, artist or wishlist item. Upgrade until cutoff keeps chasing a better copy, and a file is only ever replaced by a measured upgrade.
- Verification: AcoustID fingerprinting, real-audio checks with ffmpeg (catches padded previews), silence, duration (with an adjustable tolerance) and integrity guards, and a fake-lossless detector.
- Quarantine & review: anything that fails is held with its reason and uploader. Approve it, recover it to staging, or delete it. Removed files go to a recycle bin with configurable retention.
- Tagging: Picard-style MusicBrainz release preflight pins one release per album so every track agrees. Tags are written with mutagen (ID3v2.4, FLAC, Vorbis, MP4), enriched in the order you choose.
- Extras: preferred-source cover art with a minimum size, synced lyrics from LRClib, ReplayGain 2.0 (track + album), optional lossy copies (MP3 / Opus / AAC), and atomic album publishing so half-downloaded albums never appear in your server.
- File organization: templates for albums, singles, compilations, playlists, music videos, podcasts and audiobooks (
$albumartist/$album/$track - $title and friends), including beets-compatible $atypes release labels so [2017][EP][Live] Audiotree Live and a plain [2019] Tokyo come out of the same template, and $explicit / $contentrating badges ([E], [C]) so explicit and clean versions never share a filename, and $albumartistclash / $albumartistinfo / $albumartistcomposite (MusicBrainz disambiguation, else country and genre) so two artists called Nirvana get their own folders. An opt-in lookalike mode keeps AC∕DC and What's Going On? instead of underscoring them. Every template shows the path it makes right under it as you type, for a plain, explicit or multi-disc release, or an artist that shares its name.
Discover
A personal front page shaped by your library, your listening and your watchlist.
- Start Here: a "next best move" card plus zones for For You, New & Missing, Your Taste Map and Browse & Build.
- Your Mixes: Fresh Tape (new from artists you follow), The Archives (your Spotify Discover Weekly, refreshed weekly), Hidden Gems, Popular Picks, Discovery Shuffle, Your Listening Mix, and decade Time Machine mixes. Download or sync any of them to your server.
- Adventurousness dial: drag from "safe" to "deep cuts" and the recommendations re-rank live.
- Recommended artists, Because you listen to…, New releases for you, New in your genres, Albums you're missing, More from your labels, Deep cuts.
- Stations: endless artist radio, or a stable 40-track snapshot you can download or sync.
- Deezer Curated editorial playlists (no key needed), ListenBrainz recommendations, and Last.fm Radio.
- SoulSync Charts: what the SoulSync network is wishlisting, keeping and playing this week, as playlists that open ready to sync (needs MetaSync, and the shelf hides itself without it).
- Build a playlist from 1 to 5 seed artists.
- Artist Map & Artist Web: full-screen graphs of your taste. Genres, communities, influence, and the shortest path between any two artists.
- Playlist Explorer: turn any playlist into a tree of its artists and albums, then wishlist the gaps.
Library & artist pages
- Library: every artist, filterable by letter, watch state, and which metadata sources each one is (or isn't) matched to. Export as JSON / CSV / text / M3U.
- Songs: every song you own, searchable by title from any library view. Each one shows its album and file quality so copies are easy to tell apart; play it, add it to a playlist, and (admins) delete it.
- Fix a wrong match by pasting the artist's link or ID from Spotify, Apple Music, Deezer, Discogs, Tidal, Qobuz and more. The watchlist follows the fix.
- Artist pages: full discography with ownership, live completion bars for albums / EPs / singles, top tracks, similar artists, a music video player, and concerts (Ticketmaster dates and Setlist.fm setlists you can play from your own library).
- Gap-fill pulls in releases your other metadata sources know about.
- Enhanced view (admins): inline tag editing, bulk BPM / mood / style edits, write tags to files with a diff preview, ReplayGain, reorganize with a path preview, move an album to another artist, re-identify a track, redownload with source picking, and delete (database only, or files too).
- Fix matches: change artwork from any source, inspect the database record, and forget wrong matches per source.
- Label pages: a label's full catalog with owned / missing filters. Follow a label for new releases or its whole backlog.
Watchlist & wishlist
- Watchlist: follow artists and labels. SoulSync scans for new releases on a schedule, with per-artist rules (albums, EPs, singles, live, remixes, compilations), lookback windows, scan source and auto-download. The Artist Inspector shows linked IDs per provider and recent releases, and a Blocklist keeps things you never want.
- Wishlist: everything wanted, retried automatically with progressive backoff. Browse it as a Nebula (an orb per artist, grouped by what's stuck: no match found, or downloaded then rejected) or a dense list. Open an artist to see why each track failed in plain words, retry it, or pick a source by hand.
- Requests: Overseerr-style for music too — profiles without download rights add to their wishlist like anyone else, and the scheduled run only downloads what an admin approved.
Import
An inbox for everything in your staging folder, with a Picard-style matcher.
- Drag files or folders into the browser to upload them.
- SoulSync identifies each folder by exact IDs first (Spotify links in tags, ISRCs), then tags, filenames and AcoustID.
- A confidence line decides what imports on its own, what waits for review and what needs identifying.
- The matcher lines each file up against a release's tracks, with length and quality side by side, so mismatches are obvious before anything moves. Drag to re-pair; fingerprint a folder when tags lie.
Tools & library maintenance
- Library health score with a findings inbox that turns thousands of findings into a few decisions, and Fix all safe for metadata-only repairs.
- Findings sorted by what a fix would do (safe, needs your call, review only), undo on every dismiss, and keyboard triage (`j`/`k`/`f`/`d`).
- 31 maintenance jobs, each with its own schedule: duplicate and single/album dedup, dead and orphan files, AcoustID scanning, fake-lossless and corrupt-file detection, cover art, lyrics and ReplayGain fillers, metadata gaps, album completeness, discography backfill, quality upgrades, lossy conversion, reorganize and re-tag, MBID mismatches, album tag consistency, unknown-artist and comma-artist fixes, genre cleanup and enrichment, and more.
- Database updater (incremental, full refresh or deep scan), manual library matching, backups with restore, a metadata cache browser, and config export/import (optionally with credentials).
Listening stats & scrobbling
- Listening stats: plays, time, top artists / albums / tracks, genres, when you listen, streaks, and how much of what you own you actually play.
- Your Year: a full-screen, Wrapped-style story of your year, ending in a card studio that exports shareable images using your real album art.
- Scrobbling to Last.fm and ListenBrainz from Plex, Jellyfin or Navidrome.
- History import from Last.fm, ListenBrainz and Maloja. Each profile can connect its own account and gets its own stats and recommendations.
Player & radio
A full web player built into the sidebar.
- Now Playing view with album-colour glow, synced lyrics, audio-reactive visualizers, crossfade, a sleep timer, and OS media controls.
- A persistent, reorderable queue that can auto-download tracks you don't own yet.
- Radio mode, Artist Radio and Library Radio (an endless shuffle of your own collection).
- Tracks you don't own stream from a preview source, so you can hear before you grab.
Podcasts & audiobooks
- Podcasts: discover via Apple Podcasts search or add any RSS feed (private and Patreon feeds included), OPML import/export, show notes and transcripts, and a watchlist that auto-downloads new episodes and cleans up old ones.
- Audiobooks: browse Audible's catalogue by genre, series, author and narrator, follow authors for new books, and fetch releases from Soulseek, torrent or usenet. SoulSync looks inside each release before downloading, matches your existing books to catalogue editions (across extra folders on other drives too), and keeps its own wishlist, blocklist and recycle bin.
Video: movies, TV & YouTube
A complete video side with its own database, pages and pipeline. Switch sides from the header; each profile can be given music, video, or both.
Dashboard
- The music dashboard's layout on video: a greeting with your library's size, a scan strip, and the video enrichment workers on their own orb stage.
- Next up: the calendar's billboard for what airs next, each episode with its state.
- Continue watching, Downloading now (only while something is), and Recently added with Movies / Shows tabs.
- This week in the rail: how many of the episodes that aired this week you have, a meter by state, when auto-wishlist last ran, and one button to wishlist what's missing.
- Up next video automations, watchlist and wishlist counts, and issue / findings tiles that only appear when something needs you.
Library
- Movies, shows and YouTube channels from Plex or Jellyfin, with incremental, full and deep scans, per-title sync, and a path resolver for mismatched Docker / NAS mounts.
- 15 enrichment workers: TMDB, TVDB, OMDb (IMDb, Rotten Tomatoes, Metacritic), fanart.tv, OpenSubtitles, Trakt, TVmaze, AniList, Wikidata, SponsorBlock, DeArrow, Return YouTube Dislike, streaming (where-to-watch), Mediastinger (credits scenes) and awards — plus a background YouTube upload-date enricher.
- Bulk edit & field locks: edits are written to SoulSync and pushed to your server, and locked fields are never overwritten by enrichment.
Detail pages
- Trailer-backed heroes with one primary action (Play / Resume on your server, else Get) and everything else in one More menu.
- Every rating, cast and crew, where to watch, collections and acquisition history.
- Four season views, and season tools: grab, search, wishlist, monitor.
- A Your library tab on every movie and show: each copy you own with its quality, codecs, size, folder and subtitles, whether its name matches your template, and file actions (rename to template, delete to the recycle bin). Shows get every season with counts, size, a resolution mix and a monitored switch, plus the folders a show is split across.
- Fix match that sticks: re-point a title to the right TMDB entry and scans can't switch it back.
- Person, studio, channel and playlist pages.
Finding things
- Search:
- Enhanced search across movies, shows, people, studios and channels.
- Raw release search across slskd, Prowlarr indexers and more.
- A live Fresh Releases board.
- Discover: TMDB-powered and personal.
- Recommended for you, and "finish your collection".
- Charts, streaming services, moods and world cinema.
- A full browse filter.
- TV Calendar:
- Week, agenda and month views. Every episode says where it stands (in library, downloading, wanted, failed, missing, auto-grabs on air), with cinema / home release dates for movies.
- Aired episodes are wishlisted on their own every few hours, each once, and the page says when that last ran.
- A per-profile iCal feed for your phone, readable without signing in.
Getting things
- Watchlist → wishlist → download:
- Follow shows, people, studios and YouTube channels, with back-catalog policies.
- The wishlist (Movies, TV and YouTube tabs, the same design as the music one) retries with backoff and groups what's stuck by cause: found but refused by your rules, nothing found, couldn't search, or not posted yet. Open a title to see every release the last search judged and why each was refused.
- Requests: Overseerr-style. Non-admins request, admins approve.
- Import lists: TMDB, IMDb and Plex Watchlist.
- Indexers & clients:
- Prowlarr (structured and text queries, TV query ladder including anime and daily shows) and RSS sync.
- qBittorrent, Transmission, Deluge, SABnzbd, NZBGet and slskd.
- Seeding goals, season packs, and stall detection.
- Quality profiles:
- A 16-tier ladder with upgrade-until-cutoff and Sonarr-style custom formats.
- Codec, HDR and audio preferences, audio language (prefer or require a dubbed / MULTI release), size limits and minimum seeders.
- Optional 4K libraries: a separate Movies 4K and TV 4K folder, off until you switch them on. A profile set to save to the 4K library files new titles there.
- A separate YouTube profile.
- Import: sample and wrong-episode rejection, ffprobe checks, templated renames, NFO and artwork sidecars, subtitles, disk-space guards. Plus a release blocklist and a recycle bin.
- Downloads page: Downloads / Review / Clients views with live batches, a review queue and download-client management — the same setup as the music side.
Making it yours
- Overlay Studio: a Kometa-style visual poster editor.
- Layers, dynamic fields (resolution, HDR, codecs, ratings, awards, streaming service…) and per-scope rules.
- Always rendered from a clean base, so overlays never stack and can be undone.
- Collection Studio:
- Smart-filter and list collections from TMDB, IMDb, Trakt and MDBList.
- Presets, seasonal windows, generated artwork, and wishlisting missing members.
- Poster Manager for TMDB posters, including textless ones.
- Maintenance jobs: broken files, duplicates, naming, quality upgrades, watched cleanup and more, on the same Tools page as music (health score, findings inbox, fix-all in the background). Plus backups and mass rename.
- Server Activity: a Tautulli-style live view of streams, history and stats.
- Watch Together in chat: vote on a title and watch together.
YouTube
- Follow channels and playlists as TV shows, with no API key.
- Per-channel resolution, codec, length and title filters, and retention.
- Everything lands as a Plex "TV by date" show.
Platform
Automations
A visual WHEN → DO → THEN builder shared by music and video.
- Triggers:
- Schedules: interval, daily, weekly and monthly times, app start.
- Events: downloads, quarantines, new releases, watchlist changes, playlist syncs, imports, maintenance findings.
- External: webhooks and signals from other automations.
- Actions:
- Process wishlist, scan watchlist, run a full playlist pipeline, update the database.
- Import listening history, run maintenance, clean up, back up.
- Search & download, or run your own scripts.
- Then: Discord, Telegram, Pushbullet, a webhook, a script, or a signal that chains into another automation, with per-step conditions and
{variables}.
- Automation Hub: install ready-made pipelines in one click, such as Playlist Pipeline (All-in-One), New Music Pipeline, Nightly Operations, Quality Assurance Pipeline and Full Hands-Free Pipeline.
Profiles & access
- Profiles with avatars, PINs, a home page, page access, music / video access, and a download permission.
- Per-profile watchlists, wishlists, playlists, queues and listening history.
- Non-admins get a My Account panel for their own Spotify, Tidal, ListenBrainz and Last.fm, and their own media-server identity (Plex Home user, Jellyfin / Navidrome login).
- Security:
- An admin PIN with brute-force limits, or full username/password login with recovery questions.
- Sign in with Plex or with your own OIDC provider, or OIDC only, which turns every other sign-in off. If the provider is ever down,
SOULSYNC_OIDC_ONLY_OVERRIDE=off and a restart let the admin back in with their password. Setup and troubleshooting: docs/guides/OIDC.md.
- Or trust a forward-auth header from Authelia, Authentik or oauth2-proxy.
- Reverse-proxy and sub-path aware.
- Own library per profile (Plex / Jellyfin): a profile can have its own folder and server library.
- Content caps (video): per-profile G / PG / PG-13 / R limits, enforced across the video side.
Chat & arcade
Soulseek rooms and private messages through slskd, in a Discord-style layout.
- Channels and threads, replies, reactions, mentions, pins, GIFs, link previews and file sharing.
/np, /want, /poll and friends.
- Room activities:
- A shared YouTube jukebox with voting.
- Watch Together, polls and trivia.
- Arcade: chess, Connect 4, Battleship, Othello and Gomoku, plus a slot machine.
- Everyone's client computes the same game state from the room messages, so no game server is needed.
- Room-vs-player voting, and commit-reveal boards so nobody can cheat.
- Browse a peer's shares and download from them.
API & webhooks
- REST API at
/api/v1 covering library, search, wishlist, watchlist, downloads, playlists, discover, settings, profiles and video.
- Inbound request webhook:
POST /api/v1/request with a query and SoulSync searches, matches and downloads it. Good for Discord bots and shortcuts.
- MCP server at
/mcp, so Claude and other AI apps can search, check your library and download through SoulSync with an API key. A read-only key can look but not change anything.
- Lidarr compatible API at
/lidarr, so request apps that only speak Lidarr (Singarr, MusicSeerr 1.x) can send their album requests to SoulSync instead.
- Both are off until you turn them on in Settings > System > SoulSync API. See Support/API.md.
Mobile, PWA & theming
- Fully responsive, and installable as a PWA (cover art cached for speed, never stale pages).
- Accent colours (presets or any custom colour), a sidebar visualizer, background particles, worker orbs, and Reduce Visual Effects / Max Performance switches for low-power devices.
Companion browser extension
SoulSync Companion puts your server's knowledge on the pages where you discover music. While browsing Spotify, Deezer, YouTube, Bandcamp, SoundCloud or Tidal, small pills next to artists, albums, tracks and playlists show your real library state — ✓ In library, + Wishlist, 👁 Watching — and one click wishlists a track, watches an artist, or saves a whole playlist straight to your server. Chrome and Firefox, one Manifest V3 codebase.
MetaSync & SoulSync Charts
MetaSync is an optional companion program that runs next to SoulSync. Its first network is SIN, the SoulSync Intelligence Network: SoulSync installs that share small, anonymous taste signals once a week and get shared charts back. SoulSync works exactly the same without it, and nothing is shared until you install MetaSync, join a pool and turn off Dry run.
How it flows
- Weekly read, on your machine. Early each Monday your MetaSync node reads last week's activity from SoulSync's local API: what you watchlisted, wishlisted, added and downloaded, plus what you listened to if you turned that on.
- One report a week, the only thing that leaves. The node turns the week into yes/no signals keyed only by MusicBrainz IDs, such as "this install wishlisted album X". No titles, file paths, play counts or library listings.
- Counted on arrival. The pool adds +1 to each album's count for the week and keeps nothing else from the report.
- Only crowds count. An album appears in a chart only once 15 or more different installs reported it that week. Below that it's never shown to anyone, and those counts are deleted after 3 weeks.
- Charts are built once, for everyone. Each charted album contributes its 2 most popular songs by ListenBrainz's public statistics.
- SoulSync shows them. The Refresh MetaSync Charts system automation asks your node for the charts once a day, matches every song in the background, and shows a chart only when every song in it is matched.
What gets shared. Eight one-bit signals per album or artist per week, covering the last full week. "Played it 40 times" and "played it 3 times" look the same.
| Signal | Means | Default |
|---|
watchlist_add | You started watching this artist this week | On |
wishlist_add | You wishlisted this album this week | On |
hunt_demand | Wishlisted 7+ days ago and still not downloaded | On |
recent_add | The album landed in your library this week | On |
import_keep | The album reached 14 days in your library (sent once per album, ever) | On |
download_grab | You re-grabbed, upgraded or gap-filled an album you already had | On |
download_churn | Downloaded 14+ days ago, then removed, confirmed by two weekly checks | Off (Share drop signals) |
listen_album | You played 3+ different songs from the album this week, your 50 most played at most | Off (Share listening signals) |
With listening signals off, MetaSync doesn't read your listening history at all. With them on, SoulSync only hands over the shared listening history, so a profile with its own listening account is never included. If one kind of event happens more than 500 times in a week (a bulk import, a drive remount), that kind isn't reported that week, so a report can never become a copy of your library. The node's Payload preview page shows the exact report before anything is sent.
Privacy, as built
- Counted, not stored. The pool keeps per-week totals per album, never your report and never which installs sent what.
- No week-to-week tracking. Each report carries a token that changes every week, only to stop a double send.
- Keys stay yours. The portal stores only key hashes, your node signs every request, and your pool key only works from the one node you approved. Revoking the key or unbinding the node cuts access on the very next request.
- Members can't publish. Nodes can only send their own signals and read charts. Only the official composer builds them.
- Honest limits. The pool sees a request arrive from an IP like any website (it doesn't store it), it briefly holds one week's report while counting it, and counts above 15 are public by design. The full data map is DATA.md in the MetaSync repository.
The charts
| Chart | What puts an album on it |
|---|
| Trending in SoulSync | Wishlisted or grabbed this week compared with the 3 weeks before, so a riser beats a steady seller |
| Most Wanted | Wishlisted, or still hunted after a week |
| Just Landed | Newly added to libraries this week |
| Loved & Kept | Kept past 14 days, minus albums people deleted |
| Rising | Demand at least doubled since last week |
| Breakout Artists | Artists whose watchlist adds at least doubled (20+ installs) |
| On Repeat | Played by 15+ installs that share listening signals |
| Top Tracks · from ListenBrainz | ListenBrainz's public weekly song chart, at most 2 songs per artist |
Charts are 25 albums and 50 songs, best songs first, and also come in genre and decade editions ("Trending: Hip Hop", "Trending: 2020s") once 8 charted albums share a tag. While the network is young, Trending and Just Landed fill empty slots from ListenBrainz's public charts, and the name says so ("Trending · SoulSync + ListenBrainz").
They show as a SoulSync Charts tab on the dashboard and a SoulSync Charts shelf on Discover. Charts are offers, never orders: opening one gives your profile its own playlist on the Sync page with the matches already in it, and nothing reaches your media server, wishlist or downloads until you press Sync & download (or turn on Auto-Sync for it). When the chart updates, your copy updates in place and keeps its matches, and if a chart leaves the network your copy stays yours.
Setting it up
- Get a pool key at metasync.ssync.net. It's shown once, and the portal only stores a hash of it.
- Run the node with Docker (see the MetaSync repo's compose example) or
python3 run.py, open http://localhost:8790 and set an admin password.
- Connect it: Settings → Connections → MetaSync → Connect. SoulSync finds the node and shows a pairing code, approve it on the MetaSync dashboard and the two swap keys. Connecting joins nothing, it only lets the two programs on your machine talk.
- Join the pool: paste your pool key into the same section. SoulSync hands it to the node and never contacts the pool itself.
- Approve the node on the portal the first time it shows waiting for approval, checking the fingerprint matches the node's dashboard.
- Check the report, then send it: the node starts in Dry run and only shows the report on its Payload preview page. Turn Dry run off when you're happy, and it reports once a week on its own.
To leave, Disconnect in the same section revokes the key SoulSync gave the node, and revoking your pool key or unbinding the node on the portal leaves the network completely. Help & Docs has a full MetaSync section with a flow chart and troubleshooting for every message the charts automation can show.
Installation
Docker (recommended)
curl -O https://raw.githubusercontent.com/Nezreka/SoulSync/main/docker-compose.yml
docker compose up -d
# open http://localhost:8008
The image runs as a non-root user with PUID / PGID / UMASK support, and bundles ffmpeg, fpcalc (AcoustID), Deno and a current yt-dlp.
| Port | Used for |
|---|
8008 | Web UI and API |
8888 | Spotify OAuth callback |
8889 | Tidal OAuth callback |
Release channels
| Channel | Image | What it is |
|---|
| Stable | boulderbadgedad/soulsync:latest | Promoted from dev to main when a release is ready. Recommended. |
| Pinned | boulderbadgedad/soulsync:3.4.9 or ghcr.io/nezreka/soulsync:3.4.9 | A permanent tag for each stable release |
| Dev | ghcr.io/nezreka/soulsync:dev | Rebuilt on every push to dev. New features first, occasional rough edges |
| Nightly | ghcr.io/nezreka/soulsync:nightly | Built at 04:00 UTC when dev changed that day |
| Snapshot | ghcr.io/nezreka/soulsync:dev-YYYYMMDD-<sha> | An exact dev build to pin to |
To switch, change image: in docker-compose.yml, then docker compose pull && docker compose up -d.
Unraid
Install from Community Applications, or add the template manually:
https://raw.githubusercontent.com/Nezreka/SoulSync/main/templates/soulsync.xml
Set PUID / PGID to match your share permissions (default 99 / 100). For the dev channel, change the container's Repository to ghcr.io/nezreka/soulsync:dev. See Support/UNRAID.md.
Python (no Docker)
git clone https://github.com/Nezreka/SoulSync
cd SoulSync
python -m pip install -r requirements.txt
# build the web UI (Docker does this for you)
cd webui && npm ci && npm run build && cd ..
gunicorn -c gunicorn.conf.py wsgi:application
# open http://localhost:8008
After every git pull, rebuild the web UI (cd webui && npm ci && npm run build) before restarting. If webui/static/dist/.vite/manifest.json is missing or stale, pages won't load correctly.
For YouTube streaming and music videos on bare metal you also need:
- Deno: yt-dlp needs a JavaScript runtime (
winget install DenoLand.Deno, or see deno.com).
- yt-dlp nightly when YouTube changes break things:
python -m pip install -U --pre "yt-dlp[default]".
Local development
Two terminals, so the backend and Vite reload independently:
# backend (restarts on Python changes)
python -m pip install -r requirements-dev.txt
gunicorn -c gunicorn.dev.conf.py wsgi:application
# frontend (hot reload)
cd webui && npm ci && npm run dev
python dev.py starts both on any OS (./dev.sh on Unix). Run tests with python -m pytest, and see webui/README.md for frontend notes.
Setup guide
What you need
- Nothing else, to start. SoulSync Standalone works without a media server, and HiFi, YouTube and Deezer need no extra software.
- slskd (releases) if you want Soulseek.
- Spotify API credentials (dashboard): optional, but the best source for discovery. Without them SoulSync uses Spotify's public data, Apple Music and Deezer.
- A media server (optional): Plex, Jellyfin or Navidrome.
- Prowlarr plus a torrent or usenet client, for the torrent / usenet sources and the video side.
- TMDB and TVDB keys for the video side.
1. Connect slskd (optional)
- Add an API key in slskd's
settings.yml under web > authentication > api_keys, then restart slskd.
- In SoulSync: Settings → Connections → Soulseek, paste the URL and key (or use Auto-detect).
- Share some files in slskd.
2. Connect Spotify (optional)
- Create an app at developer.spotify.com/dashboard.
- Add the redirect URI
http://127.0.0.1:8888/callback.
- Paste the Client ID and Secret into Settings → Connections → Spotify.
Behind Docker or a remote host? See Support/DOCKER-OAUTH-FIX.md.
3. Configure SoulSync
Open http://localhost:8008. Setup finds your media server, slskd, Prowlarr and download clients on its own, signs in to Plex, Tidal and Qobuz, checks every folder and connection for real (Settings > Folders keeps checking each folder as you type: free space, write access, nesting, unmapped Docker volumes), and leaves a Finish setting up checklist on the dashboard for anything you skip. Everything else lives in Settings:
- Sources / Downloads: pick a source or build your hybrid chain.
- Quality: pick a preset or build a quality profile.
- Library: set your folders and file-naming templates.
- Connections: add your media server. Use your machine's real IP, not
localhost (inside Docker that means the container itself).
4. Docker paths
| What | Container path | Notes |
|---|
| Config | /app/config | |
| Logs | /app/logs | |
| Databases | /app/data | Use a named volume (soulsync_database:/app/data). Bind-mounting a host path here can hide files the app needs. |
| Downloads | /app/downloads | The same folder slskd and your clients download to |
| Library output | /app/Transfer | Where organized music is filed |
| Import | /app/Staging | Optional, for importing music you already have |
| Music videos | /app/MusicVideos | Optional |
| Podcasts / audiobooks | /app/podcasts, /app/audiobooks | Optional |
| Video | /media/movies, /media/tv, /media/youtube | Optional, for the video side |
| Video extras | /media/anime, /media/movies-4k, /media/tv-4k | Optional: the anime and 4K libraries, commented out in the compose file |
Useful environment variables: PUID, PGID, UMASK, TZ, SOULSYNC_URL_BASE (serve under a sub-path, see docs/REVERSE_PROXY_SUBPATH.md), and SOULSYNC_LOG_LEVEL.
5. Sign in with OIDC (optional)
To let people sign in with Pocket ID, Authentik, Authelia, Keycloak or another OpenID Connect provider, follow docs/guides/OIDC.md.
Architecture
- Backend: Python 3.11, Flask + Flask-SocketIO on Gunicorn, SQLite in WAL mode (separate music and video databases). Settings live in the database, and secrets are encrypted at rest.
- Frontend: a React 19 + TypeScript app (TanStack Router and Query, Vite) running alongside the original vanilla-JS shell, which is being migrated page by page. Live updates arrive over WebSockets.
- Core pieces:
- Matching engine: version-aware fuzzy matching, aliases, cross-script names, and manual overrides that always win.
- Download orchestrator: 10 sources, a hybrid chain, quality-profile ranking, album bundles, retries.
- Import pipeline: verification, quarantine, MusicBrainz preflight, tagging, art, lyrics, ReplayGain, atomic publish.
- Enrichment workers: 14 music and 15 video, each yielding to user activity.
- Automation engine: event bus, signal chains, cycle guards.
- SoulID: deterministic cross-instance IDs for artists, albums and tracks.
Contributing
SoulSync uses a dev → main flow:
main: releases. :latest builds from here, and it only receives merges from dev.
dev: integration. :dev and nightly images build from here.
- Feature branches: branch from
dev, and open PRs against dev.
To open a PR:
- Fork, then branch from
dev: git checkout -b fix/your-change dev
- Make the change, with tests.
- Open a PR against
dev (not main).
- CI runs ruff, pytest, the web UI lint and build, and vitest. Wait for green.
- A maintainer reviews and merges.
Ruff config lives in pyproject.toml. It's intentionally lenient: it catches real bugs, not style nits.
Bugs and ideas: open a GitHub issue. For help, Discord is fastest.
License
MIT. See license.txt.
If SoulSync saves you time, consider supporting it on Ko-fi.