# Concert Archives Scraper - Concerts, Tours, Venues & Setlists (`abotapi/concert-archives-scraper`) Actor

Scrape Concert Archives concert and tour history: past and upcoming dates, venues, cities, line-ups, tours, genres, tickets and setlists. Search by band, venue or location, or paste links. Incremental monitoring with NEW, UPDATED, REAPPEARED, EXPIRED, resume and MCP export.

- **URL**: https://apify.com/abotapi/concert-archives-scraper.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Categories:** Other, Developer tools, Travel
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 concert records

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

## Concert Archives Scraper - Concerts & Tour History

Scrape concert and tour history from Concert Archives, the fan-built live-music
database. Look up a band, a venue or a city and get its complete concert
history: past dates going back decades, upcoming shows, the billed line-up,
tours, venues, locations, ticket links and the songs actually played.

Built for the questions a ticketing feed cannot answer. Where has this band
played, and when were they last in my city? What has this venue hosted? What
did they play on the night?

### What you get

One row per concert:

| Group | Fields |
|---|---|
| Identity | `kind`, `recordId`, `concertId`, `url`, `slug`, `title` |
| When | `startDate`, `endDate`, `dateText`, `isUpcoming`, `eventStatus` |
| Who | `headliner`, `lineup`, `performers` (name, page link, genre, image), `artistGenres` |
| Where | `venueName`, `venueUrl`, `venueAddress`, `venueCity`, `venueRegion`, `venueCountry`, `locationText`, `locationUrl` |
| Context | `tourName`, `description`, `imageUrl`, `labels`, `hasSetlist`, `hasPhotos` |
| Tickets | `ticketUrl`, `ticketVendor` |
| Community | `lineupCount`, `attendeeCount`, `photoCount`, `setlistCount` |
| Setlists | `setlists`: per band, the songs in order, plus a link to the setlist page |
| Monitoring | `changeType`, `changedFields`, `firstSeenAt`, `lastSeenAt` |

#### Sample row (fictional values)

```json
{
  "kind": "concert",
  "recordId": "00000000",
  "concertId": "00000000",
  "url": "https://www.concertarchives.org/concerts/sample-band--00000000",
  "title": "Sample Band",
  "startDate": "2027-01-15",
  "isUpcoming": true,
  "tourName": "Sample World Tour",
  "headliner": "Sample Band",
  "lineup": ["Sample Band", "Sample Support"],
  "venueName": "Sample Arena",
  "venueUrl": "https://www.concertarchives.org/venues/sample-arena",
  "venueCity": "Sample City",
  "venueRegion": "Sample State",
  "venueCountry": "Sample Country",
  "ticketVendor": "Sample Tickets",
  "attendeeCount": 42,
  "setlistCount": 1,
  "changeType": "NEW"
}
```

### How to use it

#### Search mode (default)

Type a keyword and pick what it should match:

- **Bands** returns that band's concert and tour history.
- **Venues** returns everything played at that venue.
- **Locations** returns everything played in that city or region.

The keyword is matched against the site's own index and the top result is used,
so `red rocks` finds the amphitheatre without you looking up its page first.

#### URL mode

Paste links, one per line. Band, venue and location pages are walked forward
through their whole history. A single concert link is read as one record. A
search link or an advanced concert-search link works too.

#### Filters (both modes)

- **Upcoming or past concerts** narrows the history to only upcoming or only
  past dates. Works on band, venue and location pages.
- **Year** returns only concerts from one year. Works on band and venue pages.
  Location pages do not support it: the site accepts the setting there and
  ignores it, so rather than hand you an unfiltered result that looks filtered,
  the run says so in the log and returns every year. Use a band or venue page
  when you need a single year.

#### Depth and cost

- **Max items** defaults to 20. Set it to 0 for the whole history, which for a
  long-running band can be thousands of concerts across dozens of pages.
- **Max pages per scope** defaults to 0, meaning no page limit, so Max items is
  the only cap that stops a run early.
- **Fetch concert details** (on by default) reads each concert's own page to add
  the full billed line-up with genres, the description, the poster image, the
  ticket seller and link, the event status and the community counts. It adds a
  per-concert surcharge, so turn it off for a fast, cheap list-only pull.
- **Include setlists** (off by default) adds the songs played, per band, for
  concerts that have a setlist. It costs one extra read per concert, so runs
  take longer. It does not add a second surcharge.

### Recurring monitoring

Turn on **Incremental changes for scheduled runs** and run this on a schedule.
The first run returns everything as `NEW`. Later runs return only what moved:

- `NEW` first time this concert was seen
- `UPDATED` something changed; `changedFields` names what
- `REAPPEARED` back after having gone missing
- `UNCHANGED` returned only when you turn on Emit unchanged
- `EXPIRED` returned only when you turn on Emit expired, and only after a run
  that scanned the whole tracked history without hitting a limit or an error

State is kept separately for each search, link and filter setup, so a run
filtered to one year never tombstones the concerts that filter excludes. Use
**State key** to name a campaign, or to deliberately share state between two
differently configured runs.

**Resume from a previous run** is a different thing: paste a run or dataset ID
to continue ONE interrupted pull without collecting the same concerts twice.

### Send results into your apps (MCP connectors)

Optionally pipe the results straight into the tools you already use, over Model
Context Protocol. Authorize a connector under Apify, Settings, API &
Integrations, then set:

- `mcpConnectors` the connector IDs to send to, one per line
- `notionParentPageUrl` the Notion page to create item pages under, for the
  Notion connector
- `maxNotifyListings` how many items to send per connector per run

Notion gets a page per concert. Other connectors get a best-effort write or a
digest. This never changes the dataset, and a connector problem never fails the
scrape.

### What this actor deliberately does not collect

