Integrations Guide

soundspan works standalone, but these integrations unlock additional discovery and playback workflows.

For environment and secret setup, see CONFIGURATION_AND_SECURITY.md.

Lidarr

Connect soundspan to Lidarr to request/download new music and trigger imports.

What you get

Setup

  1. Open AdminDownload Services
  2. Enable Lidarr
  3. Set Lidarr URL (for example http://localhost:8686)
  4. Set Lidarr API key (Lidarr → Settings → General)
  5. Test and save

Networking note

Lidarr must reach the soundspan callback URL.

environment:
    - SOUNDSPAN_CALLBACK_URL=http://YOUR_SOUNDSPAN_IP:3030

Audiobookshelf

Connect your Audiobookshelf instance for audiobook playback in soundspan.

Audiobook detail metadata and section navigation are served from soundspan's local cache. A scheduled sync keeps that cache in step with Audiobookshelf: it adds new books within a few minutes and removes books that were deleted in Audiobookshelf, together with their cached covers and listening progress. Removals are deliberately cautious: a book is only removed after it has been absent from two complete, verified library listings taken several minutes apart, and an unreachable server or an incomplete listing never triggers removals. Books without a recorded source library are never removed automatically. Scheduled or manual sync also validates chapter coverage and backfills section data for rows that do not have it yet. Multi-file part boundaries are playable because the stream proxy exposes all files as one byte-addressable audiobook resource.

Setup

  1. Open AdminMedia Servers
  2. Turn on Enable Audiobookshelf
  3. Set Server URL (for example http://localhost:13378)
  4. Set API Key from the Audiobookshelf user settings
  5. Test and save

Soulseek

soundspan can connect directly to Soulseek for discovery/download flows.

Disclaimer: You are responsible for legal use in your jurisdiction.

Setup

  1. Open AdminDownload Services
  2. Enter Soulseek username/password
  3. Save

Notes

YouTube Music

Stream unowned tracks via per-user YouTube Music OAuth.

Disclaimer: Uses unofficial libraries (ytmusicapi, yt-dlp) and requires YouTube Music Premium.

Requirements

Admin setup

  1. Create OAuth client in Google Cloud Console
  2. Open AdminYouTube Music
  3. Enable and set client ID/secret
  4. Save

Per-user setup

  1. Open SettingsIntegrationsYouTube Music
  2. Select Open Google Sign-In Page
  3. Complete the provider authorization flow
  4. Choose quality and save

Quality settings

Setting Approximate bitrate
Low ~64 kbps
Medium ~128 kbps
High ~256 kbps
Lossless Best available

API access modes

All routes below still require soundspan authentication and ytMusicEnabled=true. Browse, search, and public stream routes normally work without a linked account, subject to sidecar availability and provider behavior.

Mode Endpoints
Normally works without a linked account (sidecar-dependent) GET /api/browse/ytmusic/charts, GET /api/browse/ytmusic/categories, GET /api/browse/ytmusic/playlist/:id, POST /api/ytmusic/search, POST /api/ytmusic/match, POST /api/ytmusic/match-batch, GET /api/ytmusic/stream-info-public/:videoId, GET /api/ytmusic/stream-public/:videoId
Per-user OAuth required GET /api/ytmusic/album/:browseId, GET /api/ytmusic/artist/:channelId, GET /api/ytmusic/song/:videoId, GET /api/ytmusic/stream-info/:videoId, GET /api/ytmusic/stream/:videoId, GET /api/ytmusic/library/songs, GET /api/ytmusic/library/albums

Track Mapping and Playlist Import APIs

soundspan also exposes provider mapping and playlist import routes for cross-provider workflows:

Endpoint Purpose
POST /api/browse/playlists/parse Parse Spotify, Deezer, YouTube Music, and TIDAL playlist URLs before import
GET /api/track-mappings/album/:albumId Read provider mappings for an album's local tracks
POST /api/track-mappings/batch Persist multiple mapping links in one request
POST /api/import/preview Resolve playlist tracks (local/YT/TIDAL) without creating a playlist
POST /api/import/execute Create a playlist from a resolved import
POST /api/import/jobs Start a provider-neutral playlist import job
GET /api/import/jobs List the authenticated user's import jobs
GET /api/import/jobs/:jobId Read one import job and its current progress
POST /api/import/jobs/reconnect Reconnect to an active import for the same source
POST /api/import/jobs/:jobId/cancel Cancel a queued or running import job
POST /api/import/m3u/preview Parse and preview an uploaded M3U playlist before import

TIDAL Streaming

Stream unowned tracks via per-user TIDAL OAuth.

Disclaimer: Requires TIDAL subscription and uses tiddl library.

Requirements

Per-user setup

  1. Open SettingsIntegrationsTIDAL
  2. Select Open TIDAL Authorization Page
  3. Complete the provider authorization flow
  4. Choose quality and save

Streaming auth is separate from admin download auth.

Quality settings

Setting Format
Low AAC 96 kbps
High AAC 320 kbps
Lossless FLAC 16-bit / 44.1 kHz
Max / Hi-Res FLAC 24-bit / 192 kHz

TIDAL Downloads

Use TIDAL as a download source for tracks/albums.

Disclaimer: Intended for personal use with your own subscription.

Setup

  1. Ensure tidal-streamer service is running
  2. Open AdminDownload Services
  3. Authenticate via device-code flow
  4. Choose download quality and naming template
  5. Save

File naming template examples

# Default
{album.artist}/{album.title}/{item.number:02d}. {item.title}

# Disc-track format
{album.artist}/{album.title}/{item.volume}-{item.number:02d} {item.title}

# With year
{album.artist}/{album.title} ({album.date:%Y})/{item.number:02d}. {item.title}

Default template:

{album.artist}/{album.title}/{item.number:02d}. {item.title}

TIDAL sidecar environment values

Variable Default Description
TIDAL_TRACK_DELAY 3 Delay between track downloads
MUSIC_PATH /music Path for downloaded music
TIDDL_PATH /data/.tiddl Sidecar cache/config path
DEBUG (unset) Enable debug logging

Main-channel image:

docker pull ghcr.io/soundspan/soundspan-tidal-streamer:main

ghcr.io/soundspan/soundspan-tidal-downloader is published as an alias of soundspan-tidal-streamer, and the tidal-downloader Compose hostname resolves to tidal-streamer.

YouTube Music Downloads

Use YouTube Music as a download source for albums, the same way TIDAL works.

Disclaimer: Uses unofficial libraries (ytmusicapi, yt-dlp). Intended for personal use.

Setup

  1. Ensure the ytmusic-streamer sidecar is running
  2. Open AdminYouTube Music and enable YouTube Music
  3. Open AdminDownload Preferences
  4. Choose YouTube Music (Albums) as the primary source, or pick Try YouTube Music as the fallback for another source
  5. Save

No account link is needed for downloads — the sidecar uses public album pages.

How it works

When a download job runs, soundspan searches YouTube Music for the album, then the sidecar downloads each track and files it under your music folder as Artist/Album/01. Title.mp3. The library scanner picks the album up automatically when the job finishes.

If the album is not found on YouTube Music, the job follows your When Primary Source Fails setting — it can hand off to Soulseek, Lidarr, or TIDAL, or skip.

Sidecar environment values

Variable Default Description
MUSIC_PATH /music Path for downloaded music
YT_ALBUM_DOWNLOAD_CONCURRENCY 1 Album download jobs processed at once

Last.fm and ListenBrainz Scrobbling

Each user can send their soundspan listening history to Last.fm and/or ListenBrainz. Connections are per user, under Settings -> Scrobbling. Plays from the web app and from connected Subsonic clients both forward.

ListenBrainz setup

No server configuration is needed.

  1. Copy your user token from listenbrainz.org/settings
  2. Open Settings -> Scrobbling, paste the token, and click Connect

Last.fm setup

The server operator must first create a free Last.fm API account (https://www.last.fm/api/account/create) and set two environment values:

LASTFM_API_KEY=your_api_key
LASTFM_SHARED_SECRET=your_shared_secret

LASTFM_API_KEY may already be set for metadata enrichment; scrobbling additionally requires the shared secret. Helm users storing keys in an existing Secret must add LASTFM_SHARED_SECRET to it.

These two values identify your soundspan server as an application to Last.fm — like an OAuth app credential. They are not a listener account and never receive scrobbles. Each user still connects their own Last.fm account, and each user's plays go to their own Last.fm profile.

The shared secret is intentionally never displayed in any admin screen. The Scrobbling settings page reports which of the two values is missing when Last.fm is unavailable.

Then each user connects their own account:

  1. Open Settings -> Scrobbling and click Connect Last.fm
  2. Approve the connection on the Last.fm page that opens
  3. Return and click I've approved — finish connecting

Notes

Podcasts

Podcast discovery and subscriptions require no credentials. Search uses the iTunes discovery catalog. Subscriptions use each podcast's RSS feed for episode metadata and playback.

  1. Open Podcasts
  2. Search the iTunes catalog or add an RSS feed
  3. Subscribe to keep the feed in your library

OpenSubsonic API Compatibility

soundspan exposes a Subsonic/OpenSubsonic-compatible /rest surface.

Local smoke check:

cd backend
npm run test:smoke:subsonic-proxy

See also