Question about Python musicbrainzngs.get_recording_by_id


I’m trying to get musicbrainzngs.get_recording_by_id() to return something sensible but not having a lot of luck at the moment, so I thought I’d ask some basic questions in order to isolate the problem.

Check out the following Python Code:

musicbrainzngs.auth('***', '***')

myResult = musicbrainzngs.search_artists(artist=myArtist, type="group", strict=True)
myArtistList = myResult['artists']
myArtistDict = myArtistList[0]
myArtistID = myArtistDict['id']

myResult = musicbrainzngs.get_artist_by_id(id=myArtistID,includes=['release-groups'], release_type=['album'])
myReleaseGroupDict = myResult['release-groups']
for myReleaseDict in myReleaseGroupDict:
    if myReleaseDict['title'] == myAlbum:
        myAlbumID = myReleaseDict['id']
        print('Matched:', myAlbum, '  AlbumID:',myAlbumID)

myResult = musicbrainzngs.get_recording_by_id(id=myAlbumID, includes=['releases'], release_status=['official'], release_type=['album'])

Apart from the call to musicbrainzngs.get_recording_by_id, this works fine, so some basic questions:

  1. What should I be passing to this method as the ID? I have the ArtistID and the AlbumID (ReleaseID?) both returned from MB, which one should I pass? I’ve tried both and they both fail.

  2. What should I pass as the other parameters, the parameters I am passing are the same as the call to get_artist_by_id method, so I would have thought they would be valid?

When I run this, I get the following error:

Matched: White Light/White Heat   AlbumID: fc0885e0-0284-3f9d-81ee-17c5e7196346
Traceback (most recent call last):
  File "/Documents/Development/Projects/Python/Test1/venv/lib/python3.9/site-packages/musicbrainzngs/", line 497, in _safe_read
    f =
  File "/usr/local/Cellar/python@3.9/3.9.13_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/", line 523, in open
    response = meth(req, response)
  File "/usr/local/Cellar/python@3.9/3.9.13_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/", line 632, in http_response
    response = self.parent.error(
  File "/usr/local/Cellar/python@3.9/3.9.13_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/", line 561, in error
    return self._call_chain(*args)
  File "/usr/local/Cellar/python@3.9/3.9.13_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/", line 494, in _call_chain
    result = func(*args)
  File "/usr/local/Cellar/python@3.9/3.9.13_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/urllib/", line 641, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 404: Not Found

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Documents/Development/Projects/Python/Test1/", line 130, in <module>
    myResult = musicbrainzngs.get_recording_by_id(id=myAlbumID, includes=['releases'], release_status=['official'], release_type=['album'])
  File "/Documents/Development/Projects/Python/Test1/venv/lib/python3.9/site-packages/musicbrainzngs/", line 870, in get_recording_by_id
    return _do_mb_query("recording", id, includes, params)
  File "/Documents/Development/Projects/Python/Test1/venv/lib/python3.9/site-packages/musicbrainzngs/", line 728, in _do_mb_query
    return _mb_request(path, 'GET', auth_required, args=args)
  File "/Documents/Development/Projects/Python/Test1/venv/lib/python3.9/site-packages/musicbrainzngs/", line 417, in __call__
    return*args, **kwargs)
  File "/Documents/Development/Projects/Python/Test1/venv/lib/python3.9/site-packages/musicbrainzngs/", line 690, in _mb_request
    resp = _safe_read(opener, req, body)
  File "/Documents/Development/Projects/Python/Test1/venv/lib/python3.9/site-packages/musicbrainzngs/", line 503, in _safe_read
    raise ResponseError(cause=exc)
musicbrainzngs.musicbrainz.ResponseError: caused by: HTTP Error 404: Not Found

Process finished with exit code 1

Any help would be greatly appreciated.

All the Best

It is a recording lookup, so it expects a recording ID. A recording is a specific recording of one piece of music.

What you have in myAlbumId is a release group ID. A release group you can think of like the general concept of e.g. an album. A release group then contains multiple actual releases (i.e. different versions of the album). Each release has a track list, where each track is linked to a specific recording.

