Spotify’s Liked Songs collection has an annoying limitation: it isn’t a real playlist. You can’t share it, you can’t reorder it into something public, and there’s no one-click export. If your account ever gets locked or you migrate to another service, those years of curation are stuck. Personally, I hated that for so long. But lately, I asked AI if it can help.
In this post, we’ll walk through a small Python script generated by AI (Claude Code) that copies every liked song into a normal playlist — in my case, 1,129 tracks in under a minute — and the undocumented Spotify API restriction that almost derailed it.

Why bother? A few use cases
- Backup / insurance — playlists survive in shared links and can be re-followed; Liked Songs cannot.
- Sharing — turn your entire taste profile into a link you can send to friends.
- Migration — playlist-transfer tools (TuneMyMusic, Soundiiz, etc.) work far better with playlists than with your library.
- Snapshots — run it once a year and you get dated snapshots of your music taste over time.
- Smart playlist source — a real playlist can be fed into other tools, sorted, deduplicated, or split by genre.
Prerequisites
- Python 3.8+ installed
- Two libraries:
spotipy(the de-facto Spotify Web API client) andtqdm(progress bar) - A free Spotify Developer app for API credentials
pip install spotipy tqdmStep 1: Create a Spotify app
Head to the Spotify Developer Dashboard, log in with your normal Spotify account, and click Create app. Two things matter:
- Set the Redirect URI to
http://127.0.0.1:8888/callback— the script spins up a tiny local server on that port to catch the OAuth callback. - Copy the Client ID and Client Secret from the app’s settings page.

Step 2: The script
Save this as spotify_liked_songs_duplicator.py and drop in your own Client ID and Secret:
import spotipy
from spotipy.oauth2 import SpotifyOAuth
from tqdm import tqdm
CLIENT_ID = "YOUR_CLIENT_ID"
CLIENT_SECRET = "YOUR_CLIENT_SECRET"
REDIRECT_URI = "http://127.0.0.1:8888/callback"
SCOPE = (
"user-library-read "
"playlist-modify-private "
"playlist-modify-public"
)
sp = spotipy.Spotify(
auth_manager=SpotifyOAuth(
client_id=CLIENT_ID,
client_secret=CLIENT_SECRET,
redirect_uri=REDIRECT_URI,
scope=SCOPE,
open_browser=True,
cache_path=".spotify_cache"
)
)
print("Logged in as:", sp.current_user()["display_name"])
# POST /users/{id}/playlists returns 403 for dev-mode apps; /me/playlists works
playlist = sp._post(
"me/playlists",
payload={
"name": "Liked Songs Backup",
"public": False,
"description": "Backup of all my liked songs",
},
)
playlist_id = playlist["id"]
print("Created playlist:", playlist["external_urls"]["spotify"])
tracks = []
offset = 0
while True:
results = sp.current_user_saved_tracks(limit=50, offset=offset)
if not results["items"]:
break
tracks.extend(
item["track"]["uri"]
for item in results["items"]
if item["track"] is not None
)
offset += 50
print(f"Found {len(tracks)} liked songs")
for i in tqdm(range(0, len(tracks), 100)):
sp.playlist_add_items(
playlist_id,
tracks[i:i+100]
)
print("Backup completed successfully!")The flow is simple: authenticate via OAuth, create a private playlist, page through your library 50 tracks at a time (the API maximum), then add them to the playlist in batches of 100 (also the API maximum).
Step 3: Run it
python spotify_liked_songs_duplicator.pyOn first run a browser window opens asking you to authorize the app. After that, the token is cached in .spotify_cache and subsequent runs are fully non-interactive. Expected output:
Logged in as: imtrinity94
Created playlist: https://open.spotify.com/playlist/...
Found 1129 liked songs
100%|██████████| 12/12 [00:08<00:00]
Backup completed successfully!
Note
Re-running the script creates a new playlist each time — handy for snapshots, but delete the old one first if you just want a single backup or you can put a datetime stamp in your playlist name in the script.
Also, I know there are several tools out there, even some UI hacks but I prefer this code based approach. That’s all!
Discover more from Cloud Blogger
Subscribe to get the latest posts sent to your email.










