Skip to content

Latest commit

 

History

History
1126 lines (846 loc) · 23 KB

File metadata and controls

1126 lines (846 loc) · 23 KB

Tidarr API Documentation

This documentation describes how to use the Tidarr REST API to automate downloads and manage your instance.

Table of Contents


Basic Configuration

API Base URL: http://your-host:8484

All API endpoints (except /api/is-auth-active) require authentication if ADMIN_PASSWORD is set in your Docker configuration.


Authentication

Tidarr supports two authentication methods:

Method 1: API Key (Recommended for automation)

The API key is automatically generated on first startup and stored in /shared/.tidarr-api-key.

Get your API key:

# Via Docker
docker exec tidarr cat /shared/.tidarr-api-key

# Or via Web UI: Settings → Authentication → API Key

Use it in requests:

# Via header (recommended)
curl http://localhost:8484/api/settings \
  -H "X-Api-Key: your-api-key"

# Via query parameter
curl "http://localhost:8484/api/settings?apikey=your-api-key"

Advantages:

  • ✅ Secure random 64-character key
  • ✅ No expiration (unlike JWT tokens)
  • ✅ Standard for *arr applications
  • ✅ Can be regenerated anytime

Management endpoints:

Get current API key (requires JWT):

GET /api/api-key

Regenerate API key (requires JWT):

POST /api/api-key/regenerate

⚠️ Warning: Invalidates the current key. Update it everywhere it's used.


Method 2: JWT Token (For web UI and interactive sessions)

Login:

curl -X POST http://localhost:8484/api/auth \
  -H 'Content-Type: application/json' \
  -d '{"password": "your_password"}'

Response:

{
  "status": "ok",
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Use the token:

curl http://localhost:8484/api/settings \
  -H "Authorization: Bearer your-jwt-token"

Check if authentication is active

GET /api/is-auth-active

Response:

{
  "isAuthActive": true,
  "authType": "password"
}

Possible authType values:

  • "password" - Password authentication (ADMIN_PASSWORD)
  • "oidc" - OpenID Connect authentication
  • null - No authentication configured

Note: All examples below use the API key method (X-Api-Key header).


Method 3: OpenID Connect (OIDC) Authentication

Tidarr supports OIDC authentication for integration with identity providers like Keycloak, PocketID, Authentik, etc.

Initiate OIDC login:

GET /api/auth/oidc/login

Redirects the user to the configured OIDC provider for authentication.

OIDC callback:

GET /api/auth/oidc/callback

Handles the OIDC callback and issues a JWT token. Redirects to the frontend with the token.

Required environment variables:

  • OIDC_ISSUER - The URL of your OpenID Connect provider
  • OIDC_CLIENT_ID - The client ID registered in your OIDC provider
  • OIDC_CLIENT_SECRET - The client secret for your application
  • OIDC_REDIRECT_URI - The callback URL (e.g., https://your-tidarr-domain.com/api/auth/oidc/callback)

Playback Endpoints

Generate signed streaming URL

GET /api/stream/sign/:id

Generates a time-limited signed URL for audio streaming.

Parameters:

  • id - The Tidal track ID

Example:

curl http://localhost:8484/api/stream/sign/123456789 \
  -H "X-Api-Key: your-api-key"

Response:

{
  "url": "/api/stream/play/123456789?exp=1234567890&sig=abc123..."
}

Note: The signed URL expires after 5 minutes.


Play audio stream

GET /api/stream/play/:id?exp={expiration}&sig={signature}

Streams audio content with signature validation. Supports range requests for seeking.

Parameters:

  • id - The Tidal track ID
  • exp - Expiration timestamp (from signed URL)
  • sig - Signature (from signed URL)

Note: This endpoint is typically called via the signed URL obtained from /api/stream/sign/:id.


Download Endpoints

Add an item to the download queue

Endpoint: POST /api/save

Important: Use full Tidal URLs (not numeric IDs). The id field is required and must be a non-empty string or number, unique within the queue (use the Tidal numeric ID for URL-based items, or the type value for favorites).

Supported types: album, track, video, playlist, mix, artist, artist_videos, favorite_albums, favorite_tracks, favorite_playlists, favorite_videos, favorite_artists

quality: Optional. If omitted, Tidarr uses the server's configured default quality (download.track_quality in config.toml).

Album

curl -X POST http://localhost:8484/api/save \
  -H "X-Api-Key: your-api-key" \
  -H 'Content-Type: application/json' \
  -d '{
    "item": {
      "id": "251082404",
      "url": "https://listen.tidal.com/album/251082404",
      "type": "album",
      "status": "queue_download"
    }
  }'

Track

curl -X POST http://localhost:8484/api/save \
  -H "X-Api-Key: your-api-key" \
  -H 'Content-Type: application/json' \
  -d '{
    "item": {
      "id": "123456789",
      "url": "https://listen.tidal.com/track/123456789",
      "type": "track",
      "status": "queue_download"
    }
  }'