Valid parameters depend on what data you are requesting. I am not really familiar with the musicbrainzngs library, but I’d suggest you first try some requests just by URL in your browser and get used to the parameters, than try to translate this to musicbrainzngs calls. See MusicBrainz API - MusicBrainz for the details on what requests with which parameters are possible.

Btw, you don’t need the auth for most requests (unless you request user specific data), and you should not share the auth parameters in code you share.


Ok, so I need a Recording ID, my next question is how do I get one of those? The code firstly calls search_artists with the Artist String, this returns the ArtistID, I use this as the ID for the call to get_artist_by_id which returns a list of releases. I scan through the releases returned until I find one that matches the title of the album, I then want to get the track list for this album? How do I do this? Do I need to request more info from the cake to get_artist_by_id? Do I need to make another call to an API to translate the ReleaseID to the RecordingID? I can’t seem to find this vital information anywhere.

Thanks for your help and all the best.


Given that I have an Artist Name and an Album Name, all I want to do is validate (in the following order):

  1. The Artist Name exists.
  2. The Artist has released an album called AlbumName.
  3. I then want to get the track list of the release.

I want to do this programatically using Python.

It seems that there is not a straight forward way of doing this using MusicBrainz. By straight forward I mean simple API calls that are abstracted from the underlying database. I realise that by doing this it would be hiding a LOT of using features of the database, but if there isn’t a simple of doing this then it really doesn’t matter how good the MB project is, most people will look at it and say - way too complex and move on. It seems silly to provide all this information and documentation (albeit sometimes disjointed) on the database, all the API and libraries yet not have a way to just get going! I’m sure that doing the above Artist/Album/TrackList look up is straight forward if you have experience using the database, but if you don’t it is much harder than it need be.

For instance, I’m guessing (hoping!?) the Python MusicBrainz library was tested, in which case some type of test programs must have been developed, why not share them if?

I’m giving up for the day!

All the Best

If you are looking for releases you should perform a release search, see the search query documentation at MusicBrainz API / Search - MusicBrainz

E.g. this example request will fetch all releases by artist name and release title:"The%20Velvet%20Underground"%20release:"White%20Light/White%20Heat"&fmt=json

To get the detailed track list for one release you can do:



Thanks for the help, on the above request -

What is the cad3294a-3ea9-3e0e-a426-fe9862571e34 ? The Recording ID, Release ID or what?


This is getting the details for one release, so it needs a release ID. There are similar requests possible for getting details for all the different entities.

In general the API has three types of queries:

  • Lookups that get you details about a single entity by its ID. You can include data about related entities there as well, e.g. you can include the recordings on a release, using the inc parameter
  • Browse that let’s you query a list of entities based on a related ID. E.g. list all release groups for an artist by artist ID
  • Searches, that let you specify a search query to search for specific entities

Browse and lookup are described at MusicBrainz API - MusicBrainz , search is more complicated as it allows quite flexible search queries and is described at MusicBrainz API / Search - MusicBrainz .

In general it’s best to refer to the general API docs first, then check how to achieve the desired requests with the language binding. The documentation for the different language bindings for the most part assumes some familiarity with the API in general.

1 Like

The problem with the docs is they all mention the “id” but without knowing what ID its referring too they are hard to fathom. I’m a developer so I’m used to reading technical stuff but with MB I can’t seem to find one clear abstracted API, all those I’ve found so far you need to know the database structure to use it. Ok, so I have to understand the structure, it would help if I know the high level steps needed to pragmatically step through a list of ArtistName and AlbumName strings and get the tracks associated with that album. Is there anywhere where it simply explains how to do this simple job?

It seems its much more difficult to send MusicBrainz URL requests from within Python, I suppose this is why the Python library was developed. So, although I can form the request I want in a browser, I can’t do it from within Python (well I can send the form and send request ok, but can’t get the info back in any reasonable format, which means I’d have to translate the JSON etc). So it’s one of four options, give up and write off MusicBrainz and an expensive waste of time and money, try a different language, or try get to figure out how to get the MB Python Library to work, or try to figure out how to decode all that non-standard JSON crap. I’m beginning to think they are making trying to use it hard on purpose in order to put off all non MusicBrainz database experts and protect that have the knowledge!

