# Songkick Scraper - Concert & Event Calendar (`abotapi/songkick-concert-calendar-scraper`) Actor

Scrape Songkick concert and event calendars: upcoming and past dates, venues, cities, artists, ticket availability and tour info across 100+ countries. Search by artist, venue or location, or paste event links. Incremental monitoring with NEW, UPDATED, REAPPEARED, EXPIRED, resume and MCP export.

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

## Pricing

from $1.20 / 1,000 event 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

## Songkick Concert Calendar Scraper

Pull concerts, festival dates and tour information from Songkick (songkick.com), one of the largest global concert calendars. Search by artist, venue or city, or paste any Songkick page, and get structured event records: date and time, venue with full address and coordinates, artist and supporting acts, ticket availability, tour name and capacity. Coverage spans 100+ countries, and recurring runs can report only what changed.

### Why This Scraper?

- **Any surface, one schema**: a single event record shape covers search results, artist tour dates, venue calendars, metro-area calendars and festival dates.
- **Rich location data**: venue name, street address, city, region, postal code, country and coordinates come with every calendar event, not just on detail pages.
- **Ticket monitoring**: each event's own page adds ticket availability (on sale, off sale, sold out), the ticket vendors and link, plus tour name, doors time and venue capacity.
- **Artist, venue and city search**: resolve a keyword to the top artist, venue or metro area and read its upcoming calendar, or search upcoming and past events directly.
- **Incremental monitoring**: recurring runs emit only NEW, UPDATED, REAPPEARED or EXPIRED events against the same search or links, with first-seen and last-seen timestamps.
- **Resume support**: continue an interrupted run without returning events already collected.
- **Multi-value URL mode**: paste any mix of artist, venue, metro-area, festival, calendar, search or event links in one run.

### Data You Get

> Sample shape, values are illustrative placeholders, not from a live listing.

| Field | Example value |
|---|---|
| `eventId` | `00000000` |
| `url` | `https://www.songkick.com/concerts/00000000-sample-artist-at-sample-arena` |
| `title` | `Sample Artist at Sample Arena` |
| `startDate` | `2027-01-15T19:30:00` |
| `endDate` | `2027-01-15` |
| `eventStatus` | `scheduled` |
| `eventType` | `concert` |
| `headliner` / `artistName` | `Sample Artist` |
| `artistGenres` | `["indie", "rock"]` |
| `performers` | `[{"name": "Sample Artist", "url": "https://www.songkick.com/artists/00000000-sample-artist", "genres": ["indie", "rock"]}, {"name": "Support Act", "url": null, "genres": []}]` |
| `venueName` | `Sample Arena` |
| `venueStreet` | `1 Sample Road` |
| `venueCity` | `Sample City` |
| `venueRegion` | `ST` |
| `venuePostalCode` | `00000` |
| `venueCountry` | `US` |
| `venueLatitude` / `venueLongitude` | `40.7000` / `-73.9000` |
| `venueCapacity` | `20000` |
| `metroAreaName` | `Sample City, ST, US` |
| `locationText` | `Sample Arena, Sample City, ST, US` |
| `ticketAvailability` | `in_stock` |
| `ticketVendors` | `[{"vendor": "Sample Ticket Vendor", "saleStatus": "on_sale_now"}]` |
| `ticketUrl` | `https://www.songkick.com/tickets/00000000` |
| `tourName` | `Sample Tour` |
| `doorsTime` | `18:30` |
| `changeType` | `NEW`, `UPDATED`, `REAPPEARED`, `EXPIRED` |

### How to Use

Search for upcoming events by keyword:

```json
{
  "mode": "search",
  "query": "the killers",
  "searchType": "events",
  "maxItems": 50
}
```

Resolve a keyword to an artist and read its tour dates:

```json
{
  "mode": "search",
  "query": "beyonce",
  "searchType": "artists",
  "maxItems": 50
}
```

Paste Songkick links, mixed types supported (links shown are illustrative placeholders):

```json
{
  "mode": "url",
  "urls": [
    "https://www.songkick.com/metro-areas/00000-sample-region",
    "https://www.songkick.com/artists/00000000-sample-artist/gigography",
    "https://www.songkick.com/concerts/00000000-sample-artist-at-sample-arena"
  ],
  "maxItems": 200
}
```

Monitor a search daily for changes only:

```json
{
  "mode": "search",
  "query": "the killers",
  "searchType": "events",
  "incrementalMode": true,
  "maxItems": 500
}
```