Video

curl -X POST http://localhost:8484/api/save \
  -H "X-Api-Key: your-api-key" \
  -H 'Content-Type: application/json' \
  -d '{
    "item": {
      "id": "123456789",
      "url": "https://listen.tidal.com/video/123456789",
      "type": "video",
      "status": "queue_download"
    }
  }'

Playlist

curl -X POST http://localhost:8484/api/save \
  -H "X-Api-Key: your-api-key" \
  -H 'Content-Type: application/json' \
  -d '{
    "item": {
      "id": "abc123-def456",
      "url": "https://listen.tidal.com/playlist/abc123-def456",
      "type": "playlist",
      "status": "queue_download"
    }
  }'

Mix

curl -X POST http://localhost:8484/api/save \
  -H "X-Api-Key: your-api-key" \
  -H 'Content-Type: application/json' \
  -d '{
    "item": {
      "id": "000000000000000000000000",
      "url": "https://listen.tidal.com/mix/000000000000000000000000",
      "type": "mix",
      "status": "queue_download"
    }
  }'

Artist (all albums)

curl -X POST http://localhost:8484/api/save \
  -H "X-Api-Key: your-api-key" \
  -H 'Content-Type: application/json' \
  -d '{
    "item": {
      "id": "3566315",
      "url": "https://listen.tidal.com/artist/3566315",
      "type": "artist",
      "status": "queue_download"
    }
  }'

Artist (all videos)

curl -X POST http://localhost:8484/api/save \
  -H "X-Api-Key: your-api-key" \
  -H 'Content-Type: application/json' \
  -d '{
    "item": {
      "id": "3566315",
      "url": "https://listen.tidal.com/artist/3566315",
      "type": "artist_videos",
      "status": "queue_download"
    }
  }'

Favorites

# Favorite albums
curl -X POST http://localhost:8484/api/save \
  -H "X-Api-Key: your-api-key" \
  -H 'Content-Type: application/json' \
  -d '{
    "item": {
      "id": "favorite_albums",
      "type": "favorite_albums",
      "status": "queue_download"
    }
  }'

# Favorite tracks
curl -X POST http://localhost:8484/api/save \
  -H "X-Api-Key: your-api-key" \
  -H 'Content-Type: application/json' \
  -d '{
    "item": {
      "id": "favorite_tracks",
      "type": "favorite_tracks",
      "status": "queue_download"
    }
  }'

# Favorite playlists
curl -X POST http://localhost:8484/api/save \
  -H "X-Api-Key: your-api-key" \
  -H 'Content-Type: application/json' \
  -d '{
    "item": {
      "id": "favorite_playlists",
      "type": "favorite_playlists",
      "status": "queue_download"
    }
  }'

# Favorite videos
curl -X POST http://localhost:8484/api/save \
  -H "X-Api-Key: your-api-key" \
  -H 'Content-Type: application/json' \
  -d '{
    "item": {
      "id": "favorite_videos",
      "type": "favorite_videos",
      "status": "queue_download"
    }
  }'

# Favorite artists
curl -X POST http://localhost:8484/api/save \
  -H "X-Api-Key: your-api-key" \
  -H 'Content-Type: application/json' \
  -d '{
    "item": {
      "id": "favorite_artists",
      "type": "favorite_artists",
      "status": "queue_download"
    }
  }'

Response: 201 Created


Remove an item from the queue

curl -X DELETE http://localhost:8484/api/remove \
  -H "X-Api-Key: your-api-key" \
  -H 'Content-Type: application/json' \
  -d '{"id": "12345"}'

Response: 204 No Content


Clear the entire queue

curl -X DELETE http://localhost:8484/api/remove-all \
  -H "X-Api-Key: your-api-key"

Response: 204 No Content


Remove finished items

curl -X DELETE http://localhost:8484/api/remove-finished \
  -H "X-Api-Key: your-api-key"

Response: 204 No Content


Retry failed items

Resets every item currently in error status back to queue_download. Items with any other status are left unchanged.

curl -X POST http://localhost:8484/api/retry-failed \
  -H "X-Api-Key: your-api-key"

Response: 204 No Content