Small hint: It’s much easier to get help if you don’t call other people’s work crap. Also get familiar with the APIs you are using by reading the documentation and get familiar with what the programming language you are using offers to solve certain problems.

I gave you the basic two requests you need to do above:

  1. A search request to get possible releases by artist name and release name:"The%20Velvet%20Underground"%20and%20release:"White%20Light/White%20Heat"&fmt=json

  2. A release lookup using the release ID to get details about a found ID from

As I wrote previously I am not really familiar with the musicbrainzngs python library. But there is some documentation at Usage — musicbrainzngs 0.7.1 documentation that explains how to use search, lookup and browse request. So the above two requests translate to something like this:

release_list = musicbrainzngs.search_releases('artist:"The Velvet Underground" and release:"White Light/White Heat"')
# Now you need to pick one of the releases. Maybe you have some additional criteria to apply.
# But for simplicity just use the very first search result here.
release_mbid = release_list['releases'][0]['id']
release = musicbrainzngs.get_release_by_id(release_mbid, includes=['recordings']

There are several easy ways to do HTTP requests using Python. “requests” (requests · PyPI) or “urllib3” (urllib3 · PyPI) are two popular and rather easy to use packages for this. urllib3 can even automatically parse the result for you.

I really don’t know what you mean with that. JSON ( is probably the most easiest format to get the data with and is the format most current web APIs use. In Python you have the json module:

import json
parsed_data = json.loads(data)

If you prefer XML you can also use XML, but I definitely find this more difficult to work with.


All I meant by “Crap” is that is says all over the docs the the JSON produced and sent is non-standard and can change at anytime, so I assumed that the MB Python Library would know about this non-standard JSON and do whatever is needed to turn it into a dictionary. Are you saying that the docs are wrong and that IT IS standard?

If you choose the JSON format the output is ordinary JSON. I can’t see where it says it would be non-standard JSON in MusicBrainz API - MusicBrainz or MusicBrainz API / Search - MusicBrainz

Here: API — musicbrainzngs 0.7.1 documentation

At bottom of page in red box, plus it spits it out to the console every time I run my code. It’s in a few other places too… I agree this is in the python-musicbrainzngs section but I thought it referred to the JSON it received, since I think it always returns dictionaries, not raw JSON.

I think what it tries to tell you is that the JSON format returned by the server (which you get if you configure musicbrainzngs to request JSON data) differs in some details from the structure musicbrainzngs generates from the XML. So you cannot necessarily change the format with set_format and expect the rest of the code to still work.

The reason for this is most likely because the XML format came first, and JSON was added later to the server. So when musicbrainzngs got implemented it implemented deserializing the XML into some Python structure, but that’s different from what you get when running json.loads on the JSON data returned by the server.



I took this code:

And adapted it to:

myQuery = f’artist={urllib.parse.quote(myArtist)}’+ urllib.parse.quote(’ AND release=’) + urllib.parse.quote(myAlbum)
print(‘Calling: musicbrainzngs.search_releases with: ‘,myQuery)
myReleasesDict = musicbrainzngs.search_releases(myQuery)
myReleasesList = myReleasesDict[‘releases’]
for myReleaseDict in myReleasesList:
myReleaseID = myReleaseDict[‘id’]
print(‘Calling: musicbrainzngs.get_release_by_id with: ‘, myReleaseID)
myNewReleaseDict = musicbrainzngs.get_release_by_id(myReleaseID, includes=[‘recordings’])
myMedia = myNewReleaseDict[‘media’]
myTrackDict = myMedia[0]
myTrackCount = myTrackDict[‘track-count’]
myTrackList = myTrackDict[‘tracks’]
for myRecordingDict in myTrackList:
myTrackTitle = myRecordingDict[‘title’]
myTrackNumber = myRecordingDict[‘number’]
print(myTrackNumber,’ ‘,myTrackTitle)

Which basically works in that I get tracks! Thanks a lot for this. The releases I get are totally different to if you run the same thing in the URL and not at all correct! I’ll try to spot the difference, but I the Track List is contained in the Media sub dictionary?

This is a dump of the running program:

Test MusicBrainz
Title: The Gift
Artist: The Velvet Underground
Album: White Light/White Heat
Album artist: None
Composer: Sterling Morrison; John Cale; Maureen Tucker; Lou Reed. Lyrics: Lou Reed
Publisher: None
Genre: Alternative & Punk
Calling: musicbrainzngs.search_releases with: artist=The%20Velvet%20Underground%20AND%20release%3DWhite%20Light/White%20Heat
Non standard genre name: Alternative & Punk
/Documents/Development/Projects/Python/Test1/venv/lib/python3.9/site-packages/musicbrainzngs/ UserWarning: The json format is non-official and may change at any time
warn(“The json format is non-official and may change at any time”)

Calling: musicbrainzngs.get_release_by_id with: bd7a546c-b4f6-4431-9d6d-e918750fe4c4
1 I Feel So Nice
2 A Riddle
3 Loving You
4 One-Sided Love
5 Once While Living
6 Oasis
7 Can’t Do This
8 Go Away
9 Love Sick
10 My Girl
11 I Do
12 Never Leave You
13 Can’t Get Over You

Calling: musicbrainzngs.get_release_by_id with: 26f4f181-bf2e-4000-938e-94ef6ec371d4
1 Esa prieta
2 La yerba brava
3 Mi propia sangre
4 La chiva
5 Dirindinde
6 El inventor
7 Amarra el perro
8 Tú no sabes na
9 Ileana
10 Corso y montuno

Calling: musicbrainzngs.get_release_by_id with: 827c561f-a684-4dce-a776-56e495d8b420
1 The Artist
2 Weird World
3 Big Speakers
4 Polaroid Picture
5 The Artist (Andy Tex Jones Berlin Kis Remix)
6 Weird World (Teredo Navalis Remix)

Calling: musicbrainzngs.get_release_by_id with: efc38402-503b-46f9-a330-09c8ff6e7cd4
1 The Artist Ouverture
2 1927 A Russian Affair
3 George Valentin
4 Pretty Peppy
5 At the Kinograph Studios
6 Fantaisie D’Amour
7 Waltz for Peppy
8 Silent Rumble
9 1929
10 Comme une rosée de larmes
11 The Sound of Tears
12 L’ombre des flammes
13 Charming Blackmail
14 1931
15 Peppy and George

Calling: musicbrainzngs.get_release_by_id with: 16752ef7-ce31-42ac-a28d-4ae61b80d835
1 The Artist Ouverture
2 1927 A Russian Affair
3 George Valentin
4 Pretty Peppy
5 At the Kinograph Studios
6 Fantaisie D’Amour
7 Waltz for Peppy
8 Estancia OP. 8
9 Imagination
10 Silent Rumble
11 1929
12 In the Stairs
13 Jubilee Stomp
14 Comme une rosée de larmes
15 The Sound of Tears
16 Pennies From Heaven
17 1931
18 Jungle Bar
19 L’ombre des flammes
20 Happy Ending…
21 Charming Blackmail
22 Ghosts From the Past
23 My Suicide (Dedicated to 03.29.1967)
24 Peppy and George

Calling: musicbrainzngs.get_release_by_id with: 954f2663-72de-4dfa-809d-9b80d32a2f96
1 The Artist Ouverture
2 1927 A Russian Affair
3 George Valentin
4 Pretty Peppy
5 At the Kinograph Studios
6 Fantaisie d’amour
7 Waltz for Peppy
8 Estancia op. 8
9 Imagination
10 Silent Rumble
11 1929
12 In the Stairs
13 Jubilee Stomp
14 Comme une rosée de larmes
15 The Sound of Tears
16 Pennies From Heaven
17 1931
18 Jungle Bar
19 L’Ombre des flammes
20 Happy Ending…
21 Charming Blackmail
22 Ghosts From the Past
23 My Suicide (Dedicated to 03.29.1967)
24 Peppy and George

Calling: musicbrainzngs.get_release_by_id with: 39989f76-fcd3-4c44-b00f-0bf7274f0309
1 There Goes Our Love Again (acoustic)
2 First Time Caller (acoustic)
3 Mother Tongue (acoustic)

Calling: musicbrainzngs.get_release_by_id with: 87736347-e550-4829-aaff-e45924e9e047
1 Henry The King
2 Priest
3 F.F.G.
4 O.C.D.
5 Requiem

Calling: musicbrainzngs.get_release_by_id with: e23f671b-768f-4c34-b450-90921795b3b0
1 aRtisT
2 To You
3 Baby U
4 흔들어놔! (Shake It!)
5 To You (Slow B. Ver.)
6 To You (Inst.)

Calling: musicbrainzngs.get_release_by_id with: 627a6fc6-dc8f-4316-af6b-295bac7353d5
1 Do You Know What It’s Worth
2 Papa, It’s Alright
3 When the Lady Dances
4 Hands
5 New World
6 At My Window
7 Song to Woody
8 Song to Don Earl
9 Thinkin’ About Bob Dylan
10 Freedom

Calling: musicbrainzngs.get_release_by_id with: 97cee089-1b1f-4896-a894-636d4c1b2188
1 aRtisT
2 To You
3 Baby U
4 흔들어놔! (Shake it!)
5 To You (Slow B. Ver.)
6 To You (Inst.)

Calling: musicbrainzngs.get_release_by_id with: a5be88c4-ce37-4e84-8054-ad53499bf6ae
1 I Know Whats Real
2 Still Think About You
3 My Shit
4 D.T.B. (interlude)
5 Friend Zone
6 Jungle
7 1Hunnit
8 Money Over Everything
9 Trap House
10 Fall in Love
11 Artist

Calling: musicbrainzngs.get_release_by_id with: ad91800c-4762-4b2b-9191-a58ee8e163fb
1 Artist

Calling: musicbrainzngs.get_release_by_id with: 548e8331-69bb-4fe0-aff6-ece8edfc6abf
3 Y-shirt (Deep Inside)
4 Artist
5 Alone

Calling: musicbrainzngs.get_release_by_id with: 7258553b-b4a9-41ba-99d2-6ff3b13a9d64
1 Artist

Calling: musicbrainzngs.get_release_by_id with: 2ca8d4c1-ec16-462a-8284-733801615d6c
1 개나소나 (Dog and Cow) (Intro)
2 그 여자랑 살래요 (I’m gonna move in with her)
3 나는 군인이다 (I am a soldier)
4 좋아? (You like?)
5 이태원 프리덤 (Itaewon Freedom) Remix

Calling: musicbrainzngs.get_release_by_id with: bdc1d836-36ce-4214-8460-c10c610bf587
1 The Escape Artist (radio edit)

Calling: musicbrainzngs.get_release_by_id with: 7cc6bc15-035b-49a4-bff9-623d42024ec3
1 Never Blink
2 Iller Clip
3 Get Out There
4 Standing by Starz
5 Barney (More Crime) (remix)
6 Girls Say
7 Lookin’ at It
8 Sometimes I
9 Never Equal
10 Feel This Clip
11 Really Dope
12 Delicate Lifestyle
13 Turned Out (Action)
14 Blind World
15 Drugged Out
16 Hey Girl (remix)
17 Won’t Break Me
18 Kuran
19 Barney (More Crime)

Calling: musicbrainzngs.get_release_by_id with: baa41528-3852-413e-a906-3dc5e422c0b2
1 Serenade
2 Sonntag, Op. 47, No. 3
3 Elsk, Op. 67, No. 5
4 Meinem Kinde, Op. 37, No. 3
5 Gefasster Abschied, Op. 14, No. 4
6 Lust De Sturmnacht, Op. 35, No. 1
7 Dein Angesicht, Op. 127, No. 2
8 One Touch of Venus: I’m a Stranger Here Myself
9 Berlin im Licht
10 Vingar i natten
11 Skogen sover, Op. 28, No. 6
12 Lahore
13 La Bonne Chanson, Op. 61: La lune blanche luit dans les bois
14 Der Wanderer an den Mond, D 870
15 An Silvia, D 891
16 Il pianto di Maria, HWV 234: Se d’un Dio fui fatta madre
17 Komm, liebe Zither, K 351/367b
18 Don Giovanni: Inquali eccessi_Mi tradi
19 La Clemenza di Tito: Quello di Tito è il volto
20 L’incoronazione di Poppea: A Dio, Roma! A Dio, patria! amici, a Dio!
21 Ariodante: Tu, preparati a morire
22 Paride ed Elena: Oh, del mio dolce ardor
23 Liebst du um Schönheit
24 Eugene Onegin: Kak ya lyublyu pod zvuki pesen etikh - Uhz kak po mostu, mostochku
25 La Cenerentola: Nacqui all’ affanno

Calling: musicbrainzngs.get_release_by_id with: c85d794e-ef92-4dcc-a7ee-ba646b174356
1 The Graffiti Artist

Calling: musicbrainzngs.get_release_by_id with: 8b410f02-9b35-4129-bcb8-91ca707793c1
1 A Sleepless Mind
2 Endure-Suffer-Die
3 The Spiral Dance (new version)
4 Facing the Dawn of Time
5 The March of the Universe (new version)
6 My Destination
7 In Memory of Elila

Calling: musicbrainzngs.get_release_by_id with: d8257fec-5768-4ca9-ba52-7e69a0c1cc25
1 This Time the Dream’s on Me
2 Delilah
3 But Not for Me
4 Phinupi
5 Love, Your Spell Is Everywhere
6 Scotch Blues
7 Weaver of Dreams
8 Swingin’
9 Chitlins Con Carne
10 Soul Lament
11 Midnight Blue
12 These Foolish Things
13 Hackensack
14 Freedom

Calling: musicbrainzngs.get_release_by_id with: cb0de1cd-cc2a-3b69-ad83-849f7067a337
1 Die Zauberflöte, K. 620: Overture
2 Symphony No. 3, Op. 55: III. Scherzo. Allegro vivace
3 Das Rheingold: “Zur Burg führt die Brücke” - “Abendlich strahlt der Sonne Auge” (Froh / Wotan)
4 Otello: Act III: Ballet Music
5 Passacaglia for Orchestra, Op. 1
6 Violin Concerto, Op. 64: III. Allegretto non troppo - Allegro molto vivace
7 Der Rosenkavalier, Op. 50: Act II. “Mir ist die Ehre widerfahren”
8 Symphony No. 7 in E major: III. Scherzo. Sehr schnell - Trio. Etwas langsamer
9 Der Zigeunerbaron: Act I: Overture
10 Perpetuum Mobile, Op. 257

Calling: musicbrainzngs.get_release_by_id with: 8b9fa492-3aac-409f-a5a5-ee59111847d3
1 [untitled]
2 [untitled]
3 [untitled]
4 [untitled]
5 [untitled]
6 [untitled]
7 [untitled]
8 [untitled]

Calling: musicbrainzngs.get_release_by_id with: 06b3d1da-0afe-44b2-ab60-8357cda81c2e
1 Life Is Like a Samba
2 Can You Imagine
3 Hermosa Skyline
4 Some Other Sunset
5 East Coast Dancer
6 Stages
7 Moment in Hyde Park
8 Oceana
9 Take a Look Inside My Heart
10 Gold Coast
11 Wind Season
12 Los Angeles
13 Seagull’s Paradise
14 If I Could Reach Rainbows

Process finished with exit code 0

You search query is


Expected would be something like:

artist:"The Velvet Underground" and release:"White Light/White Heat"

Note the use of colons instead of equal signs and putting the search strings into quotes so it looks for the entire phrase and not just the first word.

Also when you use musicbrainzngs you must not urlencode the parameter. The library takes care of building a valid URL. You can focus on using the proper search syntax.

The search query is using Lucene search syntax. The valid field names for MusicBrainz are documented in the MusicBrainz search API docs I linked above. Details on the general capabilities of Lucene’s query language can be found at org.apache.lucene.queryparser.classic (Lucene 7.7.2 API)


I was just about to report the same thing, the encoding was getting in the way.

Thank you so much for your help, I’ve got the basics start writing my tool now.

All the Best