# Setlist Fm Scraper (`automation-lab/setlist-fm-concert-setlists`) Actor

Search Setlist.fm and export concert dates, tours, venues, locations, and complete ordered song setlists for live-performance research.

- **URL**: https://apify.com/automation-lab/setlist-fm-concert-setlists.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.40 / 1,000 item extracteds

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/actors/running/actors-in-store.md#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

## Setlist Fm Scraper

Search public Setlist.fm pages and export concert identity, dates, tours, venues,
locations, and complete ordered song setlists. The Actor turns setlist fm pages
into analysis-ready JSON without requiring a Setlist.fm API key.

Use it for live-repertoire research, tour comparisons, venue programming,
music journalism, fan projects, and recurring concert-data pipelines.

### What does Setlist Fm Scraper do?

The Actor supports two entry points:

- search queries for an artist, venue, city, tour, or date;
- public Setlist.fm search, artist, venue, and individual setlist URLs.

For every discovered concert it opens the detail page. This avoids the truncated
song previews shown on listing pages and preserves performance order, main-set
and encore sections, cover attribution, and available concert notes.

### Who is it for?

- **Music analysts** comparing live repertoires across dates and tours.
- **Journalists and researchers** building sourced concert timelines.
- **Artist teams** reviewing tour set variation and song rotation.
- **Venue teams** studying past programming and performer history.
- **Developers** feeding concert metadata into dashboards or data warehouses.
- **Fans and archivists** creating personal, non-commercial research datasets.

### Why use this Actor?

Setlist.fm's public pages are designed for browsing, not bulk analysis. This
Actor provides one stable event record per concert, with nested ordered songs.
It follows listing pages, deduplicates concert URLs, respects a global result
limit, retries transient source failures with fresh proxy sessions, and fails
clearly when Setlist.fm returns a challenge or unexpected page.

The runtime uses residential US proxy sessions because repeated direct and
ordinary datacenter requests can receive an AWS WAF challenge. No browser is
needed, so runs remain lighter than browser-based alternatives.

### What data can I extract?

| Field | Meaning |
| --- | --- |
| `setlistId` | Stable identifier parsed from the Setlist.fm URL |
| `artist` | Performing artist |
| `eventDate` | Concert date in `YYYY-MM-DD` form when available |
| `tour` | Tour name when listed |
| `venue` | Venue name |
| `city` | Venue city/locality |
| `country` | Country label displayed by Setlist.fm |
| `songCount` | Number of listed songs |
| `songs` | Ordered song objects with section and cover details |
| `notes` | Concert-level note when available |
| `setlistUrl` | Canonical public source page |
| `artistUrl` | Linked artist page |
| `venueUrl` | Linked venue page |
| `discoveredFrom` | Query/listing URL that found the concert |
| `scrapedAt` | Extraction timestamp |

A concert can legitimately have `songCount: 0` when the event exists on
Setlist.fm but contributors have not added songs. The Actor preserves that event
rather than inventing or inferring a setlist.

### How to search Setlist.fm

Setlist.fm query syntax can target common research dimensions:

```text
artist:(Radiohead)
venue:(Madison Square Garden)
city:(London)
tour:(European Tour 2025)
date:2025-12-16
artist:(Radiohead) tour:(European Tour 2025)
```

Put one or more expressions in `queries`. They are processed independently and
results are deduplicated by canonical concert URL.

For precise entity selection, use a known artist or venue page in `startUrls`.

### Input parameters

| Input | Type | Default | Description |
| --- | --- | --- | --- |
| `queries` | string array | none | Setlist.fm search expressions |
| `startUrls` | URL array | none | Search, artist, venue, or concert pages |
| `maxItems` | integer | `20` | Global maximum complete concert records |
| `maxPages` | integer | `3` | Listing pages followed per query or URL |

At least one query or start URL is required. Only `setlist.fm` URLs are
accepted. `maxItems` ranges from 1 to 5,000 and `maxPages` from 1 to 100.

### Get started

1. Open the Actor input page.
2. Keep the prefilled tour query or enter your own Setlist.fm query.
3. Set a small `maxItems` while evaluating the output.
4. Click **Start**.
5. Open the default dataset when the run finishes.
6. Export JSON, CSV, Excel, XML, or connect the dataset API.

A useful first input is:

```json
{
  "queries": ["artist:(Radiohead) tour:(European Tour 2025)"],
  "maxItems": 5,
  "maxPages": 1
}
```

### Output example

A current source record has this shape (shortened to two songs):