Queue Management

Get queue list

Supports optional pagination via offset and limit query parameters.

curl http://localhost:8484/api/queue/list \
  -H "X-Api-Key: your-api-key"

# Paginated
curl "http://localhost:8484/api/queue/list?offset=0&limit=50" \
  -H "X-Api-Key: your-api-key"

Response:

{
  "total": 42,
  "offset": 0,
  "limit": null,
  "queue": [
    {
      "id": "251082404",
      "type": "album",
      "title": "Album Name",
      "artist": "Artist Name",
      "quality": "max",
      "status": "finished",
      "url": "http://www.tidal.com/album/251082404",
      "loading": false,
      "error": false
    }
  ]
}

Possible status values: queue_download, download, queue_processing, processing, finished, error

errorStage: Present only when status is error. "download" means the download itself failed or never fully completed — retry via Retry post-processing if files are present, or a normal re-add otherwise. "post_processing" means the download succeeded but a later step (move, tagging, ...) failed — use Retry post-processing to retry just that step.

limit is null when no limit is specified (all items returned).


Pause the queue

curl -X POST http://localhost:8484/api/queue/pause \
  -H "X-Api-Key: your-api-key"

Response: 204 No Content

Behavior:

  • Stops processing new items
  • Cancels current download and resets it to "queue" status
  • Cleans up incomplete downloads

Resume the queue

curl -X POST http://localhost:8484/api/queue/resume \
  -H "X-Api-Key: your-api-key"

Response: 204 No Content


Get queue status

curl http://localhost:8484/api/queue/status \
  -H "X-Api-Key: your-api-key"

Response:

{
  "isPaused": false,
  "batchCount": 0,
  "batchResumeAt": null
}

batchCount/batchResumeAt: Only relevant when DOWNLOAD_BATCH_SIZE is set. batchCount is the number of items downloaded in the current batch; batchResumeAt is a timestamp (ms) for the scheduled auto-resume, or null if not paused for batching.

Single download (NO_DOWNLOAD mode)

Trigger a one-off download for a specific queued item, bypassing the NO_DOWNLOAD mode pause. The item goes through the full download pipeline (beets, move to library, notifications) and ends up as finished on success, or error if the download fails (see errorStage above for what to do next).

curl -X POST http://localhost:8484/api/single-download \
  -H "X-Api-Key: your-api-key" \
  -H 'Content-Type: application/json' \
  -d '{"id": "251082404"}'

Response: 204 No Content

Behavior:

  • Item is downloaded immediately, bypassing the paused queue
  • Full post-processing pipeline runs (beets, permissions, move, notifications)
  • Item ends as finished in the queue

Error: 500 if the item is not found.


Retry post-processing

Retries tagging/move for an item stuck in error status, without re-downloading. Useful when the download itself succeeded but a later step (e.g. moving files to the library) failed, for example due to wrong permissions on the library folder — fix the underlying issue, then retry just this step. Relies on the downloaded files still being present in the item's processing folder (kept automatically when a move fails, and also when a download was interrupted partway through — e.g. a network drop mid-album keeps whatever tracks were already downloaded).

curl -X POST http://localhost:8484/api/retry-post-processing \
  -H "X-Api-Key: your-api-key" \
  -H 'Content-Type: application/json' \
  -d '{"id": "251082404"}'

Response: 204 No Content

Behavior:

  • Re-runs the full post-processing pipeline (tagging, permissions, move, notifications) using the files already downloaded
  • Does not call tiddl again — no network request to Tidal
  • Item ends as finished on success, or stays error if it fails again

Error: 500 if the item is not found, not in error status, or if another item is currently post-processing.


History Endpoints

Note: History requires ENABLE_HISTORY=true in Docker configuration.

Get download history

curl http://localhost:8484/api/history/list \
  -H "X-Api-Key: your-api-key"

Response:

["251082404", "77610756", "123456789"]

Clear history

curl -X DELETE http://localhost:8484/api/history/list \
  -H "X-Api-Key: your-api-key"

Response: 204 No Content


Configuration Endpoints

Get Tidarr configuration

curl http://localhost:8484/api/settings \
  -H "X-Api-Key: your-api-key"

Response:

{
  "noToken": false,
  "quality": "high",
  "enableBeetsAutotag": true,
  "enablePlexUpdate": true,
  "tiddl_config": {
    "auth": {
      "token": "...",
      "refresh_token": "..."
    },
    "format": {
      "quality": "high",
      "album_template": "{album_artist}/{album}/{number:02d}. {title}"
    }
  }
}

