Skip to content

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):

type,artist,artist2,artist3,album,year
album,"Apocryphos","Kammarheit","Atrium Carceri","Echo",2016

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

  1. Go to the Spotify Developer Dashboard
  2. Log in with your Spotify account
  3. Click "Create app"
  4. Fill in the details:
  5. App name: "Pushtunes" (or whatever you like)
  6. App description: "Personal music library sync tool"
  7. Redirect URIs: Add these:
    http://127.0.0.1:8080
    http://127.0.0.1:8080/callback
    http://127.0.0.1:8080/
    
  8. Click "Save"
  9. 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:

  1. Open your web browser automatically
  2. Ask you to log in to Spotify
  3. Ask you to authorize the application
  4. Redirect back to a local URL (which will fail to load - this is normal)
  5. 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:

pushtunes push albums --from csv --csv-file=test.csv --to 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:

ytmusicapi browser

Step 2: Extract Browser Headers

The exact steps depend on your browser. Here's the process for Firefox:

  1. Open your browser and go to https://music.youtube.com
  2. Log in to your YouTube Music account
  3. Click in the search field ("Search songs, albums, artists, podcasts")
  4. Open Developer Tools (press Ctrl+Shift+I or F12)
  5. Click the Network tab
  6. Type something in the search box and press Enter to perform a search
  7. In the Network tab, find the POST request named "search"
  8. Right-click on the search request
  9. Select Copy valueCopy request headers
  10. Go back to your terminal where ytmusicapi browser is waiting
  11. Paste the headers (Ctrl+V or right-click → Paste)
  12. Press Enter, then Ctrl+D to 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:

export YTM_BROWSER_JSON_PATH="/path/to/browser.json"

Otherwise, Pushtunes will look for browser.json in the current directory.

Testing YouTube Music:

pushtunes push albums --from csv --csv-file=test.csv --to ytm

Chrome/Edge Instructions:

  1. Go to https://music.youtube.com and log in
  2. Open Developer Tools (F12 or Ctrl+Shift+I)
  3. Click Network tab
  4. Search for anything in YouTube Music
  5. Find the search POST request
  6. Right-click → CopyCopy as cURL (bash)
  7. Run ytmusicapi browser
  8. Paste the cURL command
  9. 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:

  1. Display an OAuth URL in the terminal (e.g., https://link.tidal.com/XXXXX)
  2. Attempt to open the URL in your web browser automatically
  3. Ask you to log in to your Tidal account
  4. Complete the authorization (you have 5 minutes to do this)
  5. Save the session to tidal-session.json for 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:

export TIDAL_SESSION_FILE="/path/to/tidal-session.json"

Testing Tidal:

pushtunes push albums --from csv --csv-file=test.csv --to 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:

pushtunes push albums --from subsonic --to spotify -v

Dry Run

See what would be pushed without actually pushing:

pushtunes push albums --from subsonic --to spotify --dry-run

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:

pushtunes push albums --profile=myprofile.toml

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:

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:

  1. Lower the similarity threshold: --similarity=0.7
  2. Use verbose mode to see matching details: -v
  3. Create a mappings file for stubborn items (see Mappings)

Spotify Token Errors

If you get authentication errors:

  1. Delete the Spotify cache: ~/.cache/spotipy/ (Linux) or similar on other platforms
  2. Run Pushtunes again to re-authenticate

YouTube Music Token Expired

YTM tokens expire quickly. Regenerate browser.json:

ytmusicapi browser
# Follow the browser header extraction steps again

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