Getting Started¶
For installation instructions, see Installation.
Setting Up Music Sources¶
Configure at least one music source where Pushtunes will read your library from.
Subsonic / Navidrome¶
If you're using a Subsonic-compatible server (Subsonic, Navidrome, Airsonic, etc.), set these environment variables:
export SUBSONIC_URL="https://your-music.example.com"
export SUBSONIC_USER="yourusername"
export SUBSONIC_PASS="your_password"
Add these to your ~/.bashrc or ~/.zshrc to make them permanent.
Note on tracks: When using push tracks --from=subsonic, Pushtunes fetches your starred/favorite tracks from the server using the getStarred2 API endpoint.
Jellyfin¶
If you're using Jellyfin, set these environment variables:
export JELLYFIN_URL="https://jellyfin.example.com"
export JELLYFIN_USER="yourusername"
export JELLYFIN_PASS="your_password"
CSV Files¶
You can also use CSV files as a source. This is useful for:
- One-time imports
- Restoring from backups
- Custom album/track lists
CSV format:
type,artist,album,year
album,"Carbon Based Lifeforms","Interloper",2010
album,"Igorrr","Spirituality and Distortion",2020
For albums with multiple artists, use artist2, artist3, etc. (up to artist10):
Tracks in CSV:
type,artist,track,album,year
track,"Dire Straits","Sultans of Swing","Dire Straits",1978
track,"Thy Catafalque","Molekuláris Gépezetek","Róka Hasa Rádió",2009
The album and year columns data is optional for tracks. Optional service ID columns (spotify_id, ytm_id) enable exact matching without fuzzy search.
Using CSV source:
pushtunes push albums --from csv --csv-file=my_albums.csv --to spotify
pushtunes push tracks --from csv --csv-file=my_tracks.csv --to ytm
# Or for a file with mixed data
pushtunes push albums --from csv --csv-file=my_music.csv --to ytm
pushtunes push tracks --from csv --csv-file=my_music.csv --to ytm
Setting Up Streaming Services¶
Configure at least one streaming service where Pushtunes will push your music to. Of course you can skip this if you just want to push from Subsonic or Jellyfin to a CSV file, but what would be the point of that?
Spotify¶
Spotify uses OAuth authentication, which is relatively straightforward.
Step 1: Create a Spotify App
- Go to the Spotify Developer Dashboard
- Log in with your Spotify account
- Click "Create app"
- Fill in the details:
- App name: "Pushtunes" (or whatever you like)
- App description: "Personal music library sync tool"
- Redirect URIs: Add these:
- Click "Save"
- You'll see your Client ID and Client Secret (click "View client secret")
Step 2: Set Environment Variables
Set your Spotify credentials:
export SPOTIFY_CLIENT_ID="your-client-id-here"
export SPOTIFY_CLIENT_SECRET="your-client-secret-here"
Add these to your ~/.bashrc or ~/.zshrc to make them permanent.
Step 3: First Run
The first time you run Pushtunes with Spotify, it will:
- Open your web browser automatically
- Ask you to log in to Spotify
- Ask you to authorize the application
- Redirect back to a local URL (which will fail to load - this is normal)
- Ask you to paste the redirect URL into the terminal
After this one-time setup, Pushtunes will save the authorization and you won't need to do this again (unless the token expires).
Testing Spotify:
YouTube Music¶
YouTube Music authentication is more complex because Google doesn't provide a proper API. You'll need to extract authentication headers from your browser.
Token Expiration
YouTube Music tokens expire after approximately 30 minutes. You'll need to regenerate the browser.json file periodically.
Step 1: Generate Authentication File
In the same virtual environment where Pushtunes is installed, run:
Step 2: Extract Browser Headers
The exact steps depend on your browser. Here's the process for Firefox:
- Open your browser and go to https://music.youtube.com
- Log in to your YouTube Music account
- Click in the search field ("Search songs, albums, artists, podcasts")
- Open Developer Tools (press
Ctrl+Shift+IorF12) - Click the Network tab
- Type something in the search box and press Enter to perform a search
- In the Network tab, find the POST request named "search"
- Right-click on the search request
- Select Copy value → Copy request headers
- Go back to your terminal where
ytmusicapi browseris waiting - Paste the headers (Ctrl+V or right-click → Paste)
- Press Enter, then
Ctrl+Dto finish
This creates a browser.json file in your current directory with your authentication headers.
Step 3: Set Path to browser.json (Optional)
If you want to keep browser.json in a specific location:
Otherwise, Pushtunes will look for browser.json in the current directory.
Testing YouTube Music:
Chrome/Edge Instructions:
- Go to https://music.youtube.com and log in
- Open Developer Tools (
F12orCtrl+Shift+I) - Click Network tab
- Search for anything in YouTube Music
- Find the search POST request
- Right-click → Copy → Copy as cURL (bash)
- Run
ytmusicapi browser - Paste the cURL command
- Press Enter, then
Ctrl+D
Tidal¶
Tidal authentication works out of the box without needing any API credentials. The tidalapi library has built-in OAuth support.
Step 1: First Run
Simply run any Pushtunes command with Tidal. On first use, it will:
- Display an OAuth URL in the terminal (e.g.,
https://link.tidal.com/XXXXX) - Attempt to open the URL in your web browser automatically
- Ask you to log in to your Tidal account
- Complete the authorization (you have 5 minutes to do this)
- Save the session to
tidal-session.jsonfor future use
Step 2: Authenticate
When you see the OAuth URL, visit it in your browser and log in to Tidal. The authentication will complete automatically, and the session will be saved.
Subsequent Runs
After the first authentication, Pushtunes will reuse the saved session from tidal-session.json and you won't need to authenticate again until the session expires.
Optional: Custom Session File Location
By default, the session is saved to tidal-session.json in the current directory. You can specify a different location:
Testing Tidal:
Push Albums¶
# From Subsonic to Spotify
pushtunes push albums --from subsonic --to spotify
# From Jellyfin to YouTube Music
pushtunes push albums --from jellyfin --to ytm
# From CSV to Spotify
pushtunes push albums --from csv --csv-file=albums.csv --to spotify
Push Tracks¶
# From Subsonic to Spotify (starred/favorite tracks)
pushtunes push tracks --from subsonic --to spotify
# From CSV to YouTube Music
pushtunes push tracks --from csv --csv-file=tracks.csv --to ytm
Push Playlists¶
# From Subsonic to Spotify
pushtunes push playlist --from subsonic --playlist-name="My Playlist" --to spotify
# From Jellyfin to YouTube Music
pushtunes push playlist --from jellyfin --playlist-name="Favorites" --to ytm
Common Options¶
Filter Items¶
Skip items you don't want:
# Skip albums by certain artists
pushtunes push albums --from subsonic --to spotify \
--exclude="artist:'Black.*', album:'Live.*'"
See Filters for advanced examples.
Adjust Similarity Threshold¶
Control how strict the matching is (default is 0.8):
# Stricter matching (fewer false matches)
pushtunes push tracks --from subsonic --to spotify --similarity=0.9
# More lenient (catches more variations)
pushtunes push albums --from subsonic --to ytm --similarity=0.7
Verbose Output¶
See detailed matching information:
Dry Run¶
See what would be pushed without actually pushing:
Using Profiles¶
If you find yourself running the same commands repeatedly with the same options, you can save them in a profile file:
Create a profile (myprofile.toml):
[albums]
from = "subsonic"
to = "spotify"
similarity = 0.85
include = ["artist:'Volkor X'", "artist:'Opeth'"]
Use the profile:
Profiles support TOML, JSON, and YAML formats, and can contain configurations for multiple commands. See Profiles for complete documentation.
Advanced features¶
Now that you have Pushtunes set up, explore the advanced features:
- Profiles - Save reusable configuration in profile files
- Filters - Advanced filtering with includes and excludes
- Mappings - Manually map items that can't be matched automatically
- Export & CSV - Export results for analysis or retry workflows
- Cross-Service Playlists - Migrate playlists directly between streaming services
- Playlists in general - Transfer, back up and restore playlists using CSV
- Deleting Items - Safely sync libraries by removing items
For help with any command:
pushtunes --help
pushtunes push albums --help
pushtunes push tracks --help
pushtunes push playlist --help
Troubleshooting¶
"Could not find album/track X"¶
This usually means the metadata doesn't match well enough. Try:
- Lower the similarity threshold:
--similarity=0.7 - Use verbose mode to see matching details:
-v - Create a mappings file for stubborn items (see Mappings)
Spotify Token Errors¶
If you get authentication errors:
- Delete the Spotify cache:
~/.cache/spotipy/(Linux) or similar on other platforms - Run Pushtunes again to re-authenticate
YouTube Music Token Expired¶
YTM tokens expire quickly. Regenerate browser.json:
No Albums/Tracks Found in Source¶
Check your source credentials and make sure you have albums/tracks in your library:
- Subsonic: Verify you have albums in your library
- Jellyfin: Check you have music in your media library
- CSV: Ensure the CSV file exists and has the correct format