Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Spotify Client Laravel Package

jordanpartridge/spotify-client

A Laravel-friendly client for the Spotify Web API, giving you a clean, expressive way to authenticate and interact with Spotify data such as tracks, artists, albums, and playlists from your PHP applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package and (optionally) publish its config:

composer require jordanpartridge/spotify-client:^1.3.0
php artisan vendor:publish --tag=spotify-client-config

If you only need app-level access, this is the minimum viable setup in .env:

SPOTIFY_CLIENT_ID=your_client_id
SPOTIFY_CLIENT_SECRET=your_client_secret
SPOTIFY_AUTH_FLOW=client_credentials

The first place to look is the config file (config/spotify-client.php) — it now maps cleanly to environment variables, including SPOTIFY_CALLBACK_HOST, SPOTIFY_CALLBACK_PORT, and SPOTIFY_TOKEN_STORAGE_PATH. From there, the fastest first use case is resolving the client from the container and hitting a read-only endpoint:

use JordanPartridge\SpotifyClient\Contracts\SpotifyClientInterface;

$spotify = app(SpotifyClientInterface::class);
$tracks = $spotify->search()->tracks('The Beatles');

If that call returns data, your credentials and bearer token injection are working. If you need user-scoped data (playlists, saved tracks, playback), you're in Authorization Code territory — jump to the second pattern below.

Implementation Patterns

Client Credentials for background/app data. Use this for search, catalog lookups, album/track metadata, and anything that doesn't need a user context. It's the least friction path and the one you should default to in jobs, commands, and scheduled tasks:

// app/Jobs/ImportArtistCatalog.php
public function handle(SpotifyClientInterface $spotify): void
{
    $albums = $spotify->artists()->albums($this->artistId);
    // ...
}

Because the client is bound in the container, injecting SpotifyClientInterface into jobs, controllers, and commands is the idiomatic pattern — don't app() it inside methods when you can inject it.

Authorization Code for user-scoped work. Resolve the manager and select the driver:

use JordanPartridge\SpotifyClient\Auth\SpotifyAuthManager;

$auth = app('spotify.auth')->driver('authorization_code');

The manager pattern means you can swap drivers in tests by binding a fake or by overriding the driver in the container. Treat app('spotify.auth') as the extension seam — if you need a custom auth strategy later, that's where it plugs in.

Token storage in real apps. The default file-based token store is fine for single-server setups and local dev, but point it at a persistent, writable path outside storage/framework/cache if you're deploying ephemeral containers:

SPOTIFY_TOKEN_STORAGE_PATH=/var/www/shared/spotify/tokens.json

For multi-server or queue-heavy apps, implement TokenStorageInterface against your cache or database and bind it in a service provider — this is the cleanest extension point in the package and avoids per-node token drift.

Refresh is automatic, so don't pre-check expiry. The package handles expiration and refresh internally. Write your code as if tokens are always valid; don't add your own "is this token expired" guard, because you'll end up duplicating logic that's already in the authenticator and can cause double-refresh races.

Callback server config for OAuth. If your local setup uses 127.0.0.1 rather than localhost (common with Docker, Conduit, and some browsers), set the host explicitly so the redirect URI registered in the Spotify dashboard matches exactly:

SPOTIFY_CALLBACK_HOST=127.0.0.1
SPOTIFY_CALLBACK_PORT=8080

Gotchas and Tips

  • "No token provided" 401s after upgrading were the core symptom of Issue #19. If you still see them post-upgrade, it's almost always a config cache problem — run php artisan config:clear after changing any SPOTIFY_* env var. Config caching in production will silently ignore new .env values.
  • Credentials are optional but APIs are not. The release explicitly notes the package works without credentials, but API calls will fail. Don't interpret "backward compatible" as "works offline" — it's about the public API surface, not runtime behavior.
  • Callback host/port is not cosmetic. The localhost vs 127.0.0.1 mismatch (Issue #21) causes redirect URI mismatches that look like auth bugs but are registration bugs. Set SPOTIFY_CALLBACK_HOST to exactly what's whitelisted in your Spotify app dashboard.
  • Token storage path differs between contexts. The release fixes path resolution for both Laravel apps and package development. If you're writing tests or running the package's own test suite, don't assume the same path resolves — check SPOTIFY_TOKEN_STORAGE_PATH is set rather than relying on defaults.
  • No breaking changes means low upgrade risk, but not zero migration work. You don't have to change anything, but the new SpotifyAuthManager and TokenStorageInterface are worth adopting if you previously hand-rolled auth — otherwise you're carrying duplicated refresh logic.
  • Don't hardcode tokens. Since bearer injection is automatic across all requests, any token you manually set in a request or header will likely be overwritten or conflict. Let the client own that.
  • Debugging checklist for auth failures, in order: (1) php artisan config:clear, (2) confirm client ID/secret are actually loaded via config('spotify-client...'), (3) verify callback host matches dashboard, (4) check token storage path is writable, (5) confirm you're using the right flow — client credentials cannot access user endpoints no matter how valid the token is.
  • Extension point to remember: TokenStorageInterface is the intended customisation for persistence. Resist patching the file-based store directly; bind your own implementation instead so upgrades stay painless.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core