- gRPC service with MusicBrainz provider - PostgreSQL schema with migrations - Service layer with database-first caching - Repository pattern for data access - YAML configuration support - Research documentation for 17 music metadata projects
27 KiB
Lidarr Metadata API - API Reference
Base URL and Versioning
Production deployment:
- Stable:
https://api.lidarr.audio/api/v0.3 - Testing:
https://api.lidarr.audio/api/testing
Local development:
- Default:
http://localhost:5001 - Configurable via
APPLICATION_ROOTenvironment variable
Version strategy: Dual deployment with stable (v0.3) and testing versions running simultaneously.
Authentication
Read endpoints: No authentication required (public access)
Write endpoints: API key authentication via header
POST /invalidate HTTP/1.1
X-Api-Key: your-api-key-here
Configuration:
export INVALIDATE_APIKEY=your-secure-key
Default: replaceme (insecure, must change in production)
Response Format
All endpoints return JSON with consistent structure.
Common Response Headers
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: s-maxage=2592000, max-age=0
X-Application-Version: 10.0.0.0
Cache-Control explanation:
s-maxage=2592000: CDN can cache for 30 daysmax-age=0: Clients must revalidate (always check CDN/origin)
Error Response Format
{
"error": "Artist not found",
"status": 404,
"mbid": "invalid-mbid-format"
}
HTTP status codes:
200: Success400: Bad request (invalid parameters)401: Unauthorized (missing/invalid API key)404: Resource not found429: Rate limit exceeded500: Internal server error503: Service unavailable (database/cache down)
Health and Version Endpoints
GET /
Purpose: Health check and version information
Parameters: None
Response:
{
"version": "10.0.0.0",
"status": "healthy",
"timestamp": "2025-04-28T12:34:56Z"
}
Cache: No caching
Use case: Load balancer health checks, monitoring
Artist Endpoints
GET /artist/{mbid}
Purpose: Retrieve complete artist metadata with releases
Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
mbid |
UUID | Yes | - | MusicBrainz artist ID |
primTypes |
String | No | All | Primary release types (comma-separated) |
secTypes |
String | No | All | Secondary release types (comma-separated) |
releaseStatuses |
String | No | All | Release statuses (comma-separated) |
Primary release types:
Album: Studio albumsSingle: SinglesEP: Extended playsBroadcast: Radio/TV broadcastsOther: Miscellaneous
Secondary release types:
Compilation: Compilation albumsSoundtrack: Movie/game soundtracksSpokenword: Audiobooks, poetryInterview: Interview recordingsAudiobook: AudiobooksLive: Live recordingsRemix: Remix albumsDJ-mix: DJ mix albumsMixtape/Street: Mixtapes
Release statuses:
Official: Official releasesPromotion: Promotional releasesBootleg: Bootleg recordingsPseudo-Release: Pseudo-releases
Example request:
GET /artist/5b11f4ce-a62d-471e-81fc-a69a8278c7da?primTypes=Album,Single&releaseStatuses=Official HTTP/1.1
Response:
{
"Id": "5b11f4ce-a62d-471e-81fc-a69a8278c7da",
"OldIds": [],
"ArtistName": "Nirvana",
"SortName": "Nirvana",
"Disambiguation": "90s US grunge band",
"Overview": "Nirvana was an American rock band formed in Aberdeen, Washington, in 1987...",
"Type": "Group",
"Status": "Ended",
"Gender": null,
"Hometown": "Aberdeen, WA, United States",
"StartYear": 1987,
"EndYear": 1994,
"ArtistAliases": [
{
"Name": "ニルヴァーナ",
"SortName": "ニルヴァーナ",
"Locale": "ja",
"Primary": true
}
],
"Links": [
{
"Url": "https://www.spotify.com/artist/6olE6TJLqED3rqDCT0FyPh",
"Name": "spotify"
},
{
"Url": "https://www.allmusic.com/artist/mn0000352188",
"Name": "allmusic"
},
{
"Url": "https://www.discogs.com/artist/65450",
"Name": "discogs"
},
{
"Url": "https://en.wikipedia.org/wiki/Nirvana_(band)",
"Name": "wikipedia"
}
],
"Images": [
{
"Url": "https://imagecache.lidarr.audio/fanart/artist/5b11f4ce-a62d-471e-81fc-a69a8278c7da/poster.jpg",
"CoverType": "poster",
"Extension": ".jpg"
},
{
"Url": "https://imagecache.lidarr.audio/fanart/artist/5b11f4ce-a62d-471e-81fc-a69a8278c7da/banner.jpg",
"CoverType": "banner",
"Extension": ".jpg"
},
{
"Url": "https://imagecache.lidarr.audio/fanart/artist/5b11f4ce-a62d-471e-81fc-a69a8278c7da/logo.png",
"CoverType": "logo",
"Extension": ".png"
},
{
"Url": "https://imagecache.lidarr.audio/fanart/artist/5b11f4ce-a62d-471e-81fc-a69a8278c7da/fanart.jpg",
"CoverType": "fanart",
"Extension": ".jpg"
}
],
"Genres": [
"Grunge",
"Alternative Rock",
"Punk Rock"
],
"Rating": {
"Votes": 42,
"Value": 4.8
},
"Albums": [
{
"Id": "1b022e01-4da6-387b-8658-8678046e4cef",
"Title": "Nevermind",
"Disambiguation": "",
"ReleaseDate": "1991-09-24",
"Type": "Album",
"SecondaryTypes": [],
"Status": "Official",
"Genres": ["Grunge", "Alternative Rock"],
"Rating": {
"Votes": 156,
"Value": 4.9
},
"Images": [
{
"Url": "https://imagecache.lidarr.audio/cover/1b022e01-4da6-387b-8658-8678046e4cef/front.jpg",
"CoverType": "cover",
"Extension": ".jpg"
}
]
}
]
}
Response fields:
| Field | Type | Description |
|---|---|---|
Id |
UUID | MusicBrainz artist ID |
OldIds |
Array | Historical MusicBrainz IDs (after merges) |
ArtistName |
String | Primary artist name |
SortName |
String | Name for alphabetical sorting |
Disambiguation |
String | Disambiguation comment |
Overview |
String | Artist biography (from Wikipedia) |
Type |
String | Artist type (Person, Group, Orchestra, etc.) |
Status |
String | Artist status (Active, Ended, etc.) |
Gender |
String | Gender (for Person type) |
Hometown |
String | Origin location |
StartYear |
Integer | Formation/birth year |
EndYear |
Integer | Dissolution/death year |
ArtistAliases |
Array | Alternative names and translations |
Links |
Array | External links (Spotify, AllMusic, Discogs, etc.) |
Images |
Array | Artist images (poster, banner, logo, fanart) |
Genres |
Array | Genre tags |
Rating |
Object | Community rating (votes and value) |
Albums |
Array | Release groups (filtered by parameters) |
Cache behavior:
- Cache key:
artist:{mbid}:{primTypes}:{secTypes}:{releaseStatuses} - TTL: 30 days (2592000 seconds)
- Invalidation: Manual via
/artist/{mbid}/refreshor automatic via crawler
Performance:
- Cold request: 2-5 seconds (MusicBrainz DB + external APIs)
- Cached request: 50-200ms (Redis/PostgreSQL)
- CDN request: 10-50ms (Cloudflare edge)
POST /artist/{mbid}/refresh
Purpose: Invalidate cache and force fresh metadata fetch
Authentication: Required (API key)
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
mbid |
UUID | Yes | MusicBrainz artist ID |
Request:
POST /artist/5b11f4ce-a62d-471e-81fc-a69a8278c7da/refresh HTTP/1.1
X-Api-Key: your-api-key-here
Response:
{
"status": "success",
"mbid": "5b11f4ce-a62d-471e-81fc-a69a8278c7da",
"invalidated": [
"redis:artist:5b11f4ce-a62d-471e-81fc-a69a8278c7da",
"postgres:artist:5b11f4ce-a62d-471e-81fc-a69a8278c7da",
"cdn:https://api.lidarr.audio/api/v0.3/artist/5b11f4ce-a62d-471e-81fc-a69a8278c7da"
]
}
Cache invalidation:
- Delete from Redis cache
- Delete from PostgreSQL cache
- Purge from Cloudflare CDN
- Next request will fetch fresh data
Use cases:
- Artist metadata updated in MusicBrainz
- New images added to FanArt.tv
- Wikipedia article updated
- Manual cache refresh
GET /recent/artist
Purpose: List recently updated artists
Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
limit |
Integer | No | 50 | Maximum number of results |
since |
ISO 8601 | No | 24h ago | Only artists updated after this timestamp |
Example request:
GET /recent/artist?limit=10&since=2025-04-27T00:00:00Z HTTP/1.1
Response:
{
"artists": [
{
"Id": "5b11f4ce-a62d-471e-81fc-a69a8278c7da",
"ArtistName": "Nirvana",
"LastUpdated": "2025-04-28T10:30:00Z",
"ChangeType": "metadata"
},
{
"Id": "83d91898-7763-47d7-b03b-b92132375c47",
"ArtistName": "Pink Floyd",
"LastUpdated": "2025-04-28T09:15:00Z",
"ChangeType": "new_release"
}
],
"total": 2,
"limit": 10,
"since": "2025-04-27T00:00:00Z"
}
Change types:
metadata: Artist metadata updatednew_release: New release addedupdated_release: Existing release updatednew_link: New external link addedcover_art: Cover art updated
Cache: 1 hour TTL
Use case: Crawler scheduling, monitoring MusicBrainz updates
Album Endpoints
GET /album/{mbid}
Purpose: Retrieve complete album metadata with tracks
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
mbid |
UUID | Yes | MusicBrainz release group ID |
Example request:
GET /album/1b022e01-4da6-387b-8658-8678046e4cef HTTP/1.1
Response:
{
"Id": "1b022e01-4da6-387b-8658-8678046e4cef",
"OldIds": [],
"Title": "Nevermind",
"Disambiguation": "",
"Overview": "Nevermind is the second studio album by American rock band Nirvana...",
"ReleaseDate": "1991-09-24",
"Type": "Album",
"SecondaryTypes": [],
"Status": "Official",
"Artist": {
"Id": "5b11f4ce-a62d-471e-81fc-a69a8278c7da",
"ArtistName": "Nirvana"
},
"Links": [
{
"Url": "https://www.spotify.com/album/2guirTSEqLizK7j9i1MTTZ",
"Name": "spotify"
},
{
"Url": "https://www.allmusic.com/album/mw0000083881",
"Name": "allmusic"
}
],
"Images": [
{
"Url": "https://imagecache.lidarr.audio/cover/1b022e01-4da6-387b-8658-8678046e4cef/front.jpg",
"CoverType": "cover",
"Extension": ".jpg"
},
{
"Url": "https://imagecache.lidarr.audio/cover/1b022e01-4da6-387b-8658-8678046e4cef/back.jpg",
"CoverType": "disc",
"Extension": ".jpg"
}
],
"Genres": ["Grunge", "Alternative Rock"],
"Rating": {
"Votes": 156,
"Value": 4.9
},
"Media": [
{
"Position": 1,
"Format": "CD",
"Tracks": [
{
"Position": 1,
"Title": "Smells Like Teen Spirit",
"Duration": 301000,
"ArtistName": "Nirvana"
},
{
"Position": 2,
"Title": "In Bloom",
"Duration": 254000,
"ArtistName": "Nirvana"
}
]
}
]
}
Response fields:
| Field | Type | Description |
|---|---|---|
Id |
UUID | MusicBrainz release group ID |
OldIds |
Array | Historical IDs (after merges) |
Title |
String | Album title |
Disambiguation |
String | Disambiguation comment |
Overview |
String | Album description (from Wikipedia) |
ReleaseDate |
ISO 8601 | Original release date |
Type |
String | Primary type (Album, Single, EP, etc.) |
SecondaryTypes |
Array | Secondary types (Compilation, Live, etc.) |
Status |
String | Release status (Official, Promotion, etc.) |
Artist |
Object | Artist information |
Links |
Array | External links |
Images |
Array | Cover art images |
Genres |
Array | Genre tags |
Rating |
Object | Community rating |
Media |
Array | Physical/digital media with track listings |
Cache behavior:
- Cache key:
album:{mbid} - TTL: 30 days
- Invalidation: Manual or automatic
POST /album/{mbid}/refresh
Purpose: Invalidate album cache
Authentication: Required (API key)
Parameters: Same as artist refresh
Response: Same structure as artist refresh
GET /recent/album
Purpose: List recently updated albums
Parameters: Same as /recent/artist
Response: Similar structure with album-specific fields
Search Endpoints
GET /search/artist
Purpose: Search for artists by name
Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
query |
String | Yes | - | Search query |
limit |
Integer | No | 10 | Maximum results |
Example request:
GET /search/artist?query=nirvana&limit=5 HTTP/1.1
Response:
{
"results": [
{
"Id": "5b11f4ce-a62d-471e-81fc-a69a8278c7da",
"ArtistName": "Nirvana",
"Disambiguation": "90s US grunge band",
"Type": "Group",
"Score": 100,
"Images": [
{
"Url": "https://imagecache.lidarr.audio/fanart/artist/5b11f4ce-a62d-471e-81fc-a69a8278c7da/poster.jpg",
"CoverType": "poster",
"Extension": ".jpg"
}
]
},
{
"Id": "9282c8b4-ca0b-4c6b-b7e3-4f7762dfc4d6",
"ArtistName": "Nirvana",
"Disambiguation": "60s UK psychedelic band",
"Type": "Group",
"Score": 95,
"Images": []
}
],
"total": 2,
"query": "nirvana",
"limit": 5
}
Search algorithm:
- Query Solr artist core with dismax parser
- Boost fields:
artist^2 sortname alias - Minimum match: 1 term
- Sort by relevance score
- Enrich results with cached metadata
Cache:
- Cache key:
search:artist:{query}:{limit} - TTL: 1 hour
Performance:
- Cold request: 500ms-1s (Solr query + metadata enrichment)
- Cached request: 50-100ms
GET /search/album
Purpose: Search for albums by title
Parameters: Same as artist search
Response: Similar structure with album-specific fields
Search algorithm: Same as artist search, using release-group Solr core
GET /search/all
Purpose: Combined artist and album search
Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
query |
String | Yes | - | Search query |
artistLimit |
Integer | No | 5 | Max artist results |
albumLimit |
Integer | No | 5 | Max album results |
Response:
{
"artists": [...],
"albums": [...],
"query": "nevermind",
"artistLimit": 5,
"albumLimit": 5
}
Use case: Unified search UI, autocomplete
POST /search/fingerprint
Purpose: Acoustic fingerprint search (AcoustID integration)
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
fingerprint |
String | Yes | Chromaprint fingerprint |
duration |
Integer | Yes | Track duration in seconds |
Request:
POST /search/fingerprint HTTP/1.1
Content-Type: application/json
{
"fingerprint": "AQADtNGSJE...",
"duration": 301
}
Response:
{
"results": [
{
"Id": "5b11f4ce-a62d-471e-81fc-a69a8278c7da",
"ArtistName": "Nirvana",
"AlbumTitle": "Nevermind",
"TrackTitle": "Smells Like Teen Spirit",
"Score": 0.98,
"Duration": 301
}
]
}
Use case: Audio file identification, automatic tagging
Spotify Integration Endpoints
GET /spotify/artist/{id}
Purpose: Get artist metadata by Spotify ID
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
String | Yes | Spotify artist ID |
Example request:
GET /spotify/artist/6olE6TJLqED3rqDCT0FyPh HTTP/1.1
Response: Same structure as /artist/{mbid} with MusicBrainz mapping
Mapping algorithm:
- Query Spotify API for artist metadata
- Search MusicBrainz by artist name
- Calculate Levenshtein distance (threshold: 0.8)
- Return best match with MusicBrainz ID
GET /spotify/album/{id}
Purpose: Get album metadata by Spotify ID
Parameters: Same as artist endpoint
Response: Same structure as /album/{mbid} with MusicBrainz mapping
POST /spotify/lookup
Purpose: Batch Spotify ID to MusicBrainz ID mapping
Request:
POST /spotify/lookup HTTP/1.1
Content-Type: application/json
{
"artists": ["6olE6TJLqED3rqDCT0FyPh", "0k17h0D3J5VfsdmQ1iZtE9"],
"albums": ["2guirTSEqLizK7j9i1MTTZ"]
}
Response:
{
"artists": {
"6olE6TJLqED3rqDCT0FyPh": "5b11f4ce-a62d-471e-81fc-a69a8278c7da",
"0k17h0D3J5VfsdmQ1iZtE9": "83d91898-7763-47d7-b03b-b92132375c47"
},
"albums": {
"2guirTSEqLizK7j9i1MTTZ": "1b022e01-4da6-387b-8658-8678046e4cef"
}
}
Cache: 90 days TTL (Spotify IDs rarely change)
GET /spotify/auth
Purpose: Get Spotify OAuth authorization URL
Response:
{
"auth_url": "https://accounts.spotify.com/authorize?client_id=...&response_type=code&redirect_uri=..."
}
Use case: User authentication for Spotify features
GET /spotify/renew
Purpose: Refresh Spotify OAuth token
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
refresh_token |
String | Yes | Spotify refresh token |
Response:
{
"access_token": "BQD...",
"expires_in": 3600
}
Chart Endpoints
GET /chart/{name}/{type}/{selection}
Purpose: Get music charts from various sources
Parameters:
| Parameter | Type | Required | Values | Description |
|---|---|---|---|---|
name |
String | Yes | apple-music, billboard, itunes, lastfm |
Chart source |
type |
String | Yes | artist, album, track |
Chart type |
selection |
String | Yes | Source-specific | Chart category |
Chart sources and selections:
Apple Music
Selections:
top-albums: Top 100 albumsnew-releases: New album releasestop-songs: Top 100 songs
Example:
GET /chart/apple-music/album/top-albums HTTP/1.1
Billboard
Selections:
hot-100: Billboard Hot 100billboard-200: Billboard 200 albumsartist-100: Top artistsstreaming-songs: Top streaming songs
Example:
GET /chart/billboard/track/hot-100 HTTP/1.1
iTunes
Selections:
top-albums: iTunes top albumstop-songs: iTunes top songs
Example:
GET /chart/itunes/album/top-albums HTTP/1.1
Last.fm
Selections:
top-artists: Most scrobbled artiststop-albums: Most scrobbled albumstop-tracks: Most scrobbled tracks
Example:
GET /chart/lastfm/artist/top-artists HTTP/1.1
Response:
{
"chart": "billboard",
"type": "track",
"selection": "hot-100",
"date": "2025-04-28",
"entries": [
{
"position": 1,
"previousPosition": 2,
"peakPosition": 1,
"weeksOnChart": 12,
"artist": {
"Id": "5b11f4ce-a62d-471e-81fc-a69a8278c7da",
"ArtistName": "Nirvana"
},
"album": {
"Id": "1b022e01-4da6-387b-8658-8678046e4cef",
"Title": "Nevermind"
},
"track": {
"Title": "Smells Like Teen Spirit",
"Duration": 301000
}
}
]
}
Cache: 6 hours TTL (charts update daily)
MusicBrainz mapping: Chart entries are automatically mapped to MusicBrainz IDs when possible
Series Endpoints
GET /series/{mbid}
Purpose: Get series metadata (box sets, compilations)
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
mbid |
UUID | Yes | MusicBrainz series ID |
Response:
{
"Id": "series-mbid",
"Name": "The Beatles Remastered Series",
"Type": "Release group series",
"Albums": [
{
"Id": "album-mbid-1",
"Title": "Please Please Me",
"Position": 1
},
{
"Id": "album-mbid-2",
"Title": "With the Beatles",
"Position": 2
}
]
}
Use case: Box set tracking, series completion
Cache Management Endpoints
POST /invalidate
Purpose: Batch cache invalidation
Authentication: Required (API key)
Request:
POST /invalidate HTTP/1.1
X-Api-Key: your-api-key-here
Content-Type: application/json
{
"artists": [
"5b11f4ce-a62d-471e-81fc-a69a8278c7da",
"83d91898-7763-47d7-b03b-b92132375c47"
],
"albums": [
"1b022e01-4da6-387b-8658-8678046e4cef"
]
}
Response:
{
"status": "success",
"invalidated": {
"artists": 2,
"albums": 1,
"total_keys": 6
}
}
Invalidation scope:
- Redis cache
- PostgreSQL cache
- Cloudflare CDN cache
Use case: Bulk cache refresh after MusicBrainz updates
Rate Limiting
Default: No rate limiting (NullRateLimiter)
Optional: Redis-based distributed rate limiting
Configuration:
RATE_LIMITER = 'redis'
RATE_LIMIT_REQUESTS = 100
RATE_LIMIT_WINDOW = 60 # seconds
Rate limit response:
HTTP/1.1 429 Too Many Requests
Retry-After: 30
{
"error": "Rate limit exceeded",
"limit": 100,
"window": 60,
"retry_after": 30
}
CORS Support
Default: CORS enabled for all origins
Headers:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type, X-Api-Key
Configuration:
CORS_ORIGINS = ['https://lidarr.audio', 'https://app.lidarr.audio']
Pagination
Not implemented: All endpoints return complete result sets
Workaround: Use limit parameter on search and recent endpoints
Future consideration: Cursor-based pagination for large result sets
Filtering and Sorting
Artist endpoint:
- Filter by release type:
primTypes,secTypes - Filter by release status:
releaseStatuses - Sort: Albums sorted by release date (descending)
Search endpoints:
- Sort: Relevance score (descending)
- Filter: Not implemented
Chart endpoints:
- Sort: Chart position (ascending)
- Filter: Not implemented
Compression
Response compression: Supported via Accept-Encoding: gzip
Request compression: Not supported
Example:
GET /artist/5b11f4ce-a62d-471e-81fc-a69a8278c7da HTTP/1.1
Accept-Encoding: gzip
HTTP/1.1 200 OK
Content-Encoding: gzip
Content-Length: 1234
Compression ratio: Typically 5:1 for JSON responses
Conditional Requests
ETag support: Not implemented
Last-Modified support: Not implemented
Future consideration: ETag generation based on cache timestamp
Webhooks
Not implemented: No webhook support for cache invalidation or updates
Workaround: Poll /recent/artist and /recent/album endpoints
Future consideration: WebSocket or Server-Sent Events for real-time updates
API Versioning Strategy
Current approach: Path-based versioning (/api/v0.3)
Version lifecycle:
- New features developed in
testingversion - Tested in production alongside stable version
- Promoted to new stable version (e.g., v0.4)
- Old stable version deprecated after 6 months
Breaking changes: Only in major version increments
Backward compatibility: Maintained within minor versions
Performance Benchmarks
| Endpoint | Cold (ms) | Cached (ms) | CDN (ms) |
|---|---|---|---|
| GET /artist/{mbid} | 2000-5000 | 50-200 | 10-50 |
| GET /album/{mbid} | 1500-3000 | 50-150 | 10-50 |
| GET /search/artist | 500-1000 | 50-100 | N/A |
| GET /chart/billboard/hot-100 | 3000-5000 | 100-200 | 20-100 |
| POST /artist/{mbid}/refresh | 100-200 | N/A | N/A |
Factors affecting cold request performance:
- MusicBrainz database query complexity
- Number of external API calls (FanArt, Wikipedia, etc.)
- External API response times
- Network latency
Cache hit rate: 85%+ with crawler enabled
Error Handling Examples
Invalid MBID format:
GET /artist/invalid-mbid HTTP/1.1
HTTP/1.1 400 Bad Request
{
"error": "Invalid MBID format",
"mbid": "invalid-mbid"
}
Artist not found:
GET /artist/00000000-0000-0000-0000-000000000000 HTTP/1.1
HTTP/1.1 404 Not Found
{
"error": "Artist not found",
"mbid": "00000000-0000-0000-0000-000000000000"
}
Missing API key:
POST /invalidate HTTP/1.1
HTTP/1.1 401 Unauthorized
{
"error": "Missing or invalid API key"
}
Database connection error:
GET /artist/5b11f4ce-a62d-471e-81fc-a69a8278c7da HTTP/1.1
HTTP/1.1 503 Service Unavailable
{
"error": "Database unavailable",
"retry_after": 60
}
Client Implementation Examples
Python
import requests
class LidarrMetadataClient:
def __init__(self, base_url='https://api.lidarr.audio/api/v0.3'):
self.base_url = base_url
self.session = requests.Session()
def get_artist(self, mbid, prim_types=None, sec_types=None, statuses=None):
params = {}
if prim_types:
params['primTypes'] = ','.join(prim_types)
if sec_types:
params['secTypes'] = ','.join(sec_types)
if statuses:
params['releaseStatuses'] = ','.join(statuses)
response = self.session.get(f'{self.base_url}/artist/{mbid}', params=params)
response.raise_for_status()
return response.json()
def search_artist(self, query, limit=10):
response = self.session.get(
f'{self.base_url}/search/artist',
params={'query': query, 'limit': limit}
)
response.raise_for_status()
return response.json()
# Usage
client = LidarrMetadataClient()
artist = client.get_artist('5b11f4ce-a62d-471e-81fc-a69a8278c7da', prim_types=['Album'])
results = client.search_artist('nirvana')
JavaScript
class LidarrMetadataClient {
constructor(baseUrl = 'https://api.lidarr.audio/api/v0.3') {
this.baseUrl = baseUrl;
}
async getArtist(mbid, options = {}) {
const params = new URLSearchParams();
if (options.primTypes) params.set('primTypes', options.primTypes.join(','));
if (options.secTypes) params.set('secTypes', options.secTypes.join(','));
if (options.releaseStatuses) params.set('releaseStatuses', options.releaseStatuses.join(','));
const response = await fetch(`${this.baseUrl}/artist/${mbid}?${params}`);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json();
}
async searchArtist(query, limit = 10) {
const params = new URLSearchParams({ query, limit });
const response = await fetch(`${this.baseUrl}/search/artist?${params}`);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json();
}
}
// Usage
const client = new LidarrMetadataClient();
const artist = await client.getArtist('5b11f4ce-a62d-471e-81fc-a69a8278c7da', {
primTypes: ['Album']
});
const results = await client.searchArtist('nirvana');
Conclusion
The API provides comprehensive music metadata with:
- 15+ endpoints covering artists, albums, search, charts, and Spotify integration
- Multi-source aggregation from MusicBrainz, FanArt.tv, Wikipedia, Spotify, Last.fm, Billboard
- Intelligent caching with 30-day TTL and CDN integration
- Flexible filtering for release types and statuses
- Chart integration from 4 major sources
- Spotify mapping for cross-platform compatibility
The API is production-ready with excellent performance characteristics when properly cached. The dual-version deployment strategy allows safe rollout of new features.
Key strengths: comprehensive metadata, excellent caching, multi-source enrichment.
Key weaknesses: no authentication on read endpoints, no pagination, no webhooks.