Skip to content

Latest commit

 

History

29 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Music-Sync

Move liked songs and playlists between Spotify, Tidal and CSV files.
From a web page on your own computer, or from the command line.

From \ to CSV Spotify Tidal
Spotify export transfer
Tidal export transfer
CSV import import

Music-Sync finds each track by its ISRC, or else by title, artist and length, and never takes a live version for the studio one. Running it twice does not add tracks twice. It only handles playlist data, never audio.

Installation

You need Python 3.14 or newer.

git clone https://github.com/Stensel8/Music-Sync
cd Music-Sync
python3 -m venv .venv
source .venv/bin/activate        # Windows (PowerShell): .venv\Scripts\Activate.ps1
pip install -e '.[web]'

Getting started

music-sync web

Open http://127.0.0.1:8888. For each service you have not set up yet, the page shows where to create a developer app, what to fill in and where to paste its Client ID. Then log in, and you are ready.

Spotify only works with a Premium account; Tidal and CSV work without it. See Setting up Spotify and Tidal for the details.

Usage

In the browser

The dashboard has three parts: export to CSV, import a CSV, and transfer between the services. While it works it shows each step, how far it is and how long it will still take. The tracks it could not find are listed with the reason, and can be downloaded as a CSV.

On the command line

music-sync login spotify                          # once per service
music-sync login tidal

music-sync transfer spotify tidal --sync-favorites   # liked songs, to your Tidal favourites
music-sync transfer spotify tidal --liked         # liked songs, to a new playlist
music-sync transfer spotify tidal --playlist "Road trip"
music-sync export spotify --liked -o liked.csv
music-sync export tidal --all -o backup/          # liked songs and every playlist
music-sync import tidal liked.csv --playlist "From CSV"
music-sync import tidal albums.csv --albums       # artist,album per row, to your favourite albums

music-sync status                                 # what is set up and logged in
music-sync doctor                                 # tries the real APIs
Option What it does
--dry-run Look everything up, change nothing
--unmatched FILE Save the tracks that were not found to a CSV
--min-score 0.8 How sure a match must be (0 to 1)
--to-playlist NAME The playlist to fill (transfer)
--to-favorites Add to your favourites (liked songs) instead of a playlist (import)
--albums The CSV lists albums, not tracks; add them to your favourites (import)
-q No progress output
-v (before the command) Log every API call, for a bug report

music-sync --help and music-sync transfer --help show the rest.

Setting up Spotify and Tidal

Music-Sync needs a developer app for each service, made from your own account. music-sync web walks you through it; these are the same steps.

Spotify

Important

Since February 2026 Spotify's API only works for apps whose owner has Premium. Without it every request fails with HTTP 403. Someone with Premium can make the app and add you under Settings > User Management. See Spotify's quota modes and migration guide.

  1. Create an app in the Spotify Developer Dashboard.
  2. Redirect URI: http://127.0.0.1:8888/spotify/callback (127.0.0.1, not localhost).
  3. Under Which API/SDKs are you planning to use? tick Web API only.
  4. Copy the Client ID. The client secret is not needed.

Only Web API is ticked.

Without Premium the dashboard shows this banner, and the Web API cannot be ticked:

The Spotify for Developers dashboard with the banner "Your application is blocked from accessing the Web API since you do not have a Spotify Premium subscription."

The "Create app" page on a Free account. A banner says "Upgrade to Spotify Premium to access the Web API", and the Web API option is greyed out.

Tidal

  1. Click Create New App in the TIDAL developer dashboard.
  2. Redirect URI: http://127.0.0.1:8888/tidal/callback.
  3. Scopes: collection.read, collection.write, playlists.read, playlists.write and user.read.
  4. Copy the Client ID and the Client Secret. The secret lets Music-Sync search Tidal's catalogue.

The TIDAL developer dashboard with the "Create New App" button and one app.

The Scopes panel of a TIDAL app: collection.read, collection.write, playlists.read, playlists.write and user.read.

The settings file

The first run creates it and prints where it is:

  • Linux and macOS: ~/.config/music-sync/config.toml (a hidden folder: open it by its path)
  • Windows: %APPDATA%\music-sync\config.toml

Paste what you copied between the quotes and save. There is no need to restart: Music-Sync reads the file again when it changes.

[spotify]
client_id = "..."

[tidal]
client_id = "..."
client_secret = "..."

The settings file open in a text editor, next to the music-sync folder.

country = "NL" at the top picks the Tidal catalogue; without it your system's country is used. The environment variables SPOTIFY_CLIENT_ID, TIDAL_CLIENT_ID, TIDAL_CLIENT_SECRET and MUSICSYNC_COUNTRY take priority over the file. Your logins are kept next to it in tokens.json: keep that file private.

How tracks are matched

A track that is already in the target playlist is recognised without a lookup, so a second run is quick. Any other track is found by its id on the target service (a CSV exported from it), else by its ISRC, else by searching for title and artist, and as a last resort in the tracklist of its album, as spotify_to_tidal does. Each search result gets a score from 0 to 1: half for the title, 0.4 for the artist and 0.1 for the length. From 0.8 on (--min-score) it is a match.

Remaster notes, "feat." parts, spelling and punctuation do not count. Another version does: live, remix, acoustic, instrumental, sped up, "(Taylor's Version)" and the like, and other numbers ("Part 1" is not "Part 2"). A track that is not found says why:

Reason What it means
not on Tidal Nothing by this artist came up: probably not in your country's catalogue
only other songs on Tidal The artist is there, this song is not
only another version Only a live version, remix and the like
score too low for a match (0.75, needs 0.80) Close, but not sure enough; often the length differs

CSV format

Column Contents
title Track title (the only column that is required)
artists Artists, separated by ;
album Album title
duration_ms Length in milliseconds
isrc ISRC, the most reliable way to find a track again
spotify_uri / tidal_id The track's id on that service

Files must be UTF-8. The column names of other exporters (Track Name, Artist Name(s), ...) work too, and a file without a header row is read as artist,title. With --albums each row is an album: artist,album, as csv2tidal took them.

Good to know

  • Spotify only lets apps read playlists you own or collaborate on, not the ones you follow. Music-Sync skips those, and empty playlists, and says so.
  • A transfer to Tidal is fast (20 ISRCs per request); one to Spotify takes a request per track.
  • The web interface is for one person on their own computer. It only listens on 127.0.0.1; never expose it to a network.
  • Tidal's API is young. If something fails, add the output of music-sync doctor tidal to your issue.

Development

pip install -e . --group dev
pytest
ruff check . && ruff format --check . && pyright
vulture && bandit -r musicsync -ll

CI runs the same checks, plus pip-audit.

Credits

Music-Sync started out as csv2tidal, a small script by Roland Behme (Nugman) that put a list of albums in your Tidal favourites. He took the idea from a gist by RZetko, and the login code from spotify_to_tidal by Tim Rae and its contributors, which we still borrow ideas from. All three ran on python-tidal, started by Thomas Amland and kept alive by morguldir and tehkillerbee. Sten Tijhuis merged csv2tidal with his own Music-Sync prototype into this tool. The colours of the web interface come from daisyUI.

License

AGPL-3.0, the license Roland chose for csv2tidal.

About

Import/Export tool for Spotify, Tidal and CSV.

Resources

Stars

5 stars

Watchers

0 watching

Forks

Used by

Contributors

Languages