Skip to content

Configuration Reference

DeepCrate is configured via a YAML file mounted at /config/config.yaml.

Full Configuration Example

yaml
# =============================================================================
# ListenBrainz Discovery
# Recommendations based on your listening history (scrobbles)
# =============================================================================
# Enable debug logging/features (optional)
debug: false

listenbrainz:
  # Your ListenBrainz username
  username: "your_username"

  # API token from https://listenbrainz.org/settings/
  # Only required if source_type is "collaborative"
  # token: "your_token"

  # Approval mode: "auto" or "manual"
  # auto:   Adds directly to wishlist for immediate download
  # manual: Adds to pending queue for review in Web UI
  approval_mode: "manual"

  # Source type: where to get recommendations from
  # weekly_playlist: Uses weekly exploration playlists (default, no token needed)
  # collaborative: Uses CF recommendations based on listening history (requires token)
  source_type: "weekly_playlist"

# Recommendation mode: "album" or "track"
# album: Resolve recommended tracks to their parent albums (recommended)
# track: Download individual tracks only
mode: "album"

# Minimum recommendation score (0-100)
# 0 = accept all recommendations
# Higher values = only highly-relevant recommendations
# (If you prefer, you can also use 0-1 and it will be treated as a fraction.)
min_score: 0

# Number of recommendations to fetch per run
fetch_count: 100

# =============================================================================
# slskd Connection
# Soulseek client for downloading music
# =============================================================================
slskd:
  # slskd API URL
  host: "http://slskd:5030"

  # API key from slskd.yml (web.authentication.api_keys)
  api_key: "your_slskd_api_key"

  # URL base path (usually "/")
  url_base: "/"

  # Search timeout in milliseconds (legacy, prefer search.search_timeout_ms)
  search_timeout: 15000

  # Minimum tracks to consider a valid album result (legacy, prefer search.min_response_files)
  # Helps filter out incomplete uploads
  min_album_tracks: 3

  # Advanced search configuration (optional)
  search:
    # Query templates - variables: {artist}, {album}, {title}, {year}
    album_query_template: "{artist} {album}"
    track_query_template: "{artist} {title}"

    # Fallback queries to try if primary search returns no results
    # Tried in order when retry is enabled
    fallback_queries:
      - "{album}"
      - "{artist} {album} {year}"

    # Terms to remove when simplifying queries (e.g., on retry)
    exclude_terms:
      - "live"
      - "remix"
      - "cover"
      - "karaoke"

    # Search timing
    search_timeout_ms: 15000      # Timeout for slskd search API call
    max_wait_ms: 20000            # Max time to wait for search completion

    # Response filtering
    min_response_files: 3         # Minimum files to consider a valid result
    max_responses_to_evaluate: 50 # Limit responses to evaluate (performance)

    # File size constraints (MB) - filters out suspiciously small/large files
    min_file_size_mb: 1
    max_file_size_mb: 500

    # Album preferences (soft scoring, not strict filters)
    prefer_complete_albums: true  # Bonus score for results with enough tracks
    prefer_album_folder: true     # Bonus score for proper folder structure

    # Retry configuration
    retry:
      enabled: false              # Enable retry with fallback queries
      max_attempts: 3             # Total attempts including primary
      simplify_on_retry: true     # Simplify query (remove diacritics, special chars)
      delay_between_retries_ms: 5000

    # Audio quality preferences (optional)
    quality_preferences:
      enabled: true               # Enable quality-based filtering and scoring
      preferred_formats:          # Formats to prioritize (bonus scoring)
        - flac
        - wav
        - alac
        - mp3
        - m4a
        - ogg
      min_bitrate: 256            # Minimum acceptable bitrate (kbps) for lossy formats
      prefer_lossless: true       # Give lossless formats higher priority
      reject_low_quality: false   # Hard reject files below min_bitrate (vs just deprioritize)
      reject_lossless: false      # Hard reject lossless files (for users who only want lossy)

    # Completeness scoring (optional)
    # Score results based on track completeness using MusicBrainz/Deezer metadata
    completeness:
      enabled: true                 # Enable completeness scoring
      require_complete: false       # Hard reject results with fewer tracks than expected
      completeness_weight: 500      # Max score bonus for complete albums (0-1000)
      min_completeness_ratio: 0.5   # Below this ratio, no completeness bonus (0.0-1.0)
      file_count_cap: 200           # Max file count score points (0-1000)
      penalize_excess: true         # Reduce score for more files than expected
      excess_decay_rate: 2.0        # Penalty aggressiveness for excess files (0.0-10.0)

  # Interactive selection mode (optional)
  # Allows manual review and selection of search results before downloading
  selection:
    mode: "auto"                  # "auto" (default) or "manual"
    timeout_hours: 24             # Hours before pending selection expires (0 = no timeout)

