Skip to content

Playlists

Basic usage:

Pushtunes can push playlists in multiple directions:

# From Subsonic to streaming services
pushtunes push playlist --from subsonic --playlist-name=myplaylist --to spotify
pushtunes push playlist --from subsonic --playlist-name=myplaylist --to ytm
pushtunes push playlist --from subsonic --playlist-name=myplaylist --to tidal

# From Jellyfin to streaming services
# Note: Jellyfin requires playlist ID (multiple playlists can have same name)
pushtunes push playlist --from jellyfin --source-playlist-id "8e5d6f1d17423354e83a3c17cae758dc" --to ytm
pushtunes push playlist --from jellyfin --source-playlist-id "8e5d6f1d17423354e83a3c17cae758dc" --to tidal

# From streaming services to Subsonic/Jellyfin (NEW!)
# Note: Spotify and Jellyfin require playlist IDs
pushtunes push playlist --from spotify --source-playlist-id "37i9dQZF1DXaXB8fQg7xif" --to subsonic
pushtunes push playlist --from ytm --playlist-name "Chill Vibes" --to jellyfin

# Between streaming services
pushtunes push playlist --from spotify --source-playlist-id "37i9dQZF1DXaXB8fQg7xif" --to ytm
pushtunes push playlist --from spotify --source-playlist-id "37i9dQZF1DXaXB8fQg7xif" --to tidal
pushtunes push playlist --from jellyfin --source-playlist-id "8e5d6f1d17423354e83a3c17cae758dc" --to spotify

For more details on pushing between streaming services (Spotify ↔ YouTube Music), see Cross-Service Playlists.

Finding Playlist IDs:

Spotify:

When using Spotify as a source, you need the playlist ID. To find it:

  1. Open the playlist in Spotify (desktop or web)
  2. Click Share → Copy link to playlist
  3. The URL looks like: https://open.spotify.com/playlist/37i9dQZF1DXaXB8fQg7xif
  4. The ID is the last part: 37i9dQZF1DXaXB8fQg7xif

Or use the Spotify URI: 1. Right-click playlist → Share → Copy Spotify URI 2. The URI looks like: spotify:playlist:37i9dQZF1DXaXB8fQg7xif 3. The ID is after playlist:: 37i9dQZF1DXaXB8fQg7xif

Jellyfin:

When using Jellyfin as a source, you need the playlist ID. To find it:

  1. Open the playlist in Jellyfin web UI
  2. The URL looks like: https://jellyfin.example.com/web/index.html#!/details?id=8e5d6f1d17423354e83a3c17cae758dc
  3. The ID is the value after id=: 8e5d6f1d17423354e83a3c17cae758dc

Or via API: 1. Navigate to https://jellyfin.example.com/Users/{userId}/Items?IncludeItemTypes=Playlist 2. Find your playlist in the JSON response and copy the Id field

Let's continue with the basic cases.

Handling conflicts:

When a playlist with the same name already exists on the target service, you can control the behavior with --on-conflict:

  • abort (default): Show differences and exit without making changes

    pushtunes push playlist --from subsonic --playlist-name=chill --to ytm --on-conflict=abort
    pushtunes push playlist --from subsonic --playlist-name=chill --to tidal --on-conflict=abort
    
    This will display:

    • Number of tracks in the existing playlist vs. source
    • Tracks in common
    • Tracks that would be added
    • Tracks that would be removed
  • replace: Replace the entire playlist with tracks from source

    pushtunes push playlist --from subsonic --playlist-name=workout --to spotify --on-conflict=replace
    
    All existing tracks are removed and replaced with the source playlist.

  • append: Add only missing tracks to the existing playlist

    pushtunes push playlist --from subsonic --playlist-name=favorites --to ytm --on-conflict=append
    
    Existing tracks are preserved, new tracks are added at the end.

  • sync: Fully synchronize the playlist (add missing, remove extras)

    pushtunes push playlist --from subsonic --playlist-name=discover --to spotify --on-conflict=sync
    
    The target playlist will be made identical to the source, maintaining the same track order.

Using Target Playlist IDs (Spotify and Jellyfin)

Spotify and Jellyfin allow duplicate playlist names, which can cause conflicts. You can target a specific playlist using its ID instead of relying on name matching:

Spotify:

# First push creates the playlist - note the Playlist ID in output
pushtunes push playlist --from subsonic --playlist-name=argon --to spotify
# Output: Playlist ID: 59EkFxUZG0CnApHQIgYVUK

# Subsequent pushes using the ID
pushtunes push playlist --from subsonic --playlist-name=argon --to spotify \
  --playlist-id=59EkFxUZG0CnApHQIgYVUK --on-conflict=sync

Jellyfin:

# First push creates the playlist - note the Playlist ID in output
pushtunes push playlist --from spotify --source-playlist-id "37i9dQZF1DXaXB8fQg7xif" --to jellyfin
# Output: Playlist ID: 8e5d6f1d17423354e83a3c17cae758dc

# Subsequent pushes using the ID
pushtunes push playlist --from spotify --source-playlist-id "37i9dQZF1DXaXB8fQg7xif" --to jellyfin \
  --playlist-id=8e5d6f1d17423354e83a3c17cae758dc --on-conflict=sync

You can find playlist IDs in the web player URL or from the previous push output.

Verbose output:

Use -v or --verbose to see detailed track matching results and conflict information:

pushtunes push playlist --from subsonic --playlist-name=jazz --to spotify -v

Reverse Direction: Streaming Services → Subsonic/Jellyfin

Pushing playlists from Spotify or YouTube Music to Subsonic or Jellyfin works the same way, but uses in-memory fuzzy matching to find tracks on your local server:

# Push from Spotify to Subsonic
pushtunes push playlist --from spotify --playlist-name "My Mix" --to subsonic

# Push from YouTube Music to Jellyfin
pushtunes push playlist --from ytm --playlist-name "Workout Mix" --to jellyfin

How it works:

  1. Pushtunes loads your entire Subsonic/Jellyfin music library into memory (cached for 1 hour)
  2. For each track in the source playlist, it uses fuzzy similarity matching to find the best match
  3. Only tracks that exist in your library can be added (reported as errors if not found)
  4. You can use mappings files to manually specify how tracks should be matched

Example with conflict resolution:

# Sync a Spotify playlist to Subsonic, replacing any existing playlist
pushtunes push playlist \
  --from spotify \
  --playlist-name "Favorites" \
  --to subsonic \
  --on-conflict=sync

Using mappings for better matching:

If some tracks can't be found automatically, use a mappings file:

pushtunes push playlist \
  --from spotify \
  --playlist-name "My Mix" \
  --to subsonic \
  --mappings-file mappings.csv

See the Mappings documentation for details on the new subsonic_artist, subsonic_title, and subsonic_album columns, or download mappings_complete_example.csv as a starting template.

See also