Run Tidal authentication flow

GET /api/run-token

SSE endpoint that initiates the Tidal device authentication flow. Opens a stream that sends authentication events (login URL, status updates) until authentication completes or fails.

Response: text/event-stream

Note: This endpoint is used by the web UI during initial Tidal setup. Events are streamed until authentication completes.


Delete Tidal token

curl -X DELETE http://localhost:8484/api/token \
  -H "X-Api-Key: your-api-key"

Response: 204 No Content


Get Tiddl TOML configuration

curl http://localhost:8484/api/tiddl/config \
  -H "X-Api-Key: your-api-key"

Response:

{
  "toml": "[download]\nquality = \"high\"\nthreads = 6\n..."
}

Save Tiddl TOML configuration

curl -X POST http://localhost:8484/api/tiddl/config \
  -H "X-Api-Key: your-api-key" \
  -H 'Content-Type: application/json' \
  -d '{
    "toml": "[download]\nquality = \"max\"\nthreads = 8\n..."
  }'

Response:

{
  "success": true,
  "message": "Tiddl config saved successfully"
}

Synchronization Endpoints

Get synchronized playlists

curl http://localhost:8484/api/sync/list \
  -H "X-Api-Key: your-api-key"

Response:

[
  {
    "id": "abc123-def456",
    "title": "My Playlist",
    "url": "https://listen.tidal.com/playlist/abc123-def456",
    "type": "playlist"
  }
]

Add playlist to sync

curl -X POST http://localhost:8484/api/sync/save \
  -H "X-Api-Key: your-api-key" \
  -H 'Content-Type: application/json' \
  -d '{
    "item": {
      "id": "abc123-def456",
      "title": "My Playlist",
      "url": "https://listen.tidal.com/playlist/abc123-def456",
      "type": "playlist"
    }
  }'

Response: 201 Created


Remove playlist from sync

curl -X DELETE http://localhost:8484/api/sync/remove \
  -H "X-Api-Key: your-api-key" \
  -H 'Content-Type: application/json' \
  -d '{"id": "abc123-def456"}'

Response: 204 No Content


Remove all playlists from sync

curl -X DELETE http://localhost:8484/api/sync/remove-all \
  -H "X-Api-Key: your-api-key"

Response: 204 No Content


Trigger sync now

curl -X POST http://localhost:8484/api/sync/trigger \
  -H "X-Api-Key: your-api-key"

Response: 202 Accepted

Note: Default sync schedule is 0 3 * * * (3 AM daily). Configure with SYNC_CRON_EXPRESSION.


Custom CSS Endpoints

Get custom CSS

curl http://localhost:8484/api/custom-css \
  -H "X-Api-Key: your-api-key"

Response:

{
  "css": "body { background-color: #1a1a1a; }"
}

Save custom CSS

curl -X POST http://localhost:8484/api/custom-css \
  -H "X-Api-Key: your-api-key" \
  -H 'Content-Type: application/json' \
  -d '{
    "css": "body { background-color: #1a1a1a; }"
  }'

Response:

{
  "success": true,
  "message": "Custom CSS saved successfully"
}

Lidarr Integration

Tidarr integrates with Lidarr using:

  1. Newznab Indexer - Search and discover albums
  2. SABnzbd Download Client - Track downloads

📖 Complete setup guide: LIDARR_INTEGRATION.md


Newznab Indexer Endpoints

Base URL: http://your-tidarr-url:8484/api/lidarr

Get Capabilities

GET /api/lidarr?t=caps

Example:

curl "http://localhost:8484/api/lidarr?t=caps&apikey=your-api-key"

Response: XML capabilities document


Search Albums

GET /api/lidarr?t=search&q={query}
GET /api/lidarr?t=music&artist={artist}&album={album}

Parameters:

  • t - Request type: search or music
  • q - Search query
  • artist - Artist name (for t=music)
  • album - Album name (for t=music)

Examples:

# General search
curl "http://localhost:8484/api/lidarr?t=search&q=Daft%20Punk&apikey=your-api-key"

# Artist + Album search
curl "http://localhost:8484/api/lidarr?t=music&artist=Daft%20Punk&album=Random%20Access%20Memories&apikey=your-api-key"

Response: Newznab XML with results


Download Album

GET /api/lidarr/download/{albumId}/{quality}

Parameters:

  • albumId - The Tidal album ID
  • quality - Download quality: max (24-bit), high (16-bit), normal (AAC-320), low (AAC-96)

Example:

curl "http://localhost:8484/api/lidarr/download/34277251/high?apikey=your-api-key"

