Skip to content

Authentication

spotify-effect supports three authentication flows. The library handles token management automatically — you configure credentials once, and the layer manages access token retrieval and refresh.

Client Credentials Flow

Use this for server-to-server requests where you don’t need user-specific data (e.g., featured playlists, new releases, catalog search).

import { Effect } from "effect";
import { NodeRuntime } from "@effect/platform-node";
import { Browse, makeSpotifyLayer } from "@spotify-effect/core";
const SpotifyLayer = makeSpotifyLayer({
clientId: process.env.SPOTIFY_CLIENT_ID!,
clientSecret: process.env.SPOTIFY_CLIENT_SECRET!,
});
const program = Effect.gen(function* () {
const browse = yield* Browse;
const releases = yield* browse.getNewReleases({ limit: 10 });
return releases.items;
});
program.pipe(Effect.provide(SpotifyLayer), NodeRuntime.runMain);

How it works

  1. makeSpotifyLayer detects the client credentials flow when clientSecret is provided but redirectUri is not
  2. On first API call, the layer fetches a temporary token from Spotify’s token endpoint
  3. Tokens are cached and refreshed automatically when they expire

Limitations

  • No user access — cannot access private playlists, user library, playback state, etc.
  • No refresh token — tokens expire and must be re-obtained

Authorization Code Flow

Use this when you need to access or modify user-specific data (playlists, saved tracks, playback control).

Flow overview

  1. Redirect user to Spotify’s authorization page
  2. User grants permissions and is redirected back with an authorization code
  3. Exchange the code for access and refresh tokens
  4. Use the refresh token to obtain new access tokens when needed

Step 1: Generate authorization URL

import { getAuthorizationUrl } from "@spotify-effect/core";
const authUrl = getAuthorizationUrl(
process.env.SPOTIFY_CLIENT_ID!,
process.env.SPOTIFY_REDIRECT_URI!,
"code",
{
scope: [
"user-read-private",
"user-library-read",
"playlist-read-private",
"user-read-currently-playing",
],
},
);
// Redirect user to authUrl

Step 2: Exchange code for tokens

import { Effect } from "effect";
import { SpotifyAuth, makeSpotifyLayer } from "@spotify-effect/core";
const SpotifyLayer = makeSpotifyLayer({
clientId: process.env.SPOTIFY_CLIENT_ID!,
clientSecret: process.env.SPOTIFY_CLIENT_SECRET!,
redirectUri: process.env.SPOTIFY_REDIRECT_URI!,
});
const program = Effect.gen(function* () {
const auth = yield* SpotifyAuth;
const tokens = yield* auth.getRefreshableUserTokens(authorizationCode);
// Store tokens.access_token and tokens.refresh_token securely
return tokens;
});

Step 3: Provide tokens to the layer

Once you have tokens, provide them to the layer:

const SpotifyLayer = makeSpotifyLayer(
{
clientId: process.env.SPOTIFY_CLIENT_ID!,
clientSecret: process.env.SPOTIFY_CLIENT_SECRET!,
redirectUri: process.env.SPOTIFY_REDIRECT_URI!,
},
{
accessToken: storedAccessToken,
refreshToken: storedRefreshToken,
accessTokenExpiresAt: tokenExpiresAtTimestamp,
},
);

The layer automatically refreshes tokens when they expire.

PKCE Flow

PKCE (Proof Key for Code Exchange) is for browser-based applications where you can’t safely store a client secret.

See the Browser (PKCE) guide for detailed instructions using @spotify-effect/browser.

Scopes

Available OAuth scopes:

ScopeDescription
ugc-image-uploadUpload images to a user’s profile
user-read-playback-stateRead user’s current playback state
user-modify-playback-stateControl Spotify playback
user-read-currently-playingRead currently playing track
streamingPlay Spotify content
user-read-emailRead user’s email
user-read-privateRead user’s subscription details
playlist-read-collaborativeRead collaborative playlists
playlist-modify-publicModify public playlists
playlist-read-privateRead private playlists
playlist-modify-privateModify private playlists
user-library-modifyModify saved content
user-library-readRead saved content
user-top-readRead user’s top artists/tracks
user-read-playback-positionRead playback position
user-read-recently-playedRead recently played
user-follow-readRead followed artists
user-follow-modifyModify followed artists

Token Storage

Store tokens securely:

  • Server-side: Use encrypted cookies, secure session storage, or a database
  • Browser-side: Use sessionStorage for session tokens, localStorage with encryption for refresh tokens

The @spotify-effect/browser package handles token storage automatically using the Web Storage API.

Next steps