# Spotify Scraper — Tracks, Artists, Playlists, Charts (`eduair94/spotify-scraper`) Actor

Fast, cheap, full-coverage Spotify scraper. 50+ data categories including tracks, artists, albums, playlists, concerts, charts (Top 200 / Viral), lyrics, credits, recommendations, AI insights. Pay-per-event — no monthly fee.

- **URL**: https://apify.com/eduair94/spotify-scraper.md
- **Developed by:** [Eduardo Airaudo](https://apify.com/eduair94) (community)
- **Categories:** Social media, SEO tools, Videos
- **Stats:** 66 total users, 14 monthly users, 88.4% runs succeeded, 1 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $0.12 / 1,000 scraped items

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

## Spotify Scraper — Full Coverage, Pay-Per-Event

Extract **any** public Spotify data: tracks, artists, albums, playlists, users, podcasts, concerts, charts, lyrics, credits, recommendations, AI insights and more. **40+ categories**, accepts Spotify IDs, URLs or search keywords.

Built to undercut `canadesk/spotify` ($10/mo + usage) and `canadesk/spotify-plus` ($16/mo + usage):

- **$0 monthly rental fee**
- **$0.20 per 1,000 result items** (pay-per-event)
- **$0.30 per 1,000 single-entity fetches** (bulk-fetch)
- Raw data optional — slim output by default

### Features vs. canadesk/spotify

| Feature                              | canadesk | canadesk-plus | **This actor** |
| ------------------------------------ | -------- | ------------- | -------------- |
| Monthly rental                       | $10      | $16           | **$0**         |
| Tracks / Artists / Albums            | ✅       | ✅            | ✅             |
| Playlists / Users / Podcasts         | ✅       | ✅            | ✅             |
| Lyrics (word-synced + translations)  | ✅       | ✅            | ✅             |
| Track credits (producers, writers)   | ❌       | ❌            | ✅             |
| Artist — appears on / featuring      | ❌       | ❌            | ✅             |
| Artist — discovered on (playlists)   | ❌       | ❌            | ✅             |
| Artist — related / discography rich  | ❌       | partial       | ✅             |
| Concert feed + concert locations     | partial  | partial       | ✅             |
| Spotify Charts — Top 200 / Viral     | ❌       | ❌            | ✅             |
| Top 20 by monthly listeners/followers| ❌       | ❌            | ✅             |
| Recommendations (seed → playlist)    | ❌       | ❌            | ✅             |
| Search suggestions (autocomplete)    | ❌       | ❌            | ✅             |
| Lyrics search                        | ❌       | ❌            | ✅             |
| Partner-API rich payloads            | ❌       | ❌            | ✅             |
| Cross-platform enrichment            | ❌       | ❌            | ✅             |
| No 50-result cap                     | ❌       | ✅            | ✅             |
| No simultaneous-entry cap            | ❌       | ✅            | ✅             |

### Input

All input fields are documented in the input form.

| Field                | Type    | Purpose                                                              |
| -------------------- | ------- | -------------------------------------------------------------------- |
| `mode`               | string  | `get` / `search` / `chart`                                           |
| `category`           | string  | 42 categories (see below)                                            |
| `queries`            | array   | IDs, URLs, `spotify:*:*` URIs or search keywords                     |
| `maxResultsPerQuery` | int     | 1 – 1000 (default 50)                                                |
| `market`             | string  | ISO country (default `US`)                                           |
| `lyricsLanguage`     | string  | ISO lang for lyric translations                                      |
| `chartDate`          | string  | `YYYY-MM-DD` for historical charts                                   |
| `concurrency`        | int     | Parallel requests (1 – 20)                                           |
| `delayMs`            | int     | Pause between requests                                               |
| `includeRaw`         | bool    | Attach raw upstream JSON                                             |
| `enrichWithContrast` | string  | `ytmusic`, `applemusic`, `amazonmusic`, `pandora`, `gaana`, `tencent`|

#### Categories

**Single entities (`mode=get`):**
`track`, `track_credits`, `track_lyrics`, `album`, `album_tracks`, `album_metadata`, `artist`, `artist_overview`, `artist_albums`, `artist_singles`, `artist_appears_on`, `artist_discovered_on`, `artist_featuring`, `artist_related`, `artist_discography_overview`, `artist_concerts`, `artist_concert_locations`, `playlist`, `playlist_tracks`, `user_profile`, `user_followers`, `recommendations`, `partner_playlist`, `partner_track`, `partner_album`, `partner_artist_overview`, `partner_artist_discography`.

**Search (`mode=search`):**
`search_multi`, `search_tracks`, `search_artists`, `search_albums`, `search_playlists`, `search_users`, `search_podcasts`, `search_top_results`, `search_suggestions`, `search_lyrics`.

**Charts (`mode=chart`):**
`chart_top_200_tracks`, `chart_viral_tracks`, `chart_top_artists`, `chart_top_albums`, `chart_top_monthly_listeners`, `chart_top_followers`.

### Example inputs

#### Get artist overview from URL

```json
{
    "mode": "get",
    "category": "artist_overview",
    "queries": [
        "https://open.spotify.com/artist/06HL4z0CvFAxyc27GXpf02"
    ]
}
```

#### Search tracks

```json
{
    "mode": "search",
    "category": "search_tracks",
    "queries": [
        "bohemian rhapsody",
        "taylor swift anti-hero"
    ],
    "maxResultsPerQuery": 20,
    "market": "US"
}
```

#### Top 200 tracks — Mexico

```json
{
    "mode": "chart",
    "category": "chart_top_200_tracks",
    "queries": [
        "MX"
    ],
    "chartDate": "2026-04-22"
}
```

#### Word-synced lyrics with Spanish translation

```json
{
    "mode": "get",
    "category": "track_lyrics",
    "queries": [
        "4iV5W9uYEdYUVa79Axb7Rh"
    ],
    "lyricsLanguage": "es"
}
```

#### Get song credits (writers, producers, performers)

No API key is required when you run this Actor on Apify. Select `get`, choose
`track_credits`, and paste a Spotify track ID, URL, or URI:

```json
{
    "mode": "get",
    "category": "track_credits",
    "queries": [
        "4iV5W9uYEdYUVa79Axb7Rh"
    ]
}
```

### Output

Each item is a flat JSON object with:

- `category` — what was scraped
- `mode` — get / search / chart
- `query` — original input
- `id`, `type`, `name`, `uri`, `url` — normalized entity fields
- plus every field returned by the upstream API
- optional `raw` — full upstream JSON (`includeRaw=true`)
- optional `contrast` — cross-platform data (`enrichWithContrast`)

Only successful results are pushed to the default dataset and charged. Failed
queries are written to the `ERRORS` record in the run's key-value store with
`charged: false`, and are summarized in `RUN_SUMMARY.failedQueries`.

If every query fails, the Actor run finishes with `FAILED` status so automated
retry policies can detect it. Partial runs keep their successful dataset rows
and list the uncharged failures in `ERRORS`.

### Pricing (pay-per-event)

| Event        | Price      | When charged                              |
| ------------ | ---------- | ----------------------------------------- |
| `result-item`| $0.0002    | Per successful dataset item (≈ $0.20 per 1k rows) |
| `bulk-fetch` | $0.0003    | Reserved for single-entity fetches        |

There is no run-start fee and no automatic `apify-default-dataset-item`
event. Empty responses, invalid inputs, upstream errors, and failed runs cost
the customer **$0.00**.

**Example:** a run that pushes 10,000 track rows costs **$2.00** total. The same run on canadesk/spotify-plus would cost **$16/mo rental** + their per-result fees.

### No API key required on Apify

Click **Try for free**, choose a category, add your Spotify IDs or URLs, and
start the run. Billing is handled by Apify's pay-per-event system. The Actor's
upstream credential is configured privately by the publisher and is never an
input that customers need to provide.

Apify PPE buys Actor runs and dataset results; it does **not** issue a reusable
REST API key. If you need an API key for requests from your own application,
use RapidAPI or the Direct Portal below.

### Using the API outside Apify

If you see `upstream 401 on ... {"error":"Invalid API key"}` in the actor
log, or you're trying to hit `spotify-proxy.checkleaked.cc` yourself outside
an Apify run: that's expected. The upstream is private and only
authorized for requests coming through this actor's Apify runtime.

To call the Spotify data API directly (no Apify wrapper, your own integration,
your own rate limits), purchase a key from the
**[Direct API Key Portal](https://spotify-sub.checkleaked.com)**. Direct keys
are delivered there after checkout and authenticate requests made outside
Apify.

### Local development

```bash
npm install
npm run build
apify run
```

Edit `storage/key_value_stores/default/INPUT.json` to change input between runs.

### License

MIT

# Actor input Schema

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

What to do with each input. 'get' — fetch a known Spotify entity by ID/URL. 'search' — search Spotify with keywords. 'chart' — fetch a chart (no input needed).

## `category` (type: `string`):

Which data to extract. The category must match your 'mode'. 'get' supports all entity categories. 'search' supports search\_\* categories. 'chart' supports chart\_\* categories.

⚠️ Concert categories — pick the right one:
• 'search\_concert\_locations' = look up CITIES/PLACES (queries are place names like 'London', 'Buenos Aires'). Returns geoHash/geonameId.
• 'search\_concert\_artists' = look up upcoming concerts BY ARTIST NAME (queries are artist names like 'The Fratellis', 'Flook'). Returns concert/tour dates.
• 'artist\_concerts' = same as above but you already have the Spotify artist ID/URL.
• 'concerts\_by\_location' = list every concert at a specific geonameId.

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

One input per line. For mode=get: Spotify ID, URI, or open.spotify.com URL. To pull song credits, select mode=get and category=track\_credits, then add track IDs or URLs here. For mode=search: keywords. For mode=chart: leave empty.

## `maxResultsPerQuery` (type: `integer`):

For search/pagination categories. Ignored for single-entity 'get' calls.

## `market` (type: `string`):

Country code for regional results (tracks, charts, concerts). Leave empty for global.

## `lyricsLanguage` (type: `string`):

ISO 639-1 language code for lyrics translation. Leave empty for original.

## `chartDate` (type: `string`):

For chart\_\* categories. Leave empty for latest.

## `geoHash` (type: `string`):

Optional location filter for 'artist\_concerts'. Spotify geohash (e.g. '6cb19y38v7py' for London). Leave empty for global tour data.

## `enrichConcertDetails` (type: `boolean`):

When on: every concert is enriched in parallel with venue name, address (city / region / country / coordinates), lineup, ticket providers, and related concerts. Required for venue + address on 'artist\_concerts' / 'search\_concert\_artists' (the persisted Spotify query only returns city). Adds 1 extra request per concert (capped by 'concertDetailsLimit'). Default: ON for artist concert categories, OFF elsewhere.

## `concertDetailsLimit` (type: `integer`):

Cap on how many concerts get enriched when 'enrichConcertDetails' is on. Avoids rate limits.

## `parsedConcerts` (type: `boolean`):

Return concert data in a normalized flat shape (artists, offers, location, related concerts) instead of raw GraphQL response. Affects 'partner\_concert', 'artist\_concerts', 'search\_concert\_artists', and enriched details.

## `concurrency` (type: `integer`):

Number of queries to process in parallel. Higher = faster but more load.

## `delayMs` (type: `integer`):

Pause between requests. Use 0 for max speed.

## `includeRaw` (type: `boolean`):

Attach the full raw JSON from Spotify under a 'raw' field. Off by default for slimmer output.

## `enrichWithContrast` (type: `string`):

Attach equivalent data from another streaming platform. Optional.

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

Optional — upstream API already rotates proxies. Leave default unless debugging.

## Actor input object example

```json
{
  "mode": "get",
  "category": "track",
  "queries": [
    "4iV5W9uYEdYUVa79Axb7Rh",
    "https://open.spotify.com/artist/06HL4z0CvFAxyc27GXpf02"
  ],
  "maxResultsPerQuery": 50,
  "market": "US",
  "enrichConcertDetails": true,
  "concertDetailsLimit": 20,
  "parsedConcerts": false,
  "concurrency": 5,
  "delayMs": 0,
  "includeRaw": false,
  "enrichWithContrast": "",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

All normalized Spotify entities pushed during this run. One row per entity with consistent top-level fields (id, name, type, url, imageUrl, followers, …) and the full upstream payload under `data`.

## `resultsCsv` (type: `string`):

Same dataset, flattened to CSV — useful for spreadsheets.

## `liveView` (type: `string`):

Browse the dataset in the Apify console with the Overview / Artists / Tracks / Albums / Playlists / Charts views.

# 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": [
        "4iV5W9uYEdYUVa79Axb7Rh",
        "https://open.spotify.com/artist/06HL4z0CvFAxyc27GXpf02"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("eduair94/spotify-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 = { "queries": [
        "4iV5W9uYEdYUVa79Axb7Rh",
        "https://open.spotify.com/artist/06HL4z0CvFAxyc27GXpf02",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("eduair94/spotify-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 '{
  "queries": [
    "4iV5W9uYEdYUVa79Axb7Rh",
    "https://open.spotify.com/artist/06HL4z0CvFAxyc27GXpf02"
  ]
}' |
apify call eduair94/spotify-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,eduair94/spotify-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/iSBI7FkiTKmEtgImW/builds/1qOxpPSoDea1lJatK/openapi.json
