| title | Auth |
|---|---|
| description | Authenticate spogo with browser cookies or Spotify Authorization Code OAuth with PKCE. |
spogo supports two authentication mechanisms:
- Browser cookies are the default and preserve the existing Connect/internal-endpoint behavior.
- Spotify OAuth uses the official Authorization Code flow with PKCE for Web API requests. It does not use or store a client secret.
Choose Web API authentication with --auth cookies|oauth, SPOGO_AUTH, or the profile's auth setting. The default is cookies, so existing profiles keep their current behavior.
| Goal | Engine | Auth | Credentials required |
|---|---|---|---|
| Existing internal endpoints and Connect playback | connect or auto |
cookies |
Spotify browser cookies |
| Official Spotify Web API only | web |
oauth |
OAuth token cache + Spotify client ID |
| Connect first, official Web API for public-API fallbacks | connect or auto |
oauth |
Both browser cookies and OAuth |
OAuth cannot replace cookies for Spotify's internal Connect protocol. If you want a cookie-free setup, use --engine web --auth oauth.
spogo implements Spotify's Authorization Code with PKCE flow. PKCE is designed for installed/public clients that cannot safely hold a client secret.
Create an application in the Spotify Developer Dashboard and add this redirect URI exactly:
http://127.0.0.1:8888/callback
Spotify requires an explicit loopback IP. localhost is not accepted. A different loopback URI is fine, but it must match the dashboard entry and the value passed to spogo exactly.
spogo auth oauth login --client-id YOUR_SPOTIFY_CLIENT_IDspogo starts a loopback-only callback server, generates a cryptographically random state value and PKCE verifier, opens the Spotify authorization page, validates the callback state, exchanges the code, and stores the resulting access and refresh tokens.
If the machine cannot open a browser automatically:
spogo auth oauth login --client-id YOUR_SPOTIFY_CLIENT_ID --no-openOpen the URL printed to stderr. The command waits up to five minutes by default; change that with --wait-timeout.
For a custom registered callback:
spogo auth oauth login \
--client-id YOUR_SPOTIFY_CLIENT_ID \
--redirect-uri http://127.0.0.1:9999/callbackThe login stores only the non-secret client ID, redirect URI, and auth = "oauth" in the profile config. Client secrets are unsupported and are never read from or written to config.
spogo --engine web --auth oauth search track "weezer" --limit 5
spogo --engine web --auth oauth library tracks list --limit 20After login, auth = "oauth" is saved for the profile, so --auth oauth is optional. --engine web remains explicit because the default connect engine still requires cookies.
spogo requests the scopes needed by its existing Web API surface:
- playback state read/write and currently-playing access
- saved-library read/write
- followed-artist read/write
- private/collaborative playlist read and public/private playlist write
- top tracks and recently played history
- private account data required by Spotify search/profile endpoints
It does not request email access, streaming, image upload, or Web Playback SDK scopes.
spogo auth oauth status
spogo auth oauth clearstatus reads only local metadata. It never prints access or refresh token values and does not call Spotify. clear removes the token cache and returns the profile to the default cookie auth selection while retaining the non-secret client ID and redirect URI for a future login.
Access tokens refresh automatically before expiry. Spotify refresh responses that omit a replacement refresh token retain the previous refresh token. If Spotify rejects or expires the refresh token, run auth oauth login again.
Profile config example:
[profile.default]
auth = "oauth"
spotify_client_id = "your-public-client-id"
spotify_redirect_uri = "http://127.0.0.1:8888/callback"
engine = "web"Equivalent environment overrides:
export SPOGO_AUTH=oauth
export SPOGO_SPOTIFY_CLIENT_ID=your-public-client-id
export SPOGO_SPOTIFY_REDIRECT_URI=http://127.0.0.1:8888/callback
export SPOGO_ENGINE=webThere is intentionally no client-secret config key, flag, or environment variable.
OAuth tokens are stored per profile under the config directory:
<config-dir>/spogo/oauth/<profile>.json
Profile names that are not portable lowercase filename segments are encoded before deriving the token and lock filenames, so separators, traversal components, Windows-reserved names, and case variants cannot escape or alias within the OAuth directory.
The OAuth directory is mode 0700 and token file is mode 0600 on POSIX systems. Writes use a same-directory temporary file, file sync, and atomic rename. spogo refuses to load a token file that is readable or writable by group/other users.
Treat the token cache as a credential. Do not copy it into source control, logs, shell history, or CI artifacts.
Cookie auth remains the default. spogo reads the cookies your browser already has for open.spotify.com and uses them for the internal Web Player and Connect protocols. The cookie machinery comes from steipete/sweetcookie.
sp_dcis required.sp_keyis optional and helps with rotation.sp_tis recommended for Connect playback control.
spogo auth import --browser chromeSupported browser names are chrome, brave, edge, firefox, and safari.
For a non-default browser profile:
spogo auth import --browser chrome --browser-profile "Profile 1"To choose where spogo writes the imported JSON cookie cache:
spogo auth import --cookie-path /path/to/spogo-cookies.json--cookie-path is an output file, not a browser database to read. When the browser-store read returns nothing, spogo surfaces the underlying warning, such as a locked keychain, missing profile, or decryption failure.
- In Chrome, open DevTools, then Application, Cookies,
https://open.spotify.com. - Copy
sp_dcand, preferably,sp_t.sp_keyis optional. - Run:
spogo auth pasteFor non-interactive input:
printf '%s\n%s\n' "sp_dc=..." "sp_t=..." | spogo auth paste --no-inputCookie imports and pastes replace the JSON file atomically using a synced temporary file. On POSIX systems, every replacement is mode 0600, even when an older file had broader permissions; newly created cookie directories are mode 0700. Failed writes preserve the previous file, and concurrent readers never see a partially written cookie jar.
spogo auth status
spogo auth clearThese existing commands remain cookie-specific. They do not inspect or clear OAuth tokens.
auth status does not call Spotify. To verify cookies actually work, run a command that uses them:
spogo status
spogo search track "test" --limit 1Profiles keep cookie jars, OAuth token caches, and settings separate:
Default cookie, Connect cache, and OAuth filenames use the profile name when it is portable lowercase ASCII (letters, digits, dots, hyphens, and underscores). Other names, including path separators, uppercase letters, and Windows reserved names, are encoded to keep profiles distinct and inside their respective directories. Long names use a SHA-256 digest to stay within filesystem filename limits, including lock-file suffixes. Existing explicit cookie_path settings remain supported. After upgrading, unusual profile names get a fresh Connect cache; if cookies were stored only at an old implicit path, re-import them or set an explicit cookie_path. spogo does not read or delete legacy implicit paths that could belong to another profile.
spogo --profile work auth import --browser chrome --browser-profile "Profile 1"
spogo --profile personal auth oauth login --client-id YOUR_SPOTIFY_CLIENT_ID
spogo --profile work status
spogo --profile personal --engine web search track "test"no cookies found: choose the correct browser profile or useauth paste.- OAuth callback bind failure: another process is using the registered port. Stop it or register and pass a different loopback redirect URI.
- OAuth state mismatch: leave the command running and use the newest authorization URL it printed. Invalid callbacks are rejected.
- OAuth token cache permissions error: change the token file to owner-only mode (
0600) and its directory to0700, or clear and log in again. - OAuth works with
webbutconnectfails: expected. Connect still requires Spotify browser cookies. - OAuth refresh rejected: run
spogo auth oauth loginagain. 401/403with cookies: re-import after logging back intoopen.spotify.com.
See Troubleshooting for more.