# =============================================================================
# Catalog Discovery
# Find new artists similar to ones you already own
# =============================================================================
catalog_discovery:
  # Enable/disable catalog discovery
  enabled: true

  # Subsonic server connection (Navidrome, Gonic, Airsonic, etc.)
  # Note: "navidrome:" key is deprecated but still supported for backward compatibility
  subsonic:
    host: "http://navidrome:4533"
    username: "your_username"
    password: "your_password"

  # Last.fm API (get free key from https://www.last.fm/api/account/create)
  lastfm:
    api_key: "your_lastfm_api_key"

  # ListenBrainz (optional) - no API key needed
  # Uses ListenBrainz Labs similar artists API
  listenbrainz:
    enabled: true

  # Maximum new artists to discover per run
  max_artists_per_run: 10

  # Minimum similarity score (0-1)
  # Higher = safer bets, lower = more adventurous
  # 0.3 is a good balance
  min_similarity: 0.3

  # Number of similar artists to fetch per library artist
  similar_artist_limit: 10

  # Number of albums to queue per discovered artist
  albums_per_artist: 3

  # Approval mode: "auto" or "manual"
  mode: "manual"

# =============================================================================
# Library Duplicate Detection (Optional)
# Avoid downloading albums you already own
# Requires catalog_discovery.subsonic to be configured
# =============================================================================
library_duplicate:
  # Enable library duplicate checking
  enabled: true

  # Auto-reject items that already exist in your library
  # If false, items are just marked as "In Library" for manual review
  auto_reject: false

# =============================================================================
# Library Organization (Optional)
# Move completed slskd downloads into your music library
# =============================================================================
library_organize:
  # Enable library organization
  enabled: false

  # Where slskd saves completed downloads (must be accessible to DeepCrate)
  # This path must be mounted as a volume in your docker-compose.yaml
  downloads_path: "/downloads/complete"

  # Destination music library path (must be accessible to DeepCrate)
  # This path must be mounted as a volume in your docker-compose.yaml
  library_path: "/music/library"

  # Organization mode: "flat" or "artist_album"
  # flat: Places album folders directly in library_path
  # artist_album: Creates Artist/Album folder structure
  organization: "artist_album"

  # If true, run automatically on an interval (see LIBRARY_ORGANIZE_INTERVAL env var)
  auto_organize: false

  # Delete the source folder after a successful transfer
  delete_after_move: true

  # Trigger a Subsonic server rescan after organizing (requires catalog_discovery.subsonic)
  # Note: "navidrome_rescan:" key is deprecated but still supported for backward compatibility
  subsonic_rescan: false

  # Optional beets integration for tagging/import (requires beets installed in the container)
  beets:
    enabled: false
    command: "beet import --quiet"

# =============================================================================
# Preview Player (Optional)
# Listen to 30-second track previews before approving/rejecting
# =============================================================================
preview:
  # Enable preview player feature (defaults to true)
  enabled: true

  # Optional Spotify fallback (requires Spotify Developer credentials)
  # Deezer is used by default and requires no API key
  spotify:
    enabled: false
    client_id: "your_spotify_client_id"
    client_secret: "your_spotify_client_secret"

# =============================================================================
# Scoring (Optional)
# Control how queue items are scored during discovery
# =============================================================================
scoring:
  # Apply a score bonus to albums with high MusicBrainz community ratings
  # Disable if you prefer scoring based purely on genre and source relevance
  musicbrainz_ratings: true

