# MusicBrainz Scraper · Artists, Releases, Labels & Recordings (`reapx/musicbrainz-scraper`) Actor

Extract comprehensive MusicBrainz data for artists, releases, labels, and recordings. Get structured MBID identifiers, release dates, genres, countries, and barcodes without browser automation.

- **URL**: https://apify.com/reapx/musicbrainz-scraper.md
- **Developed by:** [Tarek Etman](https://apify.com/reapx) (community)
- **Categories:** News, Videos, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.30 / 1,000 record returneds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

![reapX — public sources in, addressable records out](https://reapx.dev/reapx.gif)

## MusicBrainz Scraper · Artists, Releases, Labels & Recordings

The **MusicBrainz scraper** extracts comprehensive, structured music database records directly from the official MusicBrainz REST API (`https://musicbrainz.org/ws/2/`). Query artists, releases, record labels, and sound recordings with custom Lucene search queries, genre tags, ISO country codes, and release decades. Every row includes standard addressable entity slugs (`slug`), canonical MusicBrainz UUIDs (`mbid`), credit information, track counts, release dates, and barcodes.

> Maintained by **reapX**. Every row cites the Apify run that produced it — nothing is
> inferred, modelled or filled in, and a field absent from the source is absent from the row.
> The extracted archive for this source is browsable at
> [reapx.dev/data/musicbrainz-scraper/](https://reapx.dev/data/musicbrainz-scraper/) and mirrored as an open dataset on
> [Hugging Face](https://huggingface.co/datasets/reapxdev/musicbrainz-scraper) and
> [Kaggle](https://www.kaggle.com/datasets/reapxdev/musicbrainz-scraper). Questions: reapxdev@proton.me

***

### Features

- **Multi-Entity Extraction**: Retrieve structured data for **Artists**, **Releases**, **Labels**, and **Recordings**.
- **Addressable Entity Key**: Emits a normalized `slug` (e.g. `the-beatles`, `pink-floyd`, `abbey-road`) for direct entity page routing and indexing across knowledge graphs.
- **Canonical MBIDs**: Preserves exact 36-character MusicBrainz UUID identifiers in the `mbid` field.
- **Rich Lucene Search Support**: Combine free-text queries, genre tags (`tag:rock`), country codes (`country:GB`), and decade ranges (`date:[1970 TO 1979]`).
- **Compliant Rate Limiting**: Built-in 1 request per second throttling with automatic exponential backoff on HTTP 429 and 503 status codes.
- **No Headless Browser Overhead**: Uses direct HTTP API calls for maximum efficiency and speed.
- **Pay-Per-Event Pricing**: Billed strictly per valid record returned; rate-limited, empty, or failed requests cost $0.

***

### ⬇️ Input

Configure the MusicBrainz Scraper using the input parameters below.

| Parameter | Type | Required | Default | Description | Example |
| :--- | :--- | :--- | :--- | :--- | :--- |
| `entityType` | `string` | **Yes** | `"artist"` | Select MusicBrainz entity category: `artist`, `release`, `label`, or `recording`. | `"artist"` |
| `query` | `string` | No | `"tag:rock AND country:GB"` | Free-text keyword query or custom Lucene search string. | `"artist:Pink Floyd"` |
| `genre` | `string` | No | `""` | Musical genre or community style tag filter. | `"jazz"` |
| `country` | `string` | No | `""` | 2-letter ISO 3166-1 alpha-2 country code. | `"GB"` |
| `decade` | `string` | No | `""` | Release or activity decade filter (e.g. 1970s, 1980s). | `"1970s"` |
| `maxResults` | `integer` | **Yes** | `50` | Maximum number of entity records to extract and push. | `50` |

#### Input Example

```json
{
  "entityType": "release",
  "query": "tag:jazz AND country:US",
  "genre": "jazz",
  "country": "US",
  "decade": "1960s",
  "maxResults": 50
}
```

***

### ⬆️ Output

The scraper writes extracted records directly to the run's default dataset. Each row corresponds to a single MusicBrainz entity.

#### Output Dataset Fields

| Field Name | Type | Description | Example |
| :--- | :--- | :--- | :--- |
| `slug` | `string` | Normalized URL-friendly slug derived from entity name or title. | `"the-beatles"` |
| `mbid` | `string` | Canonical 36-character MusicBrainz UUID identifier. | `"b10bbbfc-cf9e-42e0-be17-e2c3e1d2600d"` |
| `name` | `string` | Human-readable name of the artist, release, label, or recording. | `"The Beatles"` |
| `entityType` | `string` | Category of entity (`artist`, `release`, `label`, `recording`). | `"artist"` |
| `type` | `string` | Subtype classification (e.g. `Group`, `Person`, `Album`, `Single`). | `"Group"` |
| `country` | `string` | ISO 3166-1 alpha-2 country code of origin. | `"GB"` |
| `area` | `string` | Associated geographic area or region name. | `"United Kingdom"` |
| `disambiguation` | `string` | MusicBrainz comment distinguishing identical entity names. | `"UK rock band"` |
| `date` | `string` | Primary release date or activity start date. | `"1969-09-26"` |
| `lifeSpanStart` | `string` | Formation or birth date. | `"1960"` |
| `lifeSpanEnd` | `string` | Dissolution or death date. | `"1970"` |
| `tags` | `string` | Comma-separated genre and style tags. | `"rock, pop, classic rock"` |
| `score` | `integer` | Search relevance score (0–100). | `100` |
| `barcode` | `string` | Commercial EAN/UPC barcode (releases). | `"077774644624"` |
| `artistCredit` | `string` | Credited artists or collaborators. | `"The Beatles"` |
| `label` | `string` | Associated record label name(s). | `"Apple Records"` |
| `format` | `string` | Physical or digital format (e.g. Vinyl, CD). | `"Vinyl"` |
| `trackCount` | `integer` | Total number of tracks on release. | `17` |
| `length` | `integer` | Duration in milliseconds (recordings). | `260000` |
| `url` | `string` | Canonical MusicBrainz entity webpage URL. | `"https://musicbrainz.org/artist/b10bbbfc-cf9e-42e0-be17-e2c3e1d2600d"` |

#### Sample Output Record

```json
{
  "slug": "pink-floyd",
  "mbid": "83d91898-7763-47d7-b03b-b92132375c47",
  "name": "Pink Floyd",
  "entityType": "artist",
  "type": "Group",
  "country": "GB",
  "area": "United Kingdom",
  "disambiguation": "UK progressive rock band",
  "date": "1965",
  "lifeSpanStart": "1965",
  "lifeSpanEnd": "2014",
  "tags": "progressive rock, psychedelic rock, art rock",
  "score": 100,
  "barcode": "",
  "artistCredit": "",
  "label": "",
  "format": "",
  "trackCount": 0,
  "length": 0,
  "url": "https://musicbrainz.org/artist/83d91898-7763-47d7-b03b-b92132375c47"
}
```

***

### How it works

1. **HTTP Query Execution**: Sends direct GET requests to `https://musicbrainz.org/ws/2/{entity}` without launching headless browser instances.
2. **Lucene Search Integration**: Translates input parameters (keywords, genre, country, decade) into standard MusicBrainz Lucene query syntax.
3. **Rate Limiting & Resiliency**: Enforces a strict 1 request/second rule with `User-Agent: reapx/1.0 ( reapxdev@proton.me )` and exponential backoff retry on HTTP 429 or 503 responses.
4. **Key Normalization**: Automatically transforms entity names into clean, lowercased ASCII slugs (`slug`), while preserving exact MusicBrainz UUIDs (`mbid`).
5. **Streaming Output**: Emits items row-by-row into the default dataset as they are fetched.

***

### ❓ FAQ

##### How are MusicBrainz rate limits handled?

MusicBrainz requires clients to limit requests to 1 per second and present a descriptive User-Agent header. This scraper enforces rate limits natively and retries transparently if temporary rate limit errors (HTTP 429/503) occur.

##### Can I search using complex Lucene queries?

Yes. You can supply full Lucene query strings in the `query` field, such as `artist:"Miles Davis" AND type:Album AND date:[1950 TO 1960]`.

##### What is the `slug` field used for?

The `slug` field provides a clean, predictable URL identifier (e.g. `pink-floyd`) suitable for entity page routing, knowledge graph cross-linking, and dataset deduplication.

##### How does pricing work?

This actor runs under Pay-Per-Event pricing. You are charged a flat micro-fee per valid entity record returned. Searches yielding zero results or failing due to rate limits cost nothing.

***

### 💬 Your feedback

Have feature requests, questions, or bug reports? Reach out directly to **reapx**:

- Email: **reapxdev@proton.me**
- Data Hub: [reapx.dev/data/musicbrainz-scraper/](https://reapx.dev/data/musicbrainz-scraper/)

***

*Disclaimer: Unofficial - not affiliated with MusicBrainz / MetaBrainz Foundation. Collects public data only. reapx. Contact reapxdev@proton.me.*

### 🧪 Example input

A real, runnable configuration — this is an actual input this Actor has run with.

```json
{
  "entityType": "artist",
  "query": "tag:rock AND country:US",
  "genre": "rock",
  "country": "US",
  "decade": "1960s",
  "maxResults": 50
}
```

### 📄 Sample output

One real row from a real run of this Actor, unedited.

```json
{
  "slug": "the-beatles",
  "mbid": "b10bbbfc-cf9e-42e0-be17-e2c3e1d2600d",
  "name": "The Beatles",
  "entityType": "artist",
  "type": "Group",
  "country": "GB",
  "area": "United Kingdom",
  "disambiguation": "UK rock band, “The Fab Four”",
  "date": "1960-03-27",
  "lifeSpanStart": "1960-03-27",
  "lifeSpanEnd": "1970-04-10",
  "tags": "rock, pop, progressive rock, 80s, heavy metal, pop-rock, orchestral, experimental, british, uk, 60s, hard rock, indie rock, folk rock, psychedelic rock, psychedelic, blues rock, britpop, art rock, folk-rock, baroque pop, classic rock, 1960s, psychedelic pop, experimental rock, pop rock, europop, british invasion, rock and roll, rock roll, beat, english, sunshine pop, folk pop, rock music, liverpool, parlophone, united kingdom, hair metal, europe, 1, bbc, film soundtrack, classic pop and rock, singer songwriter, classical pop, instrumental pop, merseybeat, adult alternative pop rock, tribute albums, british psychedelia, orchestral pop, pop-metal, psychedelia, male vocalists, the-beatles, mainstream rock, boys band, abbey road, rock & roll, pop/rock, rhythm & blues, overrated, psychedelic/garage, art pop, one beatles, n., popular music, a filk artist, british rhythm & blues, beat music, get back, favoritos, the beatles - primal colours, reino unido, rock groups, vyrzukhisuc-artiest",
  "score": 100,
  "barcode": "",
  "artistCredit": "",
  "label": "",
  "format": "",
  "trackCount": 0,
  "length": 0,
  "url": "https://musicbrainz.org/artist/b10bbbfc-cf9e-42e0-be17-e2c3e1d2600d"
}
```

### ⚠️ Run outcomes and error handling

This Actor reports what happened in the run's **status message**, and it always keeps whatever it collected. These are the outcomes you can get and what each one means.

| Outcome | What it means |
|---|---|
| **Success** | Rows were returned and you were charged `record-returned` at $0.002 per row. |
| **No matches** | The source returned nothing for your filters. **Nothing is charged.** Widen the date window or drop a filter. |

#### What is guaranteed either way

- **Every row is pushed as it is built**, not buffered to the end of the run. Anything that buffers output loses everything to a timeout, a block or a migration; this does not.
- **A field absent from the source is absent from the row.** Nothing is inferred, modelled or filled in to make a row look complete.

# Actor input Schema

## `entityType` (type: `string`):

Select the MusicBrainz entity category to search and extract: <code>artist</code>, <code>release</code>, <code>label</code>, or <code>recording</code>. <br><br><b>Consequence:</b> Determines the target dataset schema and source endpoint queried. <b>Empty value:</b> Defaults to <code>artist</code>.

## `query` (type: `string`):

Free-text search term or custom Lucene query for MusicBrainz metadata (e.g. <code>tag:rock AND country:GB</code> or <code>artist:Pink Floyd</code>). <br><br><b>Consequence:</b> Broader queries return more matching entity records, increasing run time and dataset size. <b>Empty value:</b> Leave empty when using specific field filters below.

## `genre` (type: `string`):

Filter MusicBrainz entities by musical genre tag (e.g. <code>rock</code>, <code>jazz</code>, <code>electronic</code>, <code>classical</code>, <code>hip-hop</code>). <br><br><b>Consequence:</b> Restricts search results strictly to entities associated with the specified tag. <b>Empty value:</b> Leave empty to include entities across all music genres.

## `country` (type: `string`):

Filter entities by 2-letter ISO country code (e.g. <code>GB</code> for United Kingdom, <code>US</code> for United States, <code>DE</code> for Germany). <br><br><b>Consequence:</b> Filters results to entities originated in or assigned to the specified country. <b>Empty value:</b> Leave empty to query entities globally across all countries.

## `decade` (type: `string`):

Filter releases or recordings by decade (e.g. <code>1960s</code>, <code>1970s</code>, <code>1980s</code>, <code>1990s</code>, <code>2000s</code>, <code>2010s</code>, <code>2020s</code>). <br><br><b>Consequence:</b> Appends date range constraints to the search query. <b>Empty value:</b> Leave empty to include records regardless of release decade.

## `maxResults` (type: `integer`):

Maximum number of MusicBrainz entity records to return and push to the default dataset (e.g. <code>50</code> or <code>100</code>). <br><br><b>Consequence:</b> Higher values retrieve larger datasets but require more API pagination requests. <b>Empty value:</b> Defaults to 50 records.<br><br>The higher the number, the longer the run takes and the more you are charged, because you pay per row returned.

## Actor input object example

```json
{
  "entityType": "artist",
  "query": "tag:rock AND country:GB",
  "maxResults": 50
}
```

# Actor output Schema

## `results` (type: `string`):

Every record found by this run, one row per item, in the default dataset.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "entityType": "artist",
    "query": "tag:rock AND country:GB",
    "maxResults": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("reapx/musicbrainz-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "entityType": "artist",
    "query": "tag:rock AND country:GB",
    "maxResults": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("reapx/musicbrainz-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "entityType": "artist",
  "query": "tag:rock AND country:GB",
  "maxResults": 50
}' |
apify call reapx/musicbrainz-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,reapx/musicbrainz-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/RuQxNM618RbF4vFvW/builds/Iy1kPxfSQQEYurV4V/openapi.json