```json
{
  "setlistId": "34cc517",
  "artist": "Radiohead",
  "eventDate": "2025-12-16",
  "tour": "European Tour 2025",
  "venue": "Royal Arena",
  "city": "Copenhagen",
  "country": "Denmark",
  "songCount": 25,
  "songs": [
    {
      "position": 1,
      "name": "2 + 2 = 5",
      "section": "Main set",
      "encore": null,
      "info": null,
      "isCover": false,
      "coverArtist": null
    },
    {
      "position": 25,
      "name": "Karma Police",
      "section": "Encore 1",
      "encore": 1,
      "info": null,
      "isCover": false,
      "coverArtist": null
    }
  ],
  "setlistUrl": "https://www.setlist.fm/setlist/radiohead/2025/royal-arena-copenhagen-denmark-34cc517.html"
}
```

### Song order, encores, and covers

`songs.position` is one-based and follows source order. Main-set songs use
`section: "Main set"` and `encore: null`. Encore markers become `Encore 1`,
`Encore 2`, and so on. When Setlist.fm identifies a cover, `isCover` is true and
`coverArtist` contains the linked original artist when available.

No separate charge is made for songs. Songs are included inside each charged
concert `item` record.

### How much does it cost to extract concert setlists?

The Actor uses pay-per-event pricing:

- one `start` event per run;
- one `item` event per saved concert record.

The exact active tier prices appear on the Actor pricing tab before you start a
run. On the BRONZE tier, the price is $0.005 per run plus $0.003992 per saved
concert. Proxy and platform usage are paid by the Actor under pay-per-event
pricing rather than billed as a separate output event.

Examples at BRONZE rates:

| Records | Example charge |
| ---: | ---: |
| 1 | $0.008992 |
| 10 | $0.04492 |
| 100 | $0.40420 |

Higher subscription tiers receive the exact item price shown on the live
pricing tab. The one-time start fee remains $0.005.

### Recurring repertoire research

Schedule the Actor daily or weekly with the same artist or tour query. Save each
run's dataset ID and compare `setlistId`, `eventDate`, and `songs` downstream.
A source event with no songs today may contain a contributed setlist later.

The Actor does not maintain cross-run history or send alerts itself. Use Apify
Schedules, webhooks, dataset exports, or your own database for monitoring.

### Spreadsheet and database exports

Use the dataset export controls for CSV, Excel, JSON, XML, or RSS. For nested
song analysis, JSON preserves the full structure. In a warehouse, store the
concert row and flatten `songs` into a child table keyed by `setlistId` and
`position`.

### Webhooks and integrations

Common workflows include:

1. schedule an artist or tour query;
2. trigger a webhook when the run succeeds;
3. download the default dataset;
4. upsert concerts by `setlistId`;
5. flatten songs for repertoire-frequency analysis;
6. retain `setlistUrl` for attribution and audit.

Apify integrations can send results to Google Sheets, Make, Zapier, Slack, and
other services. Keep nested-song limitations of the destination in mind.

### Run with the Apify API

Replace `APIFY_TOKEN` with your token.

#### cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~setlist-fm-concert-setlists/runs?token=APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"queries":["date:2025-12-16"],"maxItems":3,"maxPages":1}'
```

#### JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/setlist-fm-concert-setlists').call({
  queries: ['artist:(Radiohead) tour:(European Tour 2025)'],
  maxItems: 5,
  maxPages: 1,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("APIFY_TOKEN")
run = client.actor("automation-lab/setlist-fm-concert-setlists").call(run_input={
    "startUrls": [{"url": "https://www.setlist.fm/setlists/radiohead-bd6bd12.html"}],
    "maxItems": 2,
    "maxPages": 1,
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)
```

### Use with MCP and AI assistants

Add the Actor to Claude Code through Apify MCP:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/setlist-fm-concert-setlists"
```

#### Claude Desktop, Cursor, and VS Code setup

Use this equivalent MCP JSON configuration in Claude Desktop, Cursor, or VS Code:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/setlist-fm-concert-setlists"
    }
  }
}
```

Example prompts:

- "Run the Setlist.fm Actor for Radiohead's European Tour 2025 and summarize song rotation."
- "Extract two recent setlists from this Setlist.fm artist URL."
- "Export concerts on 2025-12-16 and list which records include songs."

### Reliability and retry behavior

Setlist.fm protects public pages with AWS WAF. The Actor uses a small pool of
coherent residential proxy sessions and retries a failed request up to five
times, changing the session identity on each retry. Requests are sequential and
paced to reduce challenge frequency and unnecessary transfer.

After retry exhaustion, the run fails instead of returning a misleading empty
dataset. Rerun later if Setlist.fm is temporarily unavailable.

### Limits and source behavior

- Search relevance is controlled by Setlist.fm, not this Actor.
- Plain artist-name searches can include tribute acts; combine filters or use an
  artist URL for exact entity selection.
- Future events commonly exist before songs are contributed.
- Source edits can change fields between scheduled runs.
- Very large limits take longer because every event detail page is fetched.
- The Actor does not download images, audio, video, ads, or analytics assets.
- It does not use private accounts or the credentialed Setlist.fm API.

### Responsible use and legality

