Spotify Skills for Claude - Complete User Guide
October 22, 2025 ยท View on GitHub
Production Spotify API integration for Claude Desktop
Table of Contents
- Overview
- Prerequisites
- Installation & Setup
- Authentication
- Basic Usage
- Playlist Management
- Intelligent Playlist Creation
- Cover Art Generation ๐
- Search & Discovery
- Playback Control
- User Library Management
- Advanced Features
- Troubleshooting
- API Reference
Overview
Spotify Skills for Claude provides a production-ready Spotify API integration for Claude Desktop. This skill enables you to interact with Spotify programmatically through Python.
This skill provides:
- โ Complete Spotify API access - 40+ methods covering all major operations
- โ OAuth 2.0 authentication - Secure, automatic token refresh
- โ ๐จ Cover Art Generation - Create custom playlist cover images (UNIQUE: Claude cannot generate images natively!)
- โ Intelligent playlist creation - 5 different creation strategies
- โ Search & discovery - Find tracks, artists, albums, playlists
- โ Playback control - Control what's playing on your devices
- โ Library management - Manage saved tracks and playlists
What You Can Do
- Create playlists from artist names, themes, moods, or song lists
- Search for music across Spotify's entire catalog
- Control playback on any Spotify-connected device
- Access your listening history and top items
- Get personalized recommendations
- Manage your music library
Prerequisites
Prerequisites
Required
- Python 3.7+ installed on your system
- Spotify Account (Free or Premium)
- Premium required for playback control features
- Free account works for playlist management and search
- Network Access (for Claude Desktop) โ ๏ธ IMPORTANT
- Settings โ Developer โ "Allow network egress" must be ON
- Domain allowlist set to "All domains"
- Required for the skill to reach api.spotify.com
- Spotify Developer App credentials
- Internet connection for API access
Python Dependencies
pip install requests
That's it! The skill only requires the requests library for HTTP operations.
Installation & Setup
Step 0: Enable Network Access (Claude Desktop Only)
โ ๏ธ CRITICAL FOR CLAUDE DESKTOP USERS
If using this skill in Claude Desktop, you MUST enable network egress first:
- Open Claude Desktop
- Navigate to Settings โ Developer
- Toggle "Allow network egress" to ON (the toggle should be blue)
- Set "Domain allowlist" to either:
- "All domains" (easiest - shown in screenshot), OR
- "Specified domains" and add
api.spotify.com(more secure - restricts to Spotify only)
Why is this required?
- The skill needs to make HTTP requests to
api.spotify.com - Without network egress enabled, all API calls will fail
- This is a security feature that must be explicitly enabled
Verification:
- The toggle should be blue/ON
- For "All domains": "Claude can access all domains on the internet" message appears
- For "Specified domains":
api.spotify.comis listed
Step 1: Create Spotify Developer App
- Go to https://developer.spotify.com/dashboard
- Log in with your Spotify account
- Click "Create app"
- Fill in the details:
- App name: Choose any name (e.g., "My Playlist Manager")
- App description: Brief description (e.g., "Python playlist automation")
- Redirect URI:
http://localhost:8888/callback
- Check the box to agree to terms
- Click "Save"
- On your app's page, click "Settings"
- Copy your Client ID and Client Secret
Step 2: Set Environment Variables
Windows (PowerShell):
$env:SPOTIFY_CLIENT_ID = "your_client_id_here"
$env:SPOTIFY_CLIENT_SECRET = "your_client_secret_here"
$env:SPOTIFY_REDIRECT_URI = "http://localhost:8888/callback"
macOS/Linux (Bash):
export SPOTIFY_CLIENT_ID="your_client_id_here"
export SPOTIFY_CLIENT_SECRET="your_client_secret_here"
export SPOTIFY_REDIRECT_URI="http://localhost:8888/callback"
Permanent Setup (Optional):
Add these to your shell profile (~/.bashrc, ~/.zshrc, or PowerShell profile):
export SPOTIFY_CLIENT_ID="your_client_id_here"
export SPOTIFY_CLIENT_SECRET="your_client_secret_here"
export SPOTIFY_REDIRECT_URI="http://localhost:8888/callback"
export SPOTIFY_REFRESH_TOKEN="your_refresh_token_here" # After initial auth
Step 3: Install the Skill
Copy the spotify-api folder to your project or Python path:
# Option 1: Copy to your project
cp -r spotify-api/scripts /your/project/path/
# Option 2: Add to Python path
export PYTHONPATH="${PYTHONPATH}:/path/to/spotify-api/scripts"
Authentication
Initial Authentication (One-Time Setup)
Run this code once to get your refresh token:
import os
import webbrowser
from spotify_client import SpotifyClient
# Initialize client
client = SpotifyClient(
client_id=os.getenv("SPOTIFY_CLIENT_ID"),
client_secret=os.getenv("SPOTIFY_CLIENT_SECRET"),
redirect_uri=os.getenv("SPOTIFY_REDIRECT_URI")
)
# Get authorization URL
auth_url = client.get_authorization_url()
print(f"Opening browser for authorization...")
print(f"If browser doesn't open, visit: {auth_url}")
webbrowser.open(auth_url)
# After authorizing, you'll be redirected to:
# http://localhost:8888/callback?code=XXXXXXX
auth_code = input("Paste the 'code' parameter from the URL: ")
# Exchange code for tokens
token_data = client.get_access_token(auth_code)
print(f"\nโ
Authentication successful!")
print(f"Refresh Token: {token_data['refresh_token']}")
print(f"\nSave this refresh token in your environment variables:")
print(f"export SPOTIFY_REFRESH_TOKEN=\"{token_data['refresh_token']}\"")
Using Refresh Token (Recommended)
After initial setup, use your refresh token for automatic authentication:
import os
from spotify_client import SpotifyClient
client = SpotifyClient(
client_id=os.getenv("SPOTIFY_CLIENT_ID"),
client_secret=os.getenv("SPOTIFY_CLIENT_SECRET"),
redirect_uri=os.getenv("SPOTIFY_REDIRECT_URI"),
refresh_token=os.getenv("SPOTIFY_REFRESH_TOKEN")
)
# Token refreshes automatically when needed
Required Scopes
The skill requests these permissions:
playlist-modify-public- Create/edit public playlistsplaylist-modify-private- Create/edit private playlistsuser-library-read- Read saved tracksuser-library-modify- Save/remove tracksuser-read-private- Read user profileuser-read-email- Read emailuser-top-read- Read top tracks/artistsuser-read-currently-playing- See what's playinguser-modify-playback-state- Control playback (Premium only)user-read-playback-state- Read playback state
Basic Usage
Initialize Client
import os
from spotify_client import SpotifyClient
# Create client
client = SpotifyClient(
client_id=os.getenv("SPOTIFY_CLIENT_ID"),
client_secret=os.getenv("SPOTIFY_CLIENT_SECRET"),
redirect_uri=os.getenv("SPOTIFY_REDIRECT_URI"),
refresh_token=os.getenv("SPOTIFY_REFRESH_TOKEN")
)
# Tokens refresh automatically - you're ready to go!
Get Your Profile
profile = client.get_current_user()
print(f"๐ค Logged in as: {profile['display_name']}")
print(f"๐ง Email: {profile['email']}")
print(f"๐ฅ Followers: {profile['followers']['total']}")
List Your Playlists
# List first 50 playlists
playlists = client.get_user_playlists(limit=50)
for playlist in playlists:
print(f"๐ {playlist['name']}")
print(f" Tracks: {playlist['tracks']['total']}")
print(f" Public: {playlist['public']}")
print()
# To list ALL playlists (if you have more than 50), use pagination:
all_playlists = []
offset = 0
limit = 50
while True:
batch = client.get_user_playlists(limit=limit, offset=offset)
if not batch:
break
all_playlists.extend(batch)
offset += limit
print(f"Total playlists: {len(all_playlists)}")
Playlist Management
Create a Playlist
playlist = client.create_playlist(
name="My New Playlist",
description="Created with Spotify API",
public=True # Set False for private
)
print(f"โ
Created: {playlist['name']}")
print(f"๐ URL: {playlist['external_urls']['spotify']}")
Update Playlist Details
client.update_playlist(
playlist_id="playlist_id_here",
name="Updated Playlist Name",
description="New description",
public=False # Make it private
)
Add Tracks to Playlist
# Add tracks by ID
track_ids = ["track_id_1", "track_id_2", "track_id_3"]
client.add_tracks_to_playlist(
playlist_id="playlist_id_here",
track_ids=track_ids
)
# Add at specific position
client.add_tracks_to_playlist(
playlist_id="playlist_id_here",
track_ids=track_ids,
position=0 # Add at the beginning
)
Remove Tracks from Playlist
track_ids_to_remove = ["track_id_1", "track_id_2"]
client.remove_tracks_from_playlist(
playlist_id="playlist_id_here",
track_ids=track_ids_to_remove
)
Get Playlist Tracks
tracks = client.get_playlist_tracks(
playlist_id="playlist_id_here",
limit=50,
offset=0
)
for item in tracks:
track = item['track']
print(f"๐ต {track['name']} - {track['artists'][0]['name']}")
Delete (Unfollow) Playlist
client.delete_playlist(playlist_id="playlist_id_here")
Intelligent Playlist Creation
The PlaylistCreator class provides high-level methods for creating playlists intelligently.
Setup
from playlist_creator import PlaylistCreator
from spotify_client import SpotifyClient
import os
client = SpotifyClient(
client_id=os.getenv("SPOTIFY_CLIENT_ID"),
client_secret=os.getenv("SPOTIFY_CLIENT_SECRET"),
redirect_uri=os.getenv("SPOTIFY_REDIRECT_URI"),
refresh_token=os.getenv("SPOTIFY_REFRESH_TOKEN")
)
creator = PlaylistCreator(client)
Method 1: Create from Artist
Build a playlist from an artist's top tracks:
result = creator.create_from_artist(
artist_name="Taylor Swift",
playlist_name="Taylor Swift Essentials", # Optional
playlist_description="Top tracks from Taylor Swift",
public=True,
limit=50
)
print(f"โ
Created '{result['playlist']['name']}'")
print(f"๐ต Added {result['tracks_added']} tracks")
print(f"๐ค Artist: {result['artist']}")
Method 2: Create from Theme/Mood
Build a playlist based on mood or genre keywords:
result = creator.create_from_theme(
theme_keywords=["chill", "indie", "acoustic"],
playlist_name="Chill Indie Vibes",
playlist_description="Relaxing indie acoustic music",
public=True,
limit=100
)
print(f"โ
Created '{result['playlist']['name']}'")
print(f"๐ต Added {result['tracks_added']} tracks")
print(f"๐ท๏ธ Keywords: {', '.join(result['keywords'])}")
Advanced Theme Queries:
# Combine genre and year
result = creator.create_from_theme(
theme_keywords=["genre:indie year:2020-2024"],
playlist_name="Recent Indie Hits"
)
# Mood-based
result = creator.create_from_theme(
theme_keywords=["mood:happy", "mood:energetic"],
playlist_name="Good Vibes Only"
)
# Multiple attributes
result = creator.create_from_theme(
theme_keywords=["genre:electronic mood:chill tempo:slow"],
playlist_name="Chill Electronic"
)
Method 3: Create from Lyrics
Search for tracks with specific lyrical themes:
result = creator.create_from_lyrics(
lyric_keywords=["love", "heartbreak", "summer"],
playlist_name="Love & Summer",
playlist_description="Songs about love and summer",
public=True,
limit=80
)
print(f"โ
Created '{result['playlist']['name']}'")
print(f"๐ต Added {result['tracks_added']} tracks")
Method 4: Create from Song List
Build a playlist from specific song names:
song_list = [
"Shape of You - Ed Sheeran",
"Blinding Lights - The Weeknd",
"As It Was - Harry Styles",
"Anti-Hero - Taylor Swift",
"Flowers - Miley Cyrus"
]
result = creator.create_from_song_list(
song_list=song_list,
playlist_name="My Favorites 2023",
playlist_description="Personal favorites",
public=False
)
print(f"โ
Created '{result['playlist']['name']}'")
print(f"๐ต Found {result['tracks_found']} tracks")
if result['not_found_songs']:
print(f"โ ๏ธ Could not find: {', '.join(result['not_found_songs'])}")
Method 5: Create from Recommendations
Get AI-powered recommendations and create a playlist:
# First, get some seed tracks or artists
top_tracks = client.get_top_items(item_type="tracks", limit=5)
seed_track_ids = [t['id'] for t in top_tracks[:2]]
# Create playlist from recommendations
result = creator.create_from_recommendations(
playlist_name="Discover Weekly (Custom)",
seed_tracks=seed_track_ids,
seed_genres=["indie", "alternative"],
playlist_description="Personalized recommendations",
public=True,
limit=50
)
print(f"โ
Created '{result['playlist']['name']}'")
print(f"๐ต Added {result['tracks_added']} tracks")
Get Playlist Statistics
stats = creator.get_playlist_stats(playlist_id="playlist_id_here")
print(f"๐ Playlist: {stats['name']}")
print(f"๐ต Total Tracks: {stats['total_tracks']}")
print(f"โฑ๏ธ Duration: {stats['total_duration_minutes']} minutes")
print(f"๐ค Owner: {stats['owner']}")
print(f"๐ฅ Followers: {stats['followers']}")
print(f"๐ Public: {stats['public']}")
Cover Art Generation
โก UNIQUE CAPABILITY: This skill can generate images - something Claude cannot do natively! It creates custom SVG-based cover art and converts them to PNG images.
Overview
The CoverArtGenerator class enables you to create professional, thumbnail-optimized cover art for your Spotify playlists with:
- Automatic text wrapping for long playlist titles
- 20+ mood themes (summer, chill, energetic, romantic, nostalgic, etc.)
- 15+ genre color schemes (rock, jazz, electronic, blues, indie, etc.)
- 10 artist-specific moods (Beatles, Queen, Pink Floyd, Nirvana, etc.)
- Large typography (60-96px fonts) optimized for thumbnail readability
- WCAG 2.1 compliant - High contrast ratios for accessibility
- SVG โ PNG conversion with automatic optimization
Prerequisites
Required Spotify Scope: ugc-image-upload
To upload cover art to Spotify, you must have this scope enabled:
# Re-run OAuth with the ugc-image-upload scope
python get_refresh_token.py
# This will include the ugc-image-upload scope automatically
Required Python Libraries:
pip install cairosvg pillow
Setup
from cover_art_generator import CoverArtGenerator
from spotify_client import SpotifyClient
import os
# Initialize Spotify client
client = SpotifyClient(
client_id=os.getenv("SPOTIFY_CLIENT_ID"),
client_secret=os.getenv("SPOTIFY_CLIENT_SECRET"),
redirect_uri=os.getenv("SPOTIFY_REDIRECT_URI"),
refresh_token=os.getenv("SPOTIFY_REFRESH_TOKEN")
)
# Initialize cover art generator
art_gen = CoverArtGenerator(
client_id=os.getenv("SPOTIFY_CLIENT_ID"),
client_secret=os.getenv("SPOTIFY_CLIENT_SECRET"),
access_token=client.access_token
)
Theme-Based Cover Art
Create cover art using one of 20+ preset mood themes:
# Create and upload in one step
art_gen.create_and_upload_cover(
playlist_id="your_playlist_id",
title="Summer Vibes",
subtitle="2024",
theme="summer" # Auto-selects warm, vibrant colors
)
# Available themes:
# summer, chill, energetic, dark, romantic, melancholic, euphoric,
# peaceful, intense, dreamy, nostalgic, party, motivational,
# mysterious, playful, elegant, rebellious, serene, vibrant, cozy
Genre-Based Cover Art
Use genre-specific color schemes:
art_gen.create_and_upload_cover(
playlist_id="your_playlist_id",
title="Rock Classics",
subtitle="Best of the 70s",
genre="rock" # Red/black rock aesthetic
)
# Available genres:
# rock, pop, jazz, classical, electronic, hip-hop, country,
# indie, metal, r&b, blues, folk, reggae, punk, soul
Artist-Specific Cover Art
Preset colors for popular artists:
art_gen.create_and_upload_cover(
playlist_id="your_playlist_id",
title="Best of Queen",
subtitle="The Greatest Hits",
artist="queen" # Regal gold/burgundy palette
)
# Available artists:
# beatles, pinkfloyd, radiohead, queen, nirvana, davidbowie,
# ledzeppelin, acdc, therollingstones, fleetwoodmac
Custom Color Schemes
Create your own color combinations:
art_gen.generate_cover_art(
title="My Custom Playlist",
subtitle="Personal Mix",
background_color="#1a1a2e", # Dark blue
text_color="#eee", # Light gray
accent_color="#16213e", # Accent blue
output_path="my_cover.png"
)
# Then upload separately
art_gen.upload_cover_art("playlist_id", "my_cover.png")
Complete Workflow: Playlist + Cover Art
from spotify_client import SpotifyClient
from cover_art_generator import CoverArtGenerator
from playlist_creator import PlaylistCreator
# Initialize
client = SpotifyClient(...)
creator = PlaylistCreator(client)
art_gen = CoverArtGenerator(...)
# 1. Create playlist
result = creator.create_from_artist(
artist_name="Queen",
playlist_name="Queen Collection",
limit=50
)
playlist_id = result['playlist']['id']
# 2. Generate and upload cover art
art_gen.create_and_upload_cover(
playlist_id=playlist_id,
title="Queen Collection",
subtitle="50 Essential Tracks",
artist="queen"
)
print(f"โ
Created playlist with custom cover art!")
Testing Cover Art Locally
Generate cover art without uploading:
# Generate to file
art_gen.generate_cover_art(
title="Test Playlist",
subtitle="2024",
theme="chill",
output_path="test_cover.png"
)
print("โ
Generated test_cover.png")
# Test multiple designs
test_designs = [
("Summer Mix", "summer"),
("Rock Anthems", "rock"),
("Chill Vibes", "chill")
]
for title, theme in test_designs:
art_gen.generate_cover_art(
title=title,
theme=theme,
output_path=f"test_{theme}.png"
)
Text Wrapping for Long Titles
Long playlist titles automatically wrap at word boundaries:
# This long title will automatically wrap across multiple lines
art_gen.create_and_upload_cover(
playlist_id="your_playlist_id",
title="My Ultimate Workout Power Hour Playlist", # Wraps intelligently
subtitle="High Energy Mix",
theme="energetic"
)
Best Practices for LLMs
When requesting cover art generation through Claude or other LLMs, the skill includes comprehensive guidance. See spotify-api/references/COVER_ART_LLM_GUIDE.md for:
- Step-by-step execution process
- Handling vague requests (asking clarifying questions)
- Edge case handling (long titles, special characters, non-English)
- Animation implementation (optional)
- Accessibility compliance (WCAG 2.1)
- Error recovery strategies
- Quality assurance protocols
Troubleshooting Cover Art
401 Error: Missing Scope
# Error: 401 Unauthorized when uploading
# Solution: Re-run OAuth with ugc-image-upload scope
python get_refresh_token.py
# Update .env with new refresh token
Import Error: cairosvg/PIL
# Error: No module named 'cairosvg' or 'PIL'
# Solution: Install dependencies
pip install cairosvg pillow
Long Titles Cut Off
# The text wrapping is automatic, but you can also:
# 1. Use shorter titles
# 2. Abbreviate common words ("and" โ "&", "The" โ "THE")
# 3. Split into title and subtitle
art_gen.create_and_upload_cover(
title="Best Rock Music", # Main title (shorter)
subtitle="From the 80s", # Additional context
theme="rock"
)
For detailed troubleshooting, see spotify-api/COVER_ART_TROUBLESHOOTING.md.
Search & Discovery
Search for Tracks
# Simple search
tracks = client.search_tracks(query="love", limit=20)
for track in tracks:
artist = track['artists'][0]['name']
print(f"๐ต {track['name']} - {artist}")
# Advanced search with filters
tracks = client.search_tracks(query="artist:Beatles year:1960-1970", limit=50)
Search for Artists
artists = client.search_artists(query="Taylor Swift", limit=10)
for artist in artists:
print(f"๐ค {artist['name']}")
print(f" Popularity: {artist['popularity']}/100")
print(f" Followers: {artist['followers']['total']:,}")
Search for Albums
albums = client.search_albums(query="Dark Side of the Moon", limit=10)
for album in albums:
print(f"๐ฟ {album['name']} - {album['artists'][0]['name']}")
print(f" Released: {album['release_date']}")
Search for Playlists
playlists = client.search_playlists(query="workout motivation", limit=20)
for playlist in playlists:
print(f"๐ {playlist['name']}")
print(f" Tracks: {playlist['tracks']['total']}")
print(f" By: {playlist['owner']['display_name']}")
Multi-Type Search
results = client.search(
query="jazz",
types=["track", "artist", "album", "playlist"],
limit=10
)
print("Tracks:", len(results.get('tracks', {}).get('items', [])))
print("Artists:", len(results.get('artists', {}).get('items', [])))
print("Albums:", len(results.get('albums', {}).get('items', [])))
print("Playlists:", len(results.get('playlists', {}).get('items', [])))
Get Recommendations
# Get recommendations based on seeds
recommendations = client.get_recommendations(
seed_artists=["artist_id_1"],
seed_tracks=["track_id_1"],
seed_genres=["indie", "alternative"],
limit=50
)
for track in recommendations:
print(f"๐ต {track['name']} - {track['artists'][0]['name']}")
# Get available genres for seeds
genres = client.get_available_genres()
print(f"Available genres: {', '.join(genres[:20])}...")
Get Artist Information
# Get artist details
artist = client.get_artist(artist_id="artist_id_here")
print(f"๐ค {artist['name']}")
print(f"๐ญ Genres: {', '.join(artist['genres'])}")
print(f"โญ Popularity: {artist['popularity']}/100")
# Get artist's top tracks
top_tracks = client.get_artist_top_tracks(artist_id="artist_id_here")
for track in top_tracks[:10]:
print(f"๐ต {track['name']}")
# Get related artists
related = client.get_related_artists(artist_id="artist_id_here", limit=10)
for artist in related:
print(f"๐ค {artist['name']}")
# Get artist's albums
albums = client.get_artist_albums(artist_id="artist_id_here", limit=50)
for album in albums:
print(f"๐ฟ {album['name']} ({album['release_date']})")
Playback Control
Note: Playback control features require Spotify Premium.
Get Available Devices
devices = client.get_available_devices()
for device in devices:
print(f"๐ {device['name']} ({device['type']})")
print(f" Active: {device['is_active']}")
print(f" Volume: {device['volume_percent']}%")
print(f" ID: {device['id']}")
Get Currently Playing
current = client.get_currently_playing()
if current and 'item' in current:
track = current['item']
artist = track['artists'][0]['name']
print(f"๐ต Now Playing: {track['name']} - {artist}")
print(f"โฑ๏ธ Progress: {current['progress_ms'] // 1000}s / {track['duration_ms'] // 1000}s")
print(f"๐ Shuffle: {current['shuffle_state']}")
print(f"๐ Repeat: {current['repeat_state']}")
else:
print("Nothing is currently playing")
Start Playback
# Play specific tracks
track_uris = [
"spotify:track:track_id_1",
"spotify:track:track_id_2"
]
client.start_playback(
device_id="device_id_here", # Optional
track_uris=track_uris
)
# Play from a playlist/album (context)
client.start_playback(
device_id="device_id_here",
context_uri="spotify:playlist:playlist_id_here",
offset=0 # Start from first track
)
Pause Playback
client.pause_playback(device_id="device_id_here") # device_id optional
Skip Tracks
# Next track
client.next_track(device_id="device_id_here")
# Previous track
client.previous_track(device_id="device_id_here")
Seek to Position
# Seek to 1 minute 30 seconds (90000 milliseconds)
client.seek_to_position(position_ms=90000, device_id="device_id_here")
Control Repeat Mode
# Options: "off", "context" (playlist/album), "track"
client.set_repeat_mode(state="context", device_id="device_id_here")
Control Shuffle
# Enable shuffle
client.set_shuffle(state=True, device_id="device_id_here")
# Disable shuffle
client.set_shuffle(state=False, device_id="device_id_here")
Set Volume
# Set volume to 50%
client.set_volume(volume_percent=50, device_id="device_id_here")
User Library Management
Get Saved Tracks
saved = client.get_saved_tracks(limit=50, offset=0)
for item in saved:
track = item['track']
print(f"๐ {track['name']} - {track['artists'][0]['name']}")
print(f" Added: {item['added_at']}")
Save Tracks
track_ids = ["track_id_1", "track_id_2", "track_id_3"]
client.save_tracks(track_ids)
print("โ
Tracks saved to library")
Remove Saved Tracks
track_ids = ["track_id_1", "track_id_2"]
client.remove_saved_tracks(track_ids)
print("๐๏ธ Tracks removed from library")
Check if Tracks Are Saved
track_ids = ["track_id_1", "track_id_2", "track_id_3"]
saved_status = client.check_saved_tracks(track_ids)
for track_id, is_saved in zip(track_ids, saved_status):
status = "๐ Saved" if is_saved else "โ Not saved"
print(f"{track_id}: {status}")
Get Top Tracks
# Time ranges: "short_term" (4 weeks), "medium_term" (6 months), "long_term" (all time)
top_tracks = client.get_top_items(
item_type="tracks",
limit=50,
time_range="medium_term"
)
for i, track in enumerate(top_tracks, 1):
print(f"{i}. ๐ต {track['name']} - {track['artists'][0]['name']}")
Get Top Artists
top_artists = client.get_top_items(
item_type="artists",
limit=50,
time_range="long_term"
)
for i, artist in enumerate(top_artists, 1):
print(f"{i}. ๐ค {artist['name']}")
print(f" Genres: {', '.join(artist['genres'][:3])}")
Advanced Features
Get Track Details
track = client.get_track(track_id="track_id_here")
print(f"๐ต {track['name']}")
print(f"๐ค Artist: {track['artists'][0]['name']}")
print(f"๐ฟ Album: {track['album']['name']}")
print(f"โฑ๏ธ Duration: {track['duration_ms'] // 1000}s")
print(f"โญ Popularity: {track['popularity']}/100")
print(f"๐ URL: {track['external_urls']['spotify']}")
Get Multiple Tracks
track_ids = ["track_id_1", "track_id_2", "track_id_3"]
tracks = client.get_tracks(track_ids)
for track in tracks:
print(f"๐ต {track['name']} - {track['artists'][0]['name']}")
Get Audio Features
features = client.get_track_audio_features(track_id="track_id_here")
print(f"๐น Key: {features['key']}")
print(f"๐ผ Mode: {features['mode']}")
print(f"โฑ๏ธ Tempo: {features['tempo']} BPM")
print(f"๐ Loudness: {features['loudness']} dB")
print(f"๐ญ Energy: {features['energy']}")
print(f"๐ Danceability: {features['danceability']}")
print(f"๐บ Instrumentalness: {features['instrumentalness']}")
print(f"๐ Valence (happiness): {features['valence']}")
Get Album Information
album = client.get_album(album_id="album_id_here")
print(f"๐ฟ {album['name']}")
print(f"๐ค Artist: {album['artists'][0]['name']}")
print(f"๐
Released: {album['release_date']}")
print(f"๐ต Tracks: {album['total_tracks']}")
print(f"๐ญ Genres: {', '.join(album['genres']) if album['genres'] else 'N/A'}")
# Get album tracks
tracks = client.get_album_tracks(album_id="album_id_here")
for track in tracks:
print(f" {track['track_number']}. {track['name']}")
Pagination Example
# Get all user playlists (handling pagination)
all_playlists = []
offset = 0
limit = 50
while True:
batch = client.get_user_playlists(limit=limit, offset=offset)
if not batch:
break
all_playlists.extend(batch)
offset += limit
if len(batch) < limit:
break
print(f"Total playlists: {len(all_playlists)}")
Troubleshooting
Common Issues
"No module named 'spotify_client'"
Solution: Ensure you're in the correct directory or add to Python path:
import sys
sys.path.append('/path/to/spotify-api/scripts')
"Invalid client_id or client_secret"
Solutions:
- Verify credentials in Spotify Dashboard
- Check environment variables are set correctly:
import os print(os.getenv("SPOTIFY_CLIENT_ID")) - Ensure no extra spaces or quotes in credentials
"Token expired" or "Unauthorized"
Solutions:
- Refresh your token:
client.refresh_access_token() - Check your refresh token is valid
- Re-authenticate if refresh token is invalid
"429 Rate Limit Exceeded"
Solutions:
- Add delays between requests:
import time time.sleep(1) # Wait 1 second - Use batch operations when possible (up to 50-100 items)
- Implement exponential backoff for retries
"No active device found"
Solutions:
- Open Spotify on any device (phone, desktop, web player)
- Start playing something briefly
- Check available devices:
devices = client.get_available_devices() print(devices)
"Premium required" for playback control
Solution: Playback control features require Spotify Premium. Playlist management and search work with free accounts.
Debugging Tips
Enable verbose logging:
import logging
logging.basicConfig(level=logging.DEBUG)
Check API response:
try:
result = client.get_user_playlists()
except Exception as e:
print(f"Error: {e}")
import traceback
traceback.print_exc()
Verify token status:
import time
if client.token_expires_at:
remaining = client.token_expires_at - time.time()
print(f"Token expires in {remaining:.0f} seconds")
API Reference
SpotifyClient Methods
Authentication
get_authorization_url(scope)- Generate OAuth URLget_access_token(auth_code)- Exchange code for tokenrefresh_access_token(refresh_token)- Refresh expired token
Playlists
get_user_playlists(limit, offset)- List user's playlistscreate_playlist(name, description, public)- Create new playlistget_playlist(playlist_id)- Get playlist detailsupdate_playlist(playlist_id, name, description, public)- Update playlistdelete_playlist(playlist_id)- Unfollow playlistget_playlist_tracks(playlist_id, limit, offset)- Get tracksadd_tracks_to_playlist(playlist_id, track_ids, position)- Add tracksremove_tracks_from_playlist(playlist_id, track_ids)- Remove tracks
Search
search_tracks(query, limit)- Search trackssearch_artists(query, limit)- Search artistssearch_albums(query, limit)- Search albumssearch_playlists(query, limit)- Search playlistssearch(query, types, limit)- Multi-type search
Artists
get_artist(artist_id)- Get artist detailsget_artist_top_tracks(artist_id, market)- Artist's top tracks (returns up to 10)get_related_artists(artist_id, limit)- Related artistsget_artist_albums(artist_id, limit, offset)- Artist's albums
Tracks
get_track(track_id)- Get track detailsget_tracks(track_ids)- Get multiple tracksget_track_audio_features(track_id)- Audio features
Albums
get_album(album_id)- Get album detailsget_album_tracks(album_id, limit, offset)- Album tracks
User
get_current_user()- Current user profileget_user(user_id)- User profile by IDget_top_items(item_type, limit, offset, time_range)- Top tracks/artists
Library
get_saved_tracks(limit, offset)- Saved trackssave_tracks(track_ids)- Save tracksremove_saved_tracks(track_ids)- Remove saved trackscheck_saved_tracks(track_ids)- Check if saved
Recommendations
get_recommendations(seed_artists, seed_tracks, seed_genres, limit)- Get recommendationsget_available_genres()- Available genre seeds
Playback (Premium only)
get_currently_playing()- Currently playing trackget_available_devices()- Available devicesstart_playback(device_id, context_uri, track_uris, offset)- Start playbackpause_playback(device_id)- Pausenext_track(device_id)- Next trackprevious_track(device_id)- Previous trackseek_to_position(position_ms, device_id)- Seekset_repeat_mode(state, device_id)- Set repeatset_shuffle(state, device_id)- Set shuffleset_volume(volume_percent, device_id)- Set volume
PlaylistCreator Methods
create_from_artist(artist_name, playlist_name, playlist_description, public, limit)- Create from artistcreate_from_theme(theme_keywords, playlist_name, playlist_description, public, limit)- Create from themecreate_from_lyrics(lyric_keywords, playlist_name, playlist_description, public, limit)- Create from lyricscreate_from_song_list(song_list, playlist_name, playlist_description, public)- Create from song listcreate_from_recommendations(playlist_name, seed_artists, seed_tracks, seed_genres, playlist_description, public, limit)- Create from recommendationsget_playlist_stats(playlist_id)- Get playlist statistics
Rate Limits & Best Practices
Spotify API Limits
- Rate Limit: ~180 requests per minute per user
- Batch Limits:
- 50 tracks per search request
- 100 tracks per playlist add/remove
- 50 items for most bulk operations
- Total Seeds: Max 5 (artists + tracks + genres combined)
Best Practices
- Use batch operations when possible
- Implement retry logic with exponential backoff
- Cache results when appropriate
- Handle pagination for large result sets
- Store refresh token securely (never commit to git)
- Use environment variables for credentials
- Check token expiry before long-running operations
Additional Resources
- Official Spotify API Docs: https://developer.spotify.com/documentation/web-api
- Authentication Guide: See
references/authentication_guide.md - API Reference: See
references/api_reference.md - Skill Creation Guide: See
Guide/SKILL_CREATION_GUIDE.md
Support & Contributing
Getting Help
- Check this user guide
- Review
references/authentication_guide.mdfor auth issues - Check
references/api_reference.mdfor API details - See
TROUBLESHOOTINGsection above
Reporting Issues
When reporting issues, include:
- Python version
- Error message and stack trace
- Code snippet that reproduces the issue
- Spotify account type (Free/Premium)
Version: 1.0 Last Updated: October 21, 2025 License: See project LICENSE file