Response: NZB file format


SABnzbd Download Client Endpoints

Base URL: http://your-tidarr-url:8484/api/sabnzbd/api

Get Version

GET /api/sabnzbd/api?mode=version

Example:

curl "http://localhost:8484/api/sabnzbd/api?mode=version&apikey=your-api-key"

Response:

{
  "version": "3.0.0"
}

Add Download

GET /api/sabnzbd/api?mode=addurl&name={url}
POST /api/sabnzbd/api?mode=addfile  # multipart/form-data with NZB file

Example:

curl "http://localhost:8484/api/sabnzbd/api?mode=addurl&name=https://listen.tidal.com/album/34277251&apikey=your-api-key"

Response:

{
  "status": true,
  "nzo_ids": ["tidarr-34277251-1234567890"]
}

Get Queue

GET /api/sabnzbd/api?mode=queue

Example:

curl "http://localhost:8484/api/sabnzbd/api?mode=queue&apikey=your-api-key"

Response:

{
  "queue": {
    "status": "Downloading",
    "slots": [
      {
        "nzo_id": "tidarr-34277251-1234567890",
        "filename": "Daft Punk - Random Access Memories",
        "status": "Downloading"
      }
    ]
  }
}

Status mapping:

  • Downloading - Currently processing
  • Queued - Waiting in queue
  • Paused - Queue paused

Delete from Queue

GET /api/sabnzbd/api?mode=queue&name=delete&value={nzo_id}

Example:

curl "http://localhost:8484/api/sabnzbd/api?mode=queue&name=delete&value=tidarr_nzo_34277251&apikey=your-api-key"

Response:

{
  "status": true,
  "nzo_ids": ["tidarr_nzo_34277251"]
}

Get History

GET /api/sabnzbd/api?mode=history&limit={n}

Example:

curl "http://localhost:8484/api/sabnzbd/api?mode=history&limit=50&apikey=your-api-key"

Response:

{
  "history": {
    "slots": [
      {
        "nzo_id": "tidarr-34277251-1234567890",
        "name": "Daft Punk - Random Access Memories",
        "status": "Completed",
        "storage": "/music/Daft Punk/2013 - Random Access Memories"
      }
    ]
  }
}

Status mapping:

  • Completed - Successfully downloaded
  • Failed - Download failed

Delete from History

GET /api/sabnzbd/api?mode=history&name=delete&value={nzo_id}

Example:

curl "http://localhost:8484/api/sabnzbd/api?mode=history&name=delete&value=tidarr_nzo_34277251&apikey=your-api-key"

Response:

{
  "status": true,
  "nzo_ids": ["tidarr_nzo_34277251"]
}

Usage Examples

Bash: Download multiple albums

#!/bin/bash

TIDARR_URL="http://localhost:8484"
TIDARR_API_KEY=$(docker exec tidarr cat /shared/.tidarr-api-key)

albums=(
  "251082404 https://listen.tidal.com/album/251082404"
  "123456789 https://listen.tidal.com/album/123456789"
)

for entry in "${albums[@]}"; do
  id="${entry%% *}"
  album="${entry#* }"
  echo "Adding $album..."
  curl -s -X POST $TIDARR_URL/api/save \
    -H "X-Api-Key: $TIDARR_API_KEY" \
    -H 'Content-Type: application/json' \
    -d "{
      \"item\": {
        \"id\": \"$id\",
        \"url\": \"$album\",
        \"type\": \"album\",
        \"status\": \"queue_download\"
      }
    }"
  echo ""
done

Python: Add to queue

#!/usr/bin/env python3
import requests

TIDARR_URL = "http://localhost:8484"
API_KEY = "your-api-key"

headers = {"X-Api-Key": API_KEY}

album_data = {
    "item": {
        "id": "251082404",
        "url": "https://listen.tidal.com/album/251082404",
        "type": "album",
        "status": "queue_download"
    }
}

requests.post(f"{TIDARR_URL}/api/save", headers=headers, json=album_data)
print("Album added to queue")

Docker: Direct download

docker compose exec tidarr tiddl download url https://listen.tidal.com/album/251082404

HTTP Status Codes

  • 200 OK - Success
  • 201 Created - Resource created
  • 202 Accepted - Async operation accepted
  • 204 No Content - Deletion successful
  • 400 Bad Request - Invalid data
  • 403 Forbidden - Invalid API key/token
  • 404 Not Found - Resource not found
  • 500 Internal Server Error - Server error

Part of this documentation was generated with AI assistance