A MusicBrainz-API-client for reading and submitting metadata
- Access metadata from MusicBrainz
- Submit metadata
- Smart and adjustable throttling, like MusicBrainz, it allows a bursts of requests
- Build in TypeScript definitions
This package is currently only developed for the use in a node.js environment. We are looking into making this package usable in the browser as well.
MusicBrainz asks that you to identify your application by filling in the 'User-Agent' Header.
By passing appName
, appVersion
, appMail
musicbrainz-api takes care of that.
If you plan to use this module for submitting metadata, please ensure you comply with the MusicBrainz Code of conduct/Bots.
Example, how to import 'musicbrainz-api:
import {MusicBrainzApi} from 'musicbrainz-api';
const mbApi = new MusicBrainzApi({
appName: 'my-app',
appVersion: '0.1.0',
appContactInfo: 'user@mail.org'
});
The following configuration settings can be passed
import {MusicBrainzApi} from 'musicbrainz-api';
const config = {
// MusicBrainz bot account username & password (optional)
botAccount: {
username: 'myUserName_bot',
password: 'myPassword'
},
// API base URL, default: 'https://musicbrainz.org' (optional)
baseUrl: 'https://musicbrainz.org',
appName: 'my-app',
appVersion: '0.1.0',
// Optional, default: no proxy server
proxy: {
host: 'localhost',
port: 8888
},
// Your e-mail address, required for submitting ISRCs
appMail: string
}
const mbApi = new MusicbrainzApi(config);
MusicBrainz API documentation: XML Web Service/Version 2 Lookups
Arguments:
- entity:
'area'
|'artist'
|'collection'
|'instrument'
|'label'
|'place'
|'release'
|'release-group'
|'recording'
|'series'
|'work'
|'url'
|'event'
- MBID (MusicBrainz identifier)
- query
const artist = await mbApi.lookup('artist', 'ab2528d9-719f-4261-8098-21849222a0f2');
Query argument | Query value |
---|---|
query.collection |
Collection MBID |
const artists = await mbApi.browse('artist', query);
Query argument | Query value |
---|---|
query.area |
Area MBID |
query.collection |
Collection MBID |
query.recording |
Recording MBID |
query.release |
Release MBID |
query.release-group |
Release-group MBID |
query.work |
Work MBID |
const collections = await mbApi.browse('collection', query);
Query argument | Query value |
---|---|
query.area |
Area MBID |
query.artist |
Artist MBID |
query.editor |
Editor MBID |
query.event |
Event MBID |
query.label |
Label MBID |
query.place |
Place MBID |
query.recording |
Recording MBID |
query.release |
Release MBID |
query.release-group |
Release-group MBID |
query.work |
Work MBID |
const events = await mbApi.browse('event', query);
Query argument | Query value |
---|---|
query.area |
Area MBID |
query.artist |
Artist MBID |
query.collection |
Collection MBID |
query.place |
Place MBID |
const instruments = await mbApi.browse('event', query);
Query argument | Query value |
---|---|
query.collection |
Collection MBID |
const labels = await mbApi.browse('label', query);
Query argument | Query value |
---|---|
query.area |
Area MBID |
query.collection |
Collection MBID |
query.release |
Release MBID |
const places = await mbApi.browse('place', query);
Query argument | Query value |
---|---|
query.area |
Area MBID |
query.collection |
Collection MBID |
const recordings = await mbApi.browse('recording', query);
Query argument | Query value |
---|---|
query.artist |
Area MBID |
query.collection |
Collection MBID |
query.release |
Release MBID |
query.work |
Work MBID |
const releases = await mbApi.browse('release', query);
Query argument | Query value |
---|---|
query.area |
Area MBID |
query.artist |
Artist MBID |
query.editor |
Editor MBID |
query.event |
Event MBID |
query.label |
Label MBID |
query.place |
Place MBID |
query.recording |
Recording MBID |
query.release |
Release MBID |
query.release-group |
Release-group MBID |
query.work |
Work MBID |
const releaseGroups = await mbApi.browse('release-group',query);
Query argument | Query value |
---|---|
query.artist |
Artist MBID |
query.collection |
Collection MBID |
query.release |
Release MBID |
const series = await mbApi.browse('series');
Query argument | Query value |
---|---|
query.area |
Area MBID |
query.artist |
Artist MBID |
query.editor |
Editor MBID |
query.event |
Event MBID |
query.label |
Label MBID |
query.place |
Place MBID |
query.recording |
Recording MBID |
query.release |
Release MBID |
query.release-group |
Release-group MBID |
query.work |
Work MBID |
const works = await mbApi.browse('work');
Query argument | Query value |
---|---|
query.artist |
Artist MBID |
query.xollection |
Collection MBID |
const urls = await mbApi.browse('url');
Query argument | Query value |
---|---|
query.artist |
Artist MBID |
query.xollection |
Collection MBID |
Implements XML Web Service/Version 2/Search.
There are different search fields depending on the entity.
Searches can be performed using the generic search function: query(entity: mb.EntityType, query: string | IFormData, offset?: number, limit?: number): Promise<entity>
Arguments:
- Entity type, which can be one of:
artist
: search fieldslabel
: search fieldsrecording
: search fieldsrelease
: search fieldsrelease-group
: search fieldswork
: search fieldsarea
: search fieldsurl
: search fields
query {query: string, offset: number, limit: number}
query.query
: supports the full Lucene Search syntax; you can find a detailed guide at Lucene Search Syntax. For example, you can set conditions while searching for a name with the AND operator.query.offset
: optional, return search results starting at a given offset. Used for paging through more than one page of results.limit.query
: optional, an integer value defining how many entries should be returned. Only values between 1 and 100 (both inclusive) are allowed. If not given, this defaults to 25.
For example, to find any recordings of 'We Will Rock You' by Queen:
const query = 'query="We Will Rock You" AND arid:0383dadf-2a4e-4d10-a46a-e9e041da8eb3';
const result = await mbApi.search('release-group', {query});
mbApi.search('area', 'Île-de-France');
Search a release with the barcode 602537479870:
mbApi.search('release', {query: {barcode: 602537479870}});
Same as previous example, but automatically serialize parameters to search query
mbApi.search('release', 'barcode: 602537479870');
Search artist:
const result = await mbApi.search('artist', {query: 'Stromae'});
Search release-group:
const result = await mbApi.search('release-group', {query: 'Racine carrée'});
Search a combination of a release-group and an artist.
const result = await mbApi.search('release-group', {artist: 'Racine carrée', releasegroup: 'Stromae'});
Submitting data via XML POST may be done using personal MusicBrainz credentials.
Using the XML ISRC submission API.
const mbid_Formidable = '16afa384-174e-435e-bfa3-5591accda31c';
const isrc_Formidable = 'BET671300161';
const xmlMetadata = new XmlMetadata();
const xmlRecording = xmlMetadata.pushRecording(mbid_Formidable);
xmlRecording.isrcList.pushIsrc(isrc_Formidable);
await mbApi.post('recording', xmlMetadata);
For all of the following function you need to use a dedicated bot account.
Use with caution, and only on a test server, it may clear existing metadata as side effect.const mbid_Formidable = '16afa384-174e-435e-bfa3-5591accda31c';
const isrc_Formidable = 'BET671300161';
const recording = await mbApi.lookup('recording', mbid_Formidable);
// Authentication the http-session against MusicBrainz (as defined in config.baseUrl)
const succeed = await mbApi.login();
assert.isTrue(succeed, 'Login successful');
// To submit the ISRC, the `recording.id` and `recording.title` are required
await mbApi.addIsrc(recording, isrc_Formidable);
const recording = await mbApi.lookup('recording', '16afa384-174e-435e-bfa3-5591accda31c');
const succeed = await mbApi.login();
assert.isTrue(succeed, 'Login successful');
await mbApi.addUrlToRecording(recording, {
linkTypeId: LinkType.stream_for_free,
text: 'https://open.spotify.com/track/2AMysGXOe0zzZJMtH3Nizb'
});
Actually a Spotify-track-ID can be submitted easier:
const recording = await mbApi.lookup('recording', '16afa384-174e-435e-bfa3-5591accda31c');
const succeed = await mbApi.login();
assert.isTrue(succeed, 'Login successful');
await mbApi.addSpotifyIdToRecording(recording, '2AMysGXOe0zzZJMtH3Nizb');
Implementation of the Cover Art Archive API.
import {CoverArtArchiveApi} from 'musicbrainz-api';
coverArtArchiveApiClient.getReleaseCovers(releaseMbid).then(releaseCoverInfo => {
console.log('Release cover info', releaseCoverInfo);
});
coverArtArchiveApiClient.getReleaseCovers(releaseMbid, 'front').then(releaseCoverInfo => {
console.log('Get best front cover', releaseCoverInfo);
});
coverArtArchiveApiClient.getReleaseCovers(releaseMbid, 'back').then(releaseCoverInfo => {
console.log('Get best back cover', releaseCoverInfo);
});
The JavaScript in runtime is compliant with ECMAScript 2017 (ES8). Requires Node.js® version 6 or higher.