# =============================================================================
# Web UI Settings
# =============================================================================
ui:
  # Authentication settings
  auth:
    # Enable authentication (strongly recommended)
    enabled: true

    # Auth type: "basic", "api_key", or "proxy"
    type: "basic"

    # For type: "basic"
    username: "admin"
    password: "changeme"    # CHANGE THIS!

    # For type: "api_key"
    # api_key: "your_secret_api_key"

Environment Variables

Environment variables can override or supplement the config file:

VariableDefaultDescription
HOST0.0.0.0Bind address for the server
PORT8080Port for the server
LB_FETCH_INTERVAL21600Seconds between lb-fetch runs (default: 6 hours)
CATALOG_INTERVAL604800Seconds between catalog discovery (default: 7 days)
SLSKD_INTERVAL3600Seconds between download runs (default: 1 hour)
LIBRARY_SYNC_INTERVAL86400Seconds between library sync runs (default: 24 hours)
LIBRARY_ORGANIZE_INTERVAL0Seconds between library organize runs (0 = manual only)
RUN_JOBS_ON_STARTUPtrueRun jobs once on startup (false to disable)
LOG_LEVELdebug (dev), info (prod)Logging level (case-insensitive): debug, info, warn, error
LOG_DIRDATA_PATHDirectory for log files (when file logging is enabled)
LOG_TO_CONSOLEtrueEnable console logging (stdout/stderr)
LOG_TO_FILEfalseEnable file logging
CONFIG_PATH/config/config.yamlPath to config file
DATA_PATH/dataPath to data directory
DEEPCRATE_DB_FILEDATA_PATH/deepcrate.sqliteSQLite DB file path
DEEPCRATE_DB_LOGGINGfalseEnable Sequelize SQL logging (true/false)

Override Config Values via Environment

Config values can be overridden using environment variables with the DEEPCRATE_ prefix:

bash
# Override ListenBrainz username
DEEPCRATE_LISTENBRAINZ__USERNAME=myuser

# Override slskd host
DEEPCRATE_SLSKD__HOST=http://10.100.0.11:5030

# Override catalog discovery enabled
DEEPCRATE_CATALOG_DISCOVERY__ENABLED=false

Note: Use double underscore __ for nested keys.

Configuration Sections

ListenBrainz

KeyTypeRequiredDefaultDescription
usernamestringYes-Your ListenBrainz username
tokenstringNo*-API token from LB settings
approval_modestringNomanualauto or manual
source_typestringNoweekly_playlistweekly_playlist or collaborative

*Required if source_type: collaborative

Source Types:

  • weekly_playlist (default) - Uses ListenBrainz's weekly exploration playlists. These are curated playlists generated for your profile based on collaborative filtering. No API token required.
  • collaborative - Uses the collaborative filtering recommendation API directly based on your listening history. Requires an API token from your ListenBrainz settings.

Mode Settings

KeyTypeRequiredDefaultDescription
debugboolNofalseEnable debug logging/features
modestringNoalbumalbum or track
min_scorefloatNo0Minimum recommendation score (0-100, or 0-1 as a fraction)
fetch_countintNo100Recommendations per run

slskd

KeyTypeRequiredDefaultDescription
hoststringYes-slskd API URL
api_keystringYes-slskd API key
url_basestringNo/URL base path
search_timeoutintNo15000Search timeout (ms), legacy - prefer search.search_timeout_ms
min_album_tracksintNo3Min tracks for album, legacy - prefer search.min_response_files

slskd Search (Advanced)

Optional advanced search configuration under slskd.search:

KeyTypeDefaultDescription
album_query_templatestring{artist} - {album}Template for album searches. Variables: {artist}, {album}, {year}
track_query_templatestring{artist} - {title}Template for track searches. Variables: {artist}, {title}
fallback_queriesstring[][]Queries to try if primary fails (e.g., ["{album}", "{artist} {album} {year}"])
exclude_termsstring[][]Terms to remove from queries (e.g., ["live", "remix"])
search_timeout_msint15000Timeout for slskd search API call
max_wait_msint20000Max time to wait for search completion
min_response_filesint3Minimum files to consider a valid result
max_responses_to_evaluateint50Limit responses to evaluate (performance)
min_file_size_mbfloat1Minimum file size in MB
max_file_size_mbfloat500Maximum file size in MB
prefer_complete_albumsbooltrueBonus score for results with enough tracks
prefer_album_folderbooltrueBonus score for proper folder structure

