Authentication
Learn how to authenticate with the Spotify Web API using different OAuth flows
Authentication is the first step to accessing the Spotify Web API. Spotify uses OAuth 2.0 for authorization, offering several flows depending on your application type and requirements.
Choosing an Authentication Flow
Section titled “Choosing an Authentication Flow”Best for: Server-side applications that don’t need user data
- Access public Spotify data (albums, artists, tracks, playlists)
- No user login required
- Cannot access user-specific endpoints
- Tokens expire after 1 hour (no refresh)
Best for: Server-side apps that need user data
- Full access to user resources
- Supports token refresh
- Requires secure storage of client secret
- User must grant permission
Best for: Mobile apps, SPAs, desktop apps
- No client secret required
- Supports token refresh
- Secure for public clients
- User must grant permission
OAuth Scopes
Section titled “OAuth Scopes”Scopes define what your application can access. Request only the scopes you need.
Common Scopes
Section titled “Common Scopes”| Scope | Description |
|---|---|
user-read-private | Read user’s subscription details |
user-read-email | Read user’s email address |
playlist-read-private | Read user’s private playlists |
playlist-modify-public | Create and modify public playlists |
playlist-modify-private | Create and modify private playlists |
user-library-read | Read user’s saved tracks and albums |
user-library-modify | Save and remove tracks/albums |
user-read-playback-state | Read player state |
user-modify-playback-state | Control playback |
user-read-currently-playing | Read currently playing track |
user-read-recently-played | Read recently played tracks |
user-top-read | Read user’s top artists and tracks |
Client Credentials Flow
Section titled “Client Credentials Flow”Use this flow for server-to-server authentication when you only need access to public Spotify data.
-
Get your credentials
Log into the Spotify Developer Dashboard and create an app to get your Client ID and Client Secret.
-
Using the SDK with Client Credentials
The SDK handles Client Credentials authentication automatically when you set environment variables:
Terminal window export SPOTIFY_CLIENT_ID="your_client_id"export SPOTIFY_CLIENT_SECRET="your_client_secret"Then use the SDK directly:
import Spotted from "spotted-ts";// SDK automatically handles token acquisition and refreshconst client = new Spotted();// Get Taylor Swift's artist profileconst artist = await client.artists.retrieve("06HL4z0CvFAxyc27GXpf02");console.log(artist.name, "-", artist.followers.total, "followers");Or pass credentials directly:
import Spotted from "spotted-ts";const client = new Spotted({clientId: "your_client_id",clientSecret: "your_client_secret",});
Authorization Code Flow
Section titled “Authorization Code Flow”Use this flow when your application needs to access user-specific data and can securely store a client secret.
-
Redirect user to Spotify authorization
const client_id = "your_client_id";const redirect_uri = "http://localhost:3000/callback";const scopes = ["user-read-private","user-read-email","playlist-read-private","user-library-read",].join(" ");function getAuthUrl() {const params = new URLSearchParams({response_type: "code",client_id: client_id,scope: scopes,redirect_uri: redirect_uri,state: generateRandomString(16), // CSRF protection});return `https://accounts.spotify.com/authorize?${params.toString()}`;}function generateRandomString(length) {const chars ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";return Array.from({ length }, () =>chars.charAt(Math.floor(Math.random() * chars.length)),).join("");} -
Handle the callback and exchange code for tokens
async function handleCallback(code) {const response = await fetch("https://accounts.spotify.com/api/token", {method: "POST",headers: {Authorization:"Basic " +Buffer.from(client_id + ":" + client_secret).toString("base64"),"Content-Type": "application/x-www-form-urlencoded",},body: new URLSearchParams({grant_type: "authorization_code",code: code,redirect_uri: redirect_uri,}),});const tokens = await response.json();// tokens contains: access_token, refresh_token, expires_in, token_type, scopereturn tokens;} -
Refresh the access token
async function refreshAccessToken(refresh_token) {const response = await fetch("https://accounts.spotify.com/api/token", {method: "POST",headers: {Authorization:"Basic " +Buffer.from(client_id + ":" + client_secret).toString("base64"),"Content-Type": "application/x-www-form-urlencoded",},body: new URLSearchParams({grant_type: "refresh_token",refresh_token: refresh_token,}),});return response.json();}
Authorization Code with PKCE
Section titled “Authorization Code with PKCE”Use this flow for mobile apps, single-page applications, or any client that cannot securely store a client secret.
-
Generate PKCE code verifier and challenge
function generateCodeVerifier() {const array = new Uint8Array(32);crypto.getRandomValues(array);return base64UrlEncode(array);}async function generateCodeChallenge(verifier) {const encoder = new TextEncoder();const data = encoder.encode(verifier);const digest = await crypto.subtle.digest("SHA-256", data);return base64UrlEncode(new Uint8Array(digest));}function base64UrlEncode(buffer) {return btoa(String.fromCharCode(...buffer)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");} -
Redirect user with PKCE parameters
async function getAuthUrlWithPKCE() {const codeVerifier = generateCodeVerifier();const codeChallenge = await generateCodeChallenge(codeVerifier);// Store codeVerifier securely (e.g., sessionStorage)sessionStorage.setItem("code_verifier", codeVerifier);const params = new URLSearchParams({response_type: "code",client_id: client_id,scope: scopes,redirect_uri: redirect_uri,state: generateRandomString(16),code_challenge_method: "S256",code_challenge: codeChallenge,});return `https://accounts.spotify.com/authorize?${params.toString()}`;} -
Exchange code for tokens using code verifier
async function handleCallbackPKCE(code) {const codeVerifier = sessionStorage.getItem("code_verifier");const response = await fetch("https://accounts.spotify.com/api/token", {method: "POST",headers: {"Content-Type": "application/x-www-form-urlencoded",},body: new URLSearchParams({grant_type: "authorization_code",code: code,redirect_uri: redirect_uri,client_id: client_id,code_verifier: codeVerifier,}),});return response.json();}
Using the SDK with User Authentication
Section titled “Using the SDK with User Authentication”When you need to access user-specific endpoints, pass an access token to the SDK:
import Spotted from "spotted-ts";
// After completing OAuth flow and getting tokensconst client = new Spotted({ bearerToken: userAccessToken,});
// Access user-specific endpointsconst profile = await client.me.retrieve();console.log(`Logged in as: ${profile.display_name}`);
// Get user's playlistsfor await (const playlist of client.me.playlists.list()) { console.log(playlist.name);}
// Get user's saved tracksfor await (const item of client.me.tracks.list()) { console.log(`${item.track.name} by ${item.track.artists[0].name}`);}Token Refresh
Section titled “Token Refresh”The SDK handles token management internally, but if you’re managing tokens manually for user authentication, you can update the client:
// When token expires, get a new one from your OAuth flowconst newAccessToken = await refreshUserToken(refreshToken);
// Create a new client instance with the fresh tokenconst client = new Spotted({ bearerToken: newAccessToken,});Error Handling
Section titled “Error Handling”Always handle authentication errors gracefully:
async function handleAuthError(response) { if (!response.ok) { const error = await response.json();
switch (error.error) { case "invalid_grant": // Refresh token expired or revoked console.error("Please re-authenticate"); break; case "invalid_client": console.error("Invalid client credentials"); break; case "invalid_request": console.error( "Missing or invalid parameters:", error.error_description, ); break; default: console.error("Authentication error:", error.error_description); }
throw new Error(error.error_description); }
return response.json();}Next Steps
Section titled “Next Steps”Now that you understand authentication, explore these guides:
- Search & Discovery - Find tracks, artists, and albums
- Playlist Management - Create and manage playlists
- User Library - Access saved tracks and albums