Concert Archives is a community site: concerts carry attendee lists, comments
and user-uploaded photos, all attached to real people's accounts. This actor
collects the **counts** of those (`attendeeCount`, `photoCount`) and never the
names, usernames or comment text behind them.

### Notes

- No account and no API key is needed.
- The default proxy setting works on every Apify plan.
- Dates come from an archive maintained by fans. Very old entries can be
  approximate, and `startDate` is left empty rather than guessed when the site
  does not publish a parseable date.

# Actor input Schema

## `mode` (type: `string`):

Search looks up a band, venue or location by keyword and returns its concert history. URL mode reads the specific Concert Archives pages you paste.

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

Search mode: a keyword, for example a band name, a venue name or a city. Used together with Search type below.

## `searchType` (type: `string`):

Search mode: what the keyword should match. Bands returns that band's concert and tour history, Venues returns everything played at that venue, Locations returns everything played in that city or region.

## `urls` (type: `array`):

URL mode: pages to read, one per line. Band, venue and location pages are walked forward through their whole history. A single concert link is read as one record. A search link or an advanced concert-search link is also accepted. Multi-value supported.

## `dateFilter` (type: `string`):

Narrow the concert history to only upcoming or only past concerts. Applies to band, venue and location pages in both modes. Leave on All to return the complete history.

## `year` (type: `integer`):

Return only concerts from this year, for example 2024. Leave at 0 for every year. Band and venue pages support this; location pages do not, and a run that asks for it on a location says so in the log and returns every year instead.

## `fetchDetails` (type: `boolean`):

Read each concert's own page to add the full billed line-up with genres, the description, the poster image, the ticket seller and link, the event status and the community line-up, attendee and photo counts. Adds a per-concert surcharge (see the section caption above).

## `includeSetlists` (type: `boolean`):

Also return the songs played, per band, for concerts that have a setlist on the site. Needs Fetch concert details to be on. This adds one extra read per concert, so runs take longer; it does not add a second surcharge.

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

Stop after this many concerts (0 = no limit; the run then stops when the history runs out).

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

Upper bound on how many pages each band, venue, location or link is walked through (0 = no limit). Defaults wide open so Max items is the only cap that stops a run early.

## `resumeFromRunId` (type: `string`):

Paste a previous run ID or dataset ID to continue a large pull without returning concerts already collected there.

## `incrementalMode` (type: `boolean`):

Turn this on for daily or recurring monitoring. The first run returns every matching concert as NEW. Later runs normally return only NEW, UPDATED and REAPPEARED concerts. Turn on Emit unchanged or Emit expired only when you also want those rows returned (and billed). State is kept separately for each search, link and filter setup; use State key to name or deliberately share a monitoring campaign.

## `stateKey` (type: `string`):

Optional. Name this monitoring campaign to keep its state stable, or deliberately share state across differently configured runs. Leave empty to let the actor derive a key automatically from the search, link and filter settings.

## `emitUnchanged` (type: `boolean`):

Off by default. Turn on to also return concerts that have not changed since the last run, marked UNCHANGED. This returns, and bills, extra rows you already have.

## `emitExpired` (type: `boolean`):

Off by default. Turn on to also return concerts that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked history.

## `mcpConnectors` (type: `array`):

Optionally send results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize one under Apify, Settings, API & Integrations, then select it here. Notion gets a rich page-per-item export; other connectors get a best-effort write or digest. Leave empty to skip; never changes the dataset output.

## `notionParentPageUrl` (type: `string`):

URL or id of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.

## `maxNotifyListings` (type: `integer`):

Cap on items written to each connector per run. Does not affect the dataset.

## `proxyConfiguration` (type: `object`):

Apify Proxy settings. The prefilled default works on every Apify plan.

## Actor input object example

```json
{
  "mode": "search",
  "query": "the killers",
  "searchType": "bands",
  "urls": [
    "https://www.concertarchives.org/venues/red-rocks-amphitheatre--11"
  ],
  "dateFilter": "all",
  "year": 0,
  "fetchDetails": true,
  "includeSetlists": false,
  "maxItems": 20,
  "maxPages": 0,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "maxNotifyListings": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

# 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 = {
    "mode": "search",
    "query": "the killers",
    "searchType": "bands",
    "urls": [
        "https://www.concertarchives.org/venues/red-rocks-amphitheatre--11"
    ],
    "dateFilter": "all",
    "year": 0,
    "fetchDetails": true,
    "includeSetlists": false,
    "maxItems": 20,
    "maxPages": 0,
    "incrementalMode": false,
    "emitUnchanged": false,
    "emitExpired": false,
    "maxNotifyListings": 50,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/concert-archives-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 = {
    "mode": "search",
    "query": "the killers",
    "searchType": "bands",
    "urls": ["https://www.concertarchives.org/venues/red-rocks-amphitheatre--11"],
    "dateFilter": "all",
    "year": 0,
    "fetchDetails": True,
    "includeSetlists": False,
    "maxItems": 20,
    "maxPages": 0,
    "incrementalMode": False,
    "emitUnchanged": False,
    "emitExpired": False,
    "maxNotifyListings": 50,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/concert-archives-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 '{
  "mode": "search",
  "query": "the killers",
  "searchType": "bands",
  "urls": [
    "https://www.concertarchives.org/venues/red-rocks-amphitheatre--11"
  ],
  "dateFilter": "all",
  "year": 0,
  "fetchDetails": true,
  "includeSetlists": false,
  "maxItems": 20,
  "maxPages": 0,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "maxNotifyListings": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call abotapi/concert-archives-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,abotapi/concert-archives-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/qnxShYHnGSvvCUcMx/builds/r3whJwziTRjCoRHN0/openapi.json