### Input Parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| `mode` | string | `search` | `search` finds concerts and events by keyword. `url` reads specific Songkick pages you paste. |
| `query` | string | `the killers` | Search mode: a keyword such as an artist, venue or city name. |
| `searchType` | string | `events` | Search mode: `events`, `past_events`, `artists`, `venues` or `cities`. Events and Past events return matching upcoming or past concerts and festivals; the others resolve the keyword to the top entity and return its calendar. |
| `urls` | array of strings | empty | URL mode: Songkick pages, one per line. Artist, venue, metro-area, festival, gigography, venue calendar and search links are all accepted; a single concert or festival date link is read as one record. |
| `fetchDetails` | boolean | `true` | Read each event's own page to add ticket availability, ticket vendors and link, tour name, doors time and venue capacity. Adds a per-event surcharge. |
| `maxItems` | integer | `20` | Stop after this many events. `0` means no limit. |
| `maxPages` | integer | `100` | Upper bound on pages read per artist, venue, location or search. Defaults wide open so `maxItems` is the only cap that stops a run early. |
| `resumeFromRunId` | string | empty | A previous run or dataset ID to continue without returning events already collected there. |
| `incrementalMode` | boolean | `false` | Recurring monitoring: the first run marks every event NEW; later runs emit only NEW, UPDATED and REAPPEARED events, plus EXPIRED when enabled. |
| `stateKey` | string | empty | Optional name for a monitoring campaign so its state stays stable, or to deliberately share state across runs. |
| `emitUnchanged` | boolean | `false` | Also return events that have not changed since the last run, marked UNCHANGED. Returns and bills extra rows. |
| `emitExpired` | boolean | `false` | Also return events tracked before but no longer found, marked EXPIRED. Only produced after a run fully scans the tracked search. |
| `mcpConnectors` | array of strings | empty | Optional MCP connectors to receive the results (see the section below). |
| `notionParentPageUrl` | string | empty | Parent Notion page for the Notion connector export. |
| `maxNotifyListings` | integer | `50` | Cap on items written to each connector per run. Does not affect the dataset. |
| `proxyConfiguration` | object | standard | Apify Proxy settings. The default works on every Apify plan. |

### Output Example

> Sample shape, values are illustrative placeholders, not from a live listing.

```json
{
  "kind": "event",
  "recordId": "00000000",
  "eventId": "00000000",
  "url": "https://www.songkick.com/concerts/00000000-sample-artist-at-sample-arena",
  "title": "Sample Artist at Sample Arena",
  "startDate": "2027-01-15T19:30:00",
  "endDate": "2027-01-15",
  "eventStatus": "scheduled",
  "eventType": "concert",
  "headliner": "Sample Artist",
  "performers": [
    {
      "name": "Sample Artist",
      "url": "https://www.songkick.com/artists/00000000-sample-artist",
      "genres": ["indie", "rock"]
    }
  ],
  "artistName": "Sample Artist",
  "artistUrl": "https://www.songkick.com/artists/00000000-sample-artist",
  "artistGenres": ["indie", "rock"],
  "venueName": "Sample Arena",
  "venueStreet": "1 Sample Road",
  "venueCity": "Sample City",
  "venueRegion": "ST",
  "venuePostalCode": "00000",
  "venueCountry": "US",
  "venueLatitude": 40.7,
  "venueLongitude": -73.9,
  "venueCapacity": 20000,
  "metroAreaName": "Sample City, ST, US",
  "locationText": "Sample Arena, Sample City, ST, US",
  "description": "Sample Artist at Sample Arena at 2027-01-15T19:30:00",
  "imageUrl": "https://images.sk-static.com/images/media/profile_images/artists/00000000/huge_avatar",
  "ticketAvailability": "in_stock",
  "ticketVendors": [
    {
      "vendor": "Sample Ticket Vendor",
      "saleStatus": "on_sale_now"
    }
  ],
  "ticketUrl": "https://www.songkick.com/tickets/00000000",
  "tourName": "Sample Tour",
  "doorsTime": "18:30"
}
```

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

You can optionally pipe results into apps you already use via Model Context Protocol (MCP) connectors. Authorize a connector under Apify, Settings, API & Integrations, then select it in the `mcpConnectors` input field. For Notion, set `notionParentPageUrl` to the page under which item pages are created; the Notion export writes a page per event with a readable summary. Other connectors get a best-effort write or digest.

Each connector receives a condensed, human-readable summary per event (title plus the key fields flattened to plain text), not the full record. The complete event record always stays in the Apify dataset. Leave `mcpConnectors` empty to skip the export entirely; the dataset output is never changed by the connector surface.

Requires an Apify account. The default settings work on every plan.

# Actor input Schema

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

Search looks up concerts and events by keyword. URL mode reads specific Songkick pages you paste.

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

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

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

Search mode: what the keyword should find. Events and Past events return matching upcoming or past concerts and festivals. Artists, Venues and Locations return the top matching entity's upcoming calendar.

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

URL mode: Songkick pages to read, one per line. Artist, venue, metro-area, festival, gigography, venue calendar and search links are walked forward; a single concert or festival date link is read as one record. Multi-value supported.

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

Read each event's own page to add ticket availability, ticket vendors and link, tour name, doors time and venue capacity. Adds a per-event surcharge (see the section caption below).

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

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

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

Upper bound on how many pages each artist, venue, location or search is walked through. 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 events already collected there.

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

Turn this on for daily or recurring monitoring. The first run returns every matching event as NEW. Later runs normally return only NEW, UPDATED and REAPPEARED events. Turn on Emit unchanged or Emit expired only when you also want those rows returned (and billed). State is kept separately for each search and link 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 and link settings.

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

Off by default. Turn on to also return events 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 events that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked search.

## `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": "events",
  "urls": [
    "https://www.songkick.com/metro-areas/4120-us-atlanta"
  ],
  "fetchDetails": true,
  "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": "events",
    "urls": [
        "https://www.songkick.com/metro-areas/4120-us-atlanta"
    ],
    "fetchDetails": true,
    "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/songkick-concert-calendar-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": "events",
    "urls": ["https://www.songkick.com/metro-areas/4120-us-atlanta"],
    "fetchDetails": True,
    "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/songkick-concert-calendar-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": "events",
  "urls": [
    "https://www.songkick.com/metro-areas/4120-us-atlanta"
  ],
  "fetchDetails": true,
  "maxItems": 20,
  "maxPages": 0,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "maxNotifyListings": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call abotapi/songkick-concert-calendar-scraper --silent --output-dataset

```

## MCP server setup

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