Skip to content

Instantly share code, notes, and snippets.

@alexsleat
Forked from jackskhakis/add_artists.sh
Last active September 22, 2025 15:17
Show Gist options
  • Select an option

  • Save alexsleat/612c1b0eee364ead539bbe2bfcb3e743 to your computer and use it in GitHub Desktop.

Select an option

Save alexsleat/612c1b0eee364ead539bbe2bfcb3e743 to your computer and use it in GitHub Desktop.
Script to add list of artists (in a folder) to lidarr, this method bypasses the difficulties that are currently present in lidarr with relation to searching and adding new artists. This version searches MusicBrainz for the ID to use, rather than relying only on lidarr search - it then uses the lidarr:music_brainz_id method to add them, if they a…
#!/bin/bash
# Folder where existing artist folders are located (source)
source_dir="/media/old"
# The Lidarr root folder path to add new artists under
lidarr_root="/media/new"
## Note: You can use this script with the source_dir and lidarr_root dir are the same - I did and nothing broke.
# Lidarr API access
lidarr_url="http://localhost:8686"
api_key="YOUR_API_KEY_HERE"
# Set a delay (in seconds) between each add operation to avoid rate limits
delay_between_adds=120
# IDs required by Lidarr – see comments below for how to gather these
quality_profile_id=1
metadata_profile_id=1
# Log file for artists we couldn't safely match
failed_log="failed_artists.txt"
# --- START SCRIPT ---
echo "πŸ“₯ Fetching list of existing artists from Lidarr..."
existing_ids=$(curl -s "$lidarr_url/api/v1/artist" \
-H "X-Api-Key: $api_key" | jq -r '.[].foreignArtistId')
# Loop through each artist folder in the source directory
find "$source_dir" -mindepth 1 -maxdepth 1 -type d | while read -r artist_folder; do
artist_name=$(basename "$artist_folder")
echo "πŸ” Searching for: $artist_name"
# Try Lidarr lookup first
search_result=$(curl -s -G "$lidarr_url/api/v1/artist/lookup" \
--data-urlencode "term=$artist_name" \
-H "X-Api-Key: $api_key")
artist_json=$(echo "$search_result" | jq -r 'if type=="array" and length>0 then .[0] else empty end')
# If not found in Lidarr, try MusicBrainz - collects the ID from the server (uses top search result, if it matches above 85%)
if [ -z "$artist_json" ] || [ "$artist_json" == "null" ]; then
echo "πŸ”Ž Falling back to MusicBrainz for: $artist_name"
# Format the artist name for URLs i.e "Music Band" becomes "Music%20Band"
encoded_name=$(printf '%s' "$artist_name" | jq -sRr @uri)
mb_result=$(curl -s "https://musicbrainz.org/ws/2/artist/?query=$encoded_name&fmt=json&limit=1")
# Collect the score and ID:
mb_score=$(echo "$mb_result" | jq -r '.artists[0].score // empty')
mb_id=$(echo "$mb_result" | jq -r '.artists[0].id // empty')
# Check if the score is above 85 (%)
if [ -n "$mb_score" ] && [ "$mb_score" -ge 85 ]; then
echo "🎯 MusicBrainz match ($mb_score%): $artist_name ($mb_id)"
# Ask Lidarr to resolve MBID into full artist JSON
lidarr_lookup=$(curl -s -G "$lidarr_url/api/v1/artist/lookup" \
--data-urlencode "term=lidarr:$mb_id" \
-H "X-Api-Key: $api_key")
artist_json=$(echo "$lidarr_lookup" | jq -r 'if type=="array" and length>0 then .[0] else empty end')
if [ -z "$artist_json" ] || [ "$artist_json" == "null" ]; then
echo "⚠️ Lidarr could not resolve MBID for: $artist_name" | tee -a "$failed_log"
continue
fi
else
echo "⚠️ No reliable MusicBrainz match for: $artist_name (score=$mb_score)" | tee -a "$failed_log"
continue
fi
fi
# Skip artist if it already exists in Lidarr
foreign_id=$(echo "$artist_json" | jq -r '.foreignArtistId')
if echo "$existing_ids" | grep -q "$foreign_id"; then
echo "⏩ Already exists in Lidarr: $artist_name"
continue
fi
# Root path only (Lidarr creates the subfolder automatically)
target_path="$lidarr_root"
# Build the JSON payload
payload=$(jq -n \
--argjson artist "$artist_json" \
--arg path "$target_path" \
--argjson qualityProfileId "$quality_profile_id" \
--argjson metadataProfileId "$metadata_profile_id" \
'{
artistMetadataId: $artist.artistMetadataId,
qualityProfileId: $qualityProfileId,
metadataProfileId: $metadataProfileId,
rootFolderPath: $path,
monitored: true,
foreignArtistId: $artist.foreignArtistId,
artistName: $artist.artistName,
addOptions: {
monitor: "all",
searchForMissingAlbums: false
}
}')
echo "βž• Adding to Lidarr: $artist_name β†’ $target_path"
curl -s -X POST "$lidarr_url/api/v1/artist" \
-H "Content-Type: application/json" \
-H "X-Api-Key: $api_key" \
-d "$payload"
echo "βœ… Done: $artist_name"
echo "⏳ Waiting $delay_between_adds seconds before next artist..."
sleep $delay_between_adds
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment