Skip to main content
The Spotify SDK for Python supports three authentication methods depending on your use case. Each method has different capabilities and requirements.

Authentication Methods

The SDK supports:
  • Access Token: Use a pre-obtained token directly
  • Client Credentials: Automated token management for app-only access
  • Authorization Code: User authorization with refresh token support

When to Use Each Method

Access Token

Best for:
  • Testing and development
  • Short-lived scripts
  • When you already have a valid token

Client Credentials

Best for:
  • Server-to-server applications
  • Public data access
  • No user-specific data needed

Authorization Code

Best for:
  • User-facing applications
  • Accessing user libraries
  • Long-running sessions

Access Token Authentication

The simplest method is to provide an access token directly. The SDK uses this token for all API requests without any automatic refresh.
from spotify_sdk import SpotifyClient

client = SpotifyClient(access_token="your-access-token")

# Use the client
album = client.albums.get("5K79FLRUCSysQnVESLcTdb")
print(f"{album.name} by {album.artists[0].name}")

client.close()
Access tokens expire after 1 hour. The SDK does not automatically refresh them when using this method.

Client Credentials Flow

Client credentials flow automatically fetches and refreshes tokens using your app’s client ID and secret. This is ideal for server applications that don’t need user-specific data.
1

Get Credentials

Register your application at Spotify Developer Dashboard to obtain your client ID and secret.
2

Initialize Client

Create a client using the from_client_credentials factory method or pass credentials to the constructor.
3

Use the Client

The SDK automatically fetches and caches access tokens. Tokens are refreshed when they expire.

Using the Factory Method

from spotify_sdk import SpotifyClient

client = SpotifyClient.from_client_credentials(
    client_id="your-client-id",
    client_secret="your-client-secret",
)

# Token is automatically fetched and cached
album = client.albums.get("4aawyAB9vmqN3uQ7FjRGTy")
print(album.name)

client.close()

Using Environment Variables

You can store credentials in environment variables to avoid hardcoding them:
export SPOTIFY_SDK_CLIENT_ID="your-client-id"
export SPOTIFY_SDK_CLIENT_SECRET="your-client-secret"

Using the Constructor

from spotify_sdk import SpotifyClient

client = SpotifyClient(
    client_id="your-client-id",
    client_secret="your-client-secret",
)

Authorization Code Flow

Authorization code flow is used for applications that need access to user-specific data like saved tracks, playlists, or playback control. This flow requires user authorization and provides refresh tokens for long-term access.

Basic Setup

from spotify_sdk import SpotifyClient
from spotify_sdk.auth import AuthorizationCode, FileTokenCache

auth = AuthorizationCode(
    client_id="your-client-id",
    client_secret="your-client-secret",
    redirect_uri="http://127.0.0.1:8080/callback",
    scope=["user-read-private", "user-library-read"],
    token_cache=FileTokenCache(".cache/spotify-sdk/token.json"),
)

# Local helper: opens browser and captures callback automatically
auth.authorize_local()

client = SpotifyClient(auth_provider=auth)

# Access user data
saved_albums = client.albums.get_saved(limit=10)
for item in saved_albums.items:
    print(f"{item.album.name} by {item.album.artists[0].name}")

client.close()

Authorization Scopes

Specify which permissions your application needs:
scope = [
    "user-read-private",
    "user-read-email",
    "user-library-read",
    "user-library-modify",
    "playlist-read-private",
    "playlist-modify-public",
]

auth = AuthorizationCode(
    client_id="your-client-id",
    client_secret="your-client-secret",
    redirect_uri="http://127.0.0.1:8080/callback",
    scope=scope,
)
See the Spotify Authorization Scopes documentation for a full list of available scopes.

Local Authorization Helper

The authorize_local helper automatically:
  1. Opens the authorization URL in your browser
  2. Starts a local HTTP server to receive the callback
  3. Exchanges the authorization code for tokens
  4. Saves tokens to the cache
from spotify_sdk.auth import AuthorizationCode, FileTokenCache

auth = AuthorizationCode(
    client_id="your-client-id",
    client_secret="your-client-secret",
    redirect_uri="http://127.0.0.1:8080/callback",
    scope=["user-read-private"],
    token_cache=FileTokenCache(".cache/spotify-sdk/token.json"),
)

# Opens browser and handles the callback
token_info = auth.authorize_local(
    timeout=300.0,  # Wait up to 5 minutes
    show_dialog=False,  # Force approval screen
)

print(f"Access token: {token_info.access_token}")
print(f"Expires at: {token_info.expires_at}")
print(f"Refresh token: {token_info.refresh_token}")