slskd Search Retry

Optional retry configuration under slskd.search.retry:

KeyTypeDefaultDescription
enabledboolfalseEnable retry with fallback queries
max_attemptsint3Total attempts including primary
simplify_on_retrybooltrueSimplify query on retry (remove diacritics, special chars)
delay_between_retries_msint5000Delay between retry attempts

slskd Quality Preferences

Optional quality preferences configuration under slskd.search.quality_preferences:

KeyTypeDefaultDescription
enabledbooltrueEnable quality-based filtering and scoring
preferred_formatsstring[]["flac", "wav", "alac", "mp3", "m4a", "ogg"]Formats to prioritize (bonus scoring)
min_bitrateint256Minimum acceptable bitrate (kbps) for lossy formats
prefer_losslessbooltrueGive lossless formats higher priority in scoring
reject_low_qualityboolfalseHard reject files below min_bitrate (vs just deprioritize)
reject_losslessboolfalseHard reject lossless files (for users who only want lossy formats)

Quality Tiers:

  • Lossless - FLAC, WAV, ALAC, AIFF (highest priority by default)
  • High - 320+ kbps lossy (MP3, AAC, OGG, etc.)
  • Standard - 256-319 kbps lossy
  • Low - Below 256 kbps lossy

When reject_low_quality: true, files in the "Low" tier are filtered out entirely. When false, they are just scored lower and deprioritized.

When reject_lossless: true, lossless files (FLAC, WAV, ALAC, AIFF) are filtered out entirely. This is useful for users with limited storage who only want lossy formats.

slskd Completeness Scoring

Optional completeness scoring configuration under slskd.search.completeness:

KeyTypeDefaultDescription
enabledbooltrueEnable completeness scoring using MusicBrainz/Deezer track data
require_completeboolfalseHard reject results with fewer tracks than expected
completeness_weightint500Max score bonus for complete albums (0-1000)
min_completeness_ratiofloat0.5Below this ratio, no completeness bonus is given (0.0-1.0)
file_count_capint200Maximum file count score points (0-1000). When expected track count is known, this is the peak score awarded at an exact match; when unknown, it caps the fallback fileCount * 10 formula
penalize_excessbooltrueReduce score for results with more files than expected
excess_decay_ratefloat2.0How aggressively to penalize excess files (0.0-10.0)

Scoring Algorithm:

The download scoring algorithm evaluates each search result and produces a scorePercent (0-100%) normalized from these components:

  • Slot (0-100): Bonus for peers with a free upload slot
  • Quality (0-1600): Based on audio format, bitrate, and lossless preference
  • File count (0-file_count_cap): Peaks at the expected track count, decays for excess files
  • Upload speed (0-100): Bonus capping at 1 MB/s
  • Completeness (0-completeness_weight): Proportional bonus based on how complete the album is

When expected track count is unavailable (metadata lookup fails), scoring falls back to file_count * 10 (capped at file_count_cap) with no completeness bonus. In this fallback mode, file_count_cap simply limits the raw file-count score; when expected track count is known, it instead serves as the peak score at an exact match, with decay applied for excess files.

Track counts are resolved via MusicBrainz (primary, uses median of official releases) with Deezer as fallback.

slskd Interactive Selection

Optional interactive selection configuration under slskd.selection:

KeyTypeDefaultDescription
modestringautoauto (automatic best-match) or manual (user selects from results)
timeout_hoursint24Hours before pending selection expires and fails (0 = no timeout)

Selection Modes:

  • auto - Default behavior. Automatically selects the best matching result based on quality, file count, and user availability.
  • manual - Shows all search results in the UI for manual review. Users can compare sources, view file lists, and choose the preferred download source.

When mode: manual, downloads enter a pending_selection status after search completes. Users can:

  • View all available sources with quality info and file counts
  • Expand results to see individual files
  • Select a specific source to download from
  • Skip sources they don't want
  • Edit the search query and retry
  • Use auto-select to let the algorithm choose

If timeout_hours is set and the user doesn't select within that time, the download is marked as failed.

Catalog Discovery

