Configuration
The service is configured by a TOML file named config.toml in the current
working directory. A template with sensible defaults lives at
config.example.toml in the repository root.
cp config.example.toml config.toml
The schema is validated at startup by Pydantic
(passive_music_dl/config/models.py); a malformed config exits with code 1.
Full reference
[download]
output_dir = "/srv/music" # Base directory for downloads (required)
file_format = "mp3" # Output format: mp3, m4a, ogg, flac, opus
audio_quality = "best" # Audio quality (0-10 for yt-dlp)
[schedule]
interval_minutes = 15 # How often to check for new tracks
[spotify]
enabled = true
client_id = "your_spotify_client_id" # Required
client_secret = "your_spotify_client_secret" # Required
redirect_uri = "http://127.0.0.1:8080"
playlists = [
"37i9dQZEVXbNG2KDcFcKOF" # Bare playlist IDs, not URIs
]
[spotify.auth]
cache_path = ".spotipy-cache" # Directory holding spotipy's cached OAuth token
[youtube_music]
enabled = true
# auth_headers = "auth.json" # Optional: needed for private playlists
playlists = [
"PL4fGSI1pDJn6puJdseH2Rt9sMvt9E2M4i"
]
[logging]
level = "info" # notset, debug, info, warning, error, critical
Sections
[download]
The download section is required. All keys are required.
| Key | Required | Default | Description |
|---|---|---|---|
output_dir |
yes | - | Directory that tracks are downloaded into. ~ is expanded. |
file_format |
yes | - | Output codec: mp3, m4a, ogg, flac, or opus. |
audio_quality |
yes | - | Quality argument passed to yt-dlp (0-10 for VBR codecs, or best). |
Tracks are written directly into output_dir as {track_title}.{file_format};
there is no per-playlist subdirectory.
[schedule]
The schedule section is optional and defaults to an empty one.
| Key | Required | Default | Description |
|---|---|---|---|
interval_minutes |
no | 15 | Interval between sync cycles. |
[spotify]
Spotify sync is optional; omit the section to disable it. client_id and
client_secret are required when the section is present. Secrets are read
literally from the file; there is no environment-variable expansion. config.toml
is git-ignored, so the file can be kept out of version control.
| Key | Required | Default | Description |
|---|---|---|---|
enabled |
no | true |
Set to false to skip Spotify. |
client_id |
yes | - (required) | Spotify app client ID. |
client_secret |
yes | - (required) | Spotify app client secret. |
redirect_uri |
no | http://127.0.0.1:8080 |
Must match the app's registered redirect URI. |
playlists |
no | [] |
Bare Spotify playlist IDs. |
auth.cache_path |
no | .spotipy-cache |
Directory spotipy uses to cache its OAuth token. |
On first run the app prompts to authenticate (headed or headless); the token is
cached in cache_path and auto-refreshes afterwards.
[youtube_music]
YouTube Music sync is optional; omit the section to disable it.
| Key | Required | Default | Description |
|---|---|---|---|
enabled |
no | true |
Set to false to skip YouTube Music. |
auth_headers |
no | None |
Path to a ytmusicapi auth file, required for private playlists. |
playlists |
no | [] |
Bare YouTube Music playlist IDs. |
Public playlists work without auth. For private playlists (e.g. Liked Songs),
generate an auth file with ytmusicapi oauth --file auth.json and point
auth_headers at it.
[logging]
The logging section is optional and defaults to an empty one.
| Key | Required | Default | Description |
|---|---|---|---|
level |
no | info |
One of notset, debug, info, warning, error, critical. |
Keeping secrets out of version control
config.toml holds the Spotify client secret in plain text and is git-ignored;
.spotipy-cache (the cached OAuth token) is also git-ignored. There is no
environment-variable expansion in the config — put the real secret in
config.toml and rely on .gitignore to keep it out of the repository.