Manual Authorization Flow

For web applications or custom flows, handle the authorization manually:
from spotify_sdk.auth import AuthorizationCode

auth = AuthorizationCode(
    client_id="your-client-id",
    client_secret="your-client-secret",
    redirect_uri="https://your-app.com/callback",
    scope=["user-read-private"],
)

# 1. Get authorization URL
auth_url = auth.get_authorization_url(
    state="random-state-string",
    show_dialog=True,
)
print(f"Visit: {auth_url}")

# 2. User visits URL and authorizes
# 3. Parse callback URL
callback_url = "https://your-app.com/callback?code=ABC123&state=random-state-string"
code = auth.parse_response_url(
    callback_url,
    expected_state="random-state-string",
)

# 4. Exchange code for tokens
token_info = auth.exchange_code(code)
print(f"Access token: {token_info.access_token}")

Token Caching

Token caching prevents unnecessary token requests and persists tokens between sessions.

File-Based Cache

Store tokens in a JSON file:
from spotify_sdk.auth import ClientCredentials, FileTokenCache

auth = ClientCredentials(
    client_id="your-client-id",
    client_secret="your-client-secret",
    token_cache=FileTokenCache(".cache/spotify-sdk/token.json"),
)
The file is created automatically with secure permissions (mode 0600) and contains:
{
  "access_token": "BQD...",
  "expires_at": 1709567890.123,
  "refresh_token": "AQD...",
  "scope": "user-read-private user-library-read"
}

In-Memory Cache

The default cache stores tokens in memory only:
from spotify_sdk.auth import ClientCredentials, InMemoryTokenCache

auth = ClientCredentials(
    client_id="your-client-id",
    client_secret="your-client-secret",
    token_cache=InMemoryTokenCache(),  # Default if not specified
)
In-memory cache is lost when the process exits. Use FileTokenCache for persistent storage.

Custom Token Cache

Implement the TokenCache protocol for custom storage:
from spotify_sdk.auth import TokenInfo, TokenCache
import redis
import json
import time

class RedisTokenCache:
    """Redis-backed token cache."""
    
    def __init__(self, redis_client: redis.Redis, key: str = "spotify_token"):
        self._redis = redis_client
        self._key = key
    
    def get(self) -> TokenInfo | None:
        """Get cached token from Redis."""
        data = self._redis.get(self._key)
        if not data:
            return None
        
        payload = json.loads(data)
        return TokenInfo(
            access_token=payload["access_token"],
            expires_at=payload["expires_at"],
            refresh_token=payload.get("refresh_token"),
            scope=payload.get("scope"),
        )
    
    def set(self, token: TokenInfo) -> None:
        """Save token to Redis."""
        payload = {
            "access_token": token.access_token,
            "expires_at": token.expires_at,
            "refresh_token": token.refresh_token,
            "scope": token.scope,
        }
        ttl = max(0, int(token.expires_at - time.time()))
        self._redis.setex(self._key, ttl, json.dumps(payload))

Token Refresh

The SDK automatically refreshes tokens before they expire:
from spotify_sdk.auth import ClientCredentials

auth = ClientCredentials(
    client_id="your-client-id",
    client_secret="your-client-secret",
    skew_seconds=30,  # Refresh 30 seconds before expiry (default)
)

# First call: fetches new token
token1 = auth.get_access_token()

# Subsequent calls: returns cached token
token2 = auth.get_access_token()  # Same token

# After expiry: automatically refreshes
time.sleep(3600)  # Wait 1 hour
token3 = auth.get_access_token()  # New token

Refresh Configuration

skew_seconds
int
default:"30"
Number of seconds before expiry to refresh the token. Set to 0 to refresh only when expired.
timeout
float
default:"30.0"
HTTP timeout for token requests in seconds.
max_retries
int
default:"3"
Maximum retry attempts for failed token requests.
auth = ClientCredentials(
    client_id="your-client-id",
    client_secret="your-client-secret",
    skew_seconds=60,  # Refresh 1 minute before expiry
    timeout=15.0,  # 15 second timeout
    max_retries=5,  # Retry up to 5 times
)

Resource Cleanup

Always close auth providers when done to release HTTP connections:
from spotify_sdk.auth import ClientCredentials

auth = ClientCredentials(
    client_id="your-client-id",
    client_secret="your-client-secret",
)

try:
    token = auth.get_access_token()
    print(token)
finally:
    auth.close()
When using auth providers with SpotifyClient or AsyncSpotifyClient, calling client.close() also closes the auth provider.

Build docs developers (and LLMs) love