This Actor accesses public pages only. Use the data in accordance with
Setlist.fm's terms, applicable database/copyright rules, and local law. Respect
attribution, source licenses, privacy, and reasonable request volumes. Do not
use the Actor to republish protected content deceptively, identify private
individuals, or bypass access controls.

You are responsible for the purpose, frequency, retention, and redistribution
of your datasets.

### Troubleshooting

#### The run says no input was provided

Add at least one string to `queries` or one supported URL to `startUrls`.

#### My artist search includes a tribute act

Setlist.fm applies its own search matching. Use the exact artist page URL in
`startUrls`, or combine artist and tour filters for a narrower result.

#### A concert has zero songs

The event page exists but currently has no contributed songs. This is valid
source data, not a parser error. Choose an older tour or known concert if your
workflow requires repertoire.

#### The run failed after proxy retries

Setlist.fm challenged every bounded session. Wait and rerun rather than raising
concurrency. If failures persist, verify that the URL is public and current.

#### My run stops before all history is collected

Increase both `maxItems` and `maxPages`. `maxItems` is global; `maxPages` applies
separately to each listing input.

### Data quality tips

- Use artist URLs for exact artist identity.
- Use historical tours when song completeness matters.
- Keep `setlistId` as your stable upsert key.
- Preserve `setlistUrl` for attribution and change audits.
- Treat null location/tour fields and zero-song events as source state.
- Start with a small run before collecting a long artist history.

### FAQ

#### Does this require a Setlist.fm API key?

No. It extracts public server-rendered pages.

#### Does it scrape complete songs or listing previews?

It opens every discovered concert detail page and extracts the ordered list
available there. It does not rely on the truncated listing preview.

#### Can I search by venue, city, tour, or date?

Yes. Put the corresponding Setlist.fm expression in `queries`, or provide a
public venue/search URL.

#### Can I monitor changes?

Yes, by scheduling repeated runs and comparing datasets externally. The Actor
does not itself retain snapshots or send alerts.

#### Are empty setlists charged?

Yes. One `item` is a useful concert event record even when contributors have not
added songs. The record retains the event identity, artist, date, venue, and
source URL.

#### Can I increase concurrency?

Concurrency is intentionally conservative and is not exposed as an input.
Sequential requests improve reliability on the protected source.

### Related Automation Lab Actors

For adjacent public music and event research, consider:

- [Bandsintown Events Scraper](https://apify.com/automation-lab/bandsintown-events-scraper)
  for upcoming artist and venue events.
- [Billboard Music Charts Scraper](https://apify.com/automation-lab/billboard-music-charts-scraper)
  for dated chart rankings and artist performance.

These Actors use different sources and record contracts; they do not replace
Setlist.fm's contributor-maintained concert setlists.

# Actor input Schema

## `queries` (type: `array`):

Search by artist, venue, city, tour, or date. Examples: artist:(Radiohead), venue:(Madison Square Garden), city:(London), tour:(European Tour 2025), date:2025-12-16.

## `startUrls` (type: `array`):

Optional Setlist.fm search, artist, venue, or individual concert setlist pages. Other domains are rejected.

## `maxItems` (type: `integer`):

Maximum number of complete concert setlist records saved across all inputs.

## `maxPages` (type: `integer`):

Maximum listing pages followed for each query or listing URL.

## Actor input object example

```json
{
  "queries": [
    "artist:(Radiohead) tour:(European Tour 2025)"
  ],
  "startUrls": [
    {
      "url": "https://www.setlist.fm/setlists/radiohead-bd6bd12.html"
    }
  ],
  "maxItems": 20,
  "maxPages": 3
}
```

# Actor output Schema

## `overview` (type: `string`):

Open all extracted event and ordered song records in the overview view.

# 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 = {
    "queries": [
        "artist:(Radiohead) tour:(European Tour 2025)"
    ],
    "startUrls": [
        {
            "url": "https://www.setlist.fm/setlists/radiohead-bd6bd12.html"
        }
    ],
    "maxItems": 20,
    "maxPages": 3
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/setlist-fm-concert-setlists").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 = {
    "queries": ["artist:(Radiohead) tour:(European Tour 2025)"],
    "startUrls": [{ "url": "https://www.setlist.fm/setlists/radiohead-bd6bd12.html" }],
    "maxItems": 20,
    "maxPages": 3,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/setlist-fm-concert-setlists").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 '{
  "queries": [
    "artist:(Radiohead) tour:(European Tour 2025)"
  ],
  "startUrls": [
    {
      "url": "https://www.setlist.fm/setlists/radiohead-bd6bd12.html"
    }
  ],
  "maxItems": 20,
  "maxPages": 3
}' |
apify call automation-lab/setlist-fm-concert-setlists --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/setlist-fm-concert-setlists"
        }
    }
}
```

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/67GYU003sP3ioXOPt/builds/ZHO0laYGYUh2hWo5f/openapi.json
