Spotify Soloist Overview

Spotify Soloist is a headless Spotify client for Linux-based systems, aimed at devices like the Raspberry Pi. It advertises itself on your local network, authenticates through Spotify Connect, and plays audio through the device's audio system.

Build lifetime

Spotify Soloist builds are time-limited. Each build can be used for 90 days from its build date. Spotify Soloist logs the remaining lifetime at startup, logs warnings as expiry approaches, and exits with code 10 when the build has expired. Update to a newer build before the current one expires.

Runtime modes

Spotify Soloist has two main runtime modes.

ModeUse it when
Spotify Connect deviceYou want Spotify Soloist to stay online and be selectable from the Spotify app.
Single-track modeYou want a script to play one Spotify URI and exit.

The normal Spotify Connect mode is the default. It starts local network discovery, waits for Spotify Connect login, and keeps running until you stop it.

Single-track mode uses --single-track URI. It restores a previously stored session, plays one Spotify URI, and exits when that playback finishes.

Audio output

Spotify Soloist plays audio through PipeWire or PulseAudio on the Linux device. By default, it uses the system's default audio output.

When PipeWire is available, Spotify Soloist uses PipeWire. If PipeWire cannot initialize, Spotify Soloist falls back to PulseAudio. Use --pipewire-device DEVICE when you need to route audio to a specific PipeWire node name or ID.

Local control surfaces

Spotify Soloist can be used only from the Spotify app, or with extra local integration surfaces:

  • The optional WebSocket API lets another local process observe playback events and send playback commands.
  • soloist ctl connects through that local WebSocket API to send commands and print status, now-playing, queue, or event trace output.

The WebSocket API is disabled by default. Enable it with --ws ADDR:PORT. For local-only integrations, bind it to 127.0.0.1.

When you use port 0, the operating system chooses a free port. Spotify Soloist writes the actual WebSocket endpoint into ws.addr and ws.port files in the data directory after the server starts. soloist ctl uses those files for automatic same-machine discovery.

Data and cache storage

Spotify Soloist uses two storage locations:

LocationPurpose
Data directoryPrivate account data, including device identity, stored Spotify Connect session, runtime files, local crash reports, and state managed by Spotify Soloist.
Cache directoryVolatile playback cache.

The data directory also contains runtime files while Spotify Soloist is running:

FilePurpose
soloist.pidDaemon process ID used by soloist ctl status.
ws.addrWebSocket bind address, present only when --ws is enabled.
ws.portWebSocket listening port, present only when --ws is enabled.

On Linux, Spotify Soloist resolves defaults in this order:

DirectoryResolution
Data$STATE_DIRECTORY, then $XDG_DATA_HOME/soloist, then ~/.local/share/soloist
Cache$CACHE_DIRECTORY, then $XDG_CACHE_HOME/soloist, then ~/.cache/soloist

Pass --data-dir and --cache-dir to choose explicit locations.

Removing the data directory resets the device identity and stored Spotify Connect session.

Crash reports are stored locally in the data directory and are not uploaded automatically.

Configuration

Spotify Soloist does not currently read a configuration file. Configure it with CLI options, environment-driven default directories, and your process manager.

For example, this starts a long-running local device with WebSocket control enabled on a fixed loopback port:


_10
soloist \
_10
--device-name "Kitchen speaker" \
_10
--api-key "$SOLOIST_API_KEY" \
_10
--data-dir "$HOME/.local/share/soloist" \
_10
--cache-dir "$HOME/.cache/soloist" \
_10
--ws 127.0.0.1:9090

Network model

Spotify Soloist uses local network discovery so Spotify apps on the same network can find it as a Spotify Connect device. The optional WebSocket API is separate from Spotify Connect and is meant for your own local integrations.

The Spotify Soloist WebSocket API is a local integration surface. It has no built-in client authentication, authorization, TLS, Origin validation, CSRF protection, browser-facing security controls, or network exposure policy.