KeyTypeRequiredDefaultDescription
enabledboolNofalseEnable catalog discovery
subsonic.hoststringYes*-Subsonic server URL (Navidrome, Gonic, Airsonic, etc.)
subsonic.usernamestringYes*-Subsonic server username
subsonic.passwordstringYes*-Subsonic server password
lastfm.api_keystringNo-Last.fm API key (enables Last.fm provider)
listenbrainz.enabledboolNotrueEnable ListenBrainz similarity provider (no API key needed)
max_artists_per_runintNo10Max new artists per run
min_similarityfloatNo0.3Min similarity (0-1)
similar_artist_limitintNo10Similar artists per query
albums_per_artistintNo3Albums per new artist
modestringNomanualauto or manual

*Required if enabled: true. At least one similarity provider (lastfm or listenbrainz) must be configured when enabled.

Note: The navidrome key is deprecated but still supported for backward compatibility. Use subsonic for new configurations.

Similarity Providers:

Catalog discovery uses similarity providers to find artists related to your library. At least one provider must be configured when catalog discovery is enabled.

  • Last.fm - Requires API key from last.fm/api. Well-established similarity data.
  • ListenBrainz - No API key required. Uses ListenBrainz Labs similar artists API.

When both providers are configured, results are combined and artists found by multiple providers receive higher scores.

Library Duplicate Detection

KeyTypeRequiredDefaultDescription
enabledboolNofalseEnable library duplicate checking
auto_rejectboolNofalseAuto-reject items already in library

Requires catalog_discovery.subsonic to be configured for library sync.

Library Organization

KeyTypeRequiredDefaultDescription
enabledboolNofalseEnable library organization
downloads_pathstringYes*-Where slskd writes completed downloads
library_pathstringYes*-Destination music library path
organizationstringNoartist_albumflat or artist_album. flat: Places album folders directly in library_path artist_album: Creates Artist/Album folder structure
auto_organizeboolNofalseEnable scheduling (requires LIBRARY_ORGANIZE_INTERVAL > 0)
delete_after_moveboolNotrueDelete source after organizing
subsonic_rescanboolNofalseTrigger Subsonic server startScan after organizing
beets.enabledboolNofalseRun beets import before moving
beets.commandstringNobeet import --quietbeets command (import path is appended)

*Required if enabled: true

If subsonic_rescan: true, catalog_discovery.subsonic must be configured.

Note: The navidrome_rescan key is deprecated but still supported for backward compatibility.

Preview Player

KeyTypeRequiredDefaultDescription
enabledboolNotrueEnable preview player feature
spotify.enabledboolNofalseEnable Spotify as fallback source
spotify.client_idstringYes*-Spotify application client ID
spotify.client_secretstringYes*-Spotify application client secret

*Required if spotify.enabled: true

The preview player uses Deezer by default (no API key required). Spotify can be enabled as a fallback for tracks not found on Deezer. Get Spotify credentials from the Spotify Developer Dashboard.

Note: Preview clips are limited to 30 seconds by the streaming services (Deezer/Spotify). This is an industry-standard limitation to protect copyrighted content.

Scoring

KeyTypeRequiredDefaultDescription
musicbrainz_ratingsboolNotrueApply a score bonus to albums with high MusicBrainz community ratings

When enabled, albums that have a positive community rating in MusicBrainz receive a score bonus during discovery. Disable to base scoring purely on genre relevance and source signals.

UI Authentication

KeyTypeRequiredDefaultDescription
enabledboolNofalseEnable authentication
typestringNobasicbasic, api_key, proxy
usernamestringYes*-Username for basic auth
passwordstringYes*-Password for basic auth
api_keystringYes**-API key for api_key auth

*Required if type: basic **Required if type: api_key

Auth Mode Behaviors:

ModeLogin UIAPI HeaderUsername Source
basicUsername + Password formAuthorization: Basic <credentials>Config username
api_keyAPI Key input fieldAuthorization: Bearer <token>"API User"
proxyAuto-redirect (no login)None (proxy handles auth)Remote-User header
disabledAuto-redirect (no login)None"Guest"

When enabled: false, the UI behaves the same as proxy mode - users are automatically authenticated and redirected to the dashboard.

Minimal Configuration

The bare minimum to run DeepCrate with ListenBrainz only:

yaml
listenbrainz:
  username: "your_username"
  # token not required for weekly_playlist mode (default)

slskd:
  host: "http://slskd:5030"
  api_key: "your_api_key"

Docker Compose with Environment

yaml
services:
  deepcrate:
    image: ghcr.io/jordojordo/deepcrate:latest
    environment:
      - LB_FETCH_INTERVAL=21600
      - CATALOG_INTERVAL=604800
      - SLSKD_INTERVAL=3600
      - LOG_LEVEL=info
    volumes:
      - ./config.yaml:/config/config.yaml:ro
      - ./data:/data
    ports:
      - "8080:8080"

Config Validation

On startup, DeepCrate validates the configuration and logs any issues:

2026-01-11 10:00:00 - INFO - Loading configuration from /config/config.yaml
2026-01-11 10:00:00 - INFO - ListenBrainz: enabled (user: saybis)
2026-01-11 10:00:00 - INFO - Catalog Discovery: enabled
2026-01-11 10:00:00 - INFO - slskd: http://10.100.0.11:5030
2026-01-11 10:00:00 - INFO - Web UI auth: basic

If required fields are missing:

2026-01-11 10:00:00 - ERROR - Missing required config: listenbrainz.token

Secrets Management

For production, avoid putting secrets directly in config files:

Option 1: Environment Variables

yaml
listenbrainz:
  username: "my-user-name"
  token: "${LISTENBRAINZ_TOKEN}"  # Populated from env

Option 2: Docker Secrets

yaml
# docker-compose.yaml
services:
  deepcrate:
    secrets:
      - listenbrainz_token
      - slskd_api_key
    environment:
      - DEEPCRATE_LISTENBRAINZ__TOKEN_FILE=/run/secrets/listenbrainz_token

secrets:
  listenbrainz_token:
    file: ./secrets/listenbrainz_token.txt
  slskd_api_key:
    file: ./secrets/slskd_api_key.txt

Option 3: External Secret Manager

For Kubernetes or advanced setups, mount secrets as files and reference via *_FILE environment variables.

Wishlist Import/Export

The UI supports importing and exporting wishlist items as JSON files. This is useful for:

  • Bulk importing wishlists from other sources
  • Backing up your wishlist
  • Migrating between DeepCrate instances

JSON Schema

Import files must be a JSON array of objects with the following structure:

json
[
  {
    "artist": "Artist Name",
    "title": "Album or Track Title",
    "type": "album",
    "year": 2023,
    "mbid": "abc123-def456-...",
    "source": "manual",
    "coverUrl": "https://example.com/cover.jpg"
  }
]

Field Reference

FieldTypeRequiredDescription
artiststringYesArtist name
titlestringYes*Album or track title
typestringYesalbum, track, or artist
yearnumberNoRelease year
mbidstringNoMusicBrainz ID (release-group or recording)
sourcestringNolistenbrainz, catalog, or manual (defaults to manual)
coverUrlstringNoURL to album artwork

*Required for album and track types; optional for artist type.

Example Import File

json
[
  {
    "artist": "Dream Theater",
    "title": "Awake",
    "type": "album",
    "year": 1994
  },
  {
    "artist": "Aphex Twin",
    "title": "Selected Ambient Works 85-92",
    "type": "album",
    "year": 1992,
    "source": "manual"
  },
  {
    "artist": "Boards of Canada",
    "title": "Music Has the Right to Children",
    "type": "album"
  }
]

Import Behavior

  • Duplicates are skipped - Items matching an existing artist/title/type combination are not re-added
  • Validation errors - Invalid items are reported but don't prevent other items from importing
  • Source defaults to manual - If not specified, imported items are marked as manually added

Network Requirements

DeepCrate needs network access to the following services:

ServicePurpose
slskdQueue downloads
NavidromeScan library artists
api.listenbrainz.orgFetch recommendations
ws.audioscrobbler.comLast.fm similar artists
musicbrainz.orgAlbum metadata
coverartarchive.orgAlbum artwork
api.deezer.comAudio previews (default)
api.spotify.comAudio previews (optional fallback)