# Spotify Scraper: Artists, Tracks, Playlists, Podcasts (`epicscrapers/spotify-scraper`) Actor

Scrape Spotify artists, tracks, albums, playlists, podcasts and curator profiles by link, search or ISRC. Play counts, monthly listeners, followers, ISRC, UPC, credits, playlist followers, podcast ratings. $4 per 1,000 results.

- **URL**: https://apify.com/epicscrapers/spotify-scraper.md
- **Developed by:** [Epic Scrapers](https://apify.com/epicscrapers) (community)
- **Categories:** Social media, Automation, Developer tools
- **Stats:** 4 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Spotify Scraper: artists, tracks, playlists, podcasts and curators

Scrape **any Spotify page or search** to JSON, CSV or Excel: artists with **monthly listeners, followers, world rank and top cities**, tracks with **exact play counts, ISRC, label and songwriter/producer credits**, albums with **UPC**, playlists with **followers, owner and curator contacts**, podcasts with **ratings and episodes**, and user profiles.

- 🔗 **Any input**: Spotify links of every type, `spotify:` URIs, bare IDs, short links, **ISRCs and UPCs**, or search terms.
- 🔎 **Search everything**: tracks, artists, albums, playlists, podcasts, episodes and user profiles. Asks for more than Spotify's ~200 results per query by adding related queries.
- 🎯 **Playlist curator finder**: filter playlists by followers, skip Spotify's own, and get the owner's followers, emails, Instagram handles and links from the description, plus the date a track was last added.
- 📈 **Track growth**: schedule it daily with **Compare with previous run** to get the change in play counts, monthly listeners, followers and playlist followers.
- 💸 **$2 per 1,000 results**, no start fee. Playlists and albums include up to 100 tracks per result. Not-found links and filtered-out playlists are free.
- 🔑 No login, no Spotify API key, no browser.

### What you can scrape

| Input                 | One row with                                                                                                                                                                                                                |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Artist**            | monthly listeners, followers, world rank, popularity, top 5 cities, verified, biography, 10 top tracks with play counts, latest release, album/single counts, related artists, artist playlists. Optional: full discography |
| **Track** or **ISRC** | exact play count, popularity, ISRC, album, release date, label, track and disc number, language, explicit, songwriters, producers and full credits                                                                          |
| **Album** or **UPC**  | UPC, label, release date, copyrights, popularity, every track with play count, ISRC and popularity                                                                                                                          |
| **Playlist**          | followers, track count, owner and owner's followers, last track added, contacts in the description, every track with play count, ISRC and date added                                                                        |
| **Podcast (show)**    | publisher, average rating and number of ratings, topics, episode count, latest episodes                                                                                                                                     |
| **Episode**           | show, release date, duration, video or audio, description, audio preview                                                                                                                                                    |
| **User profile**      | followers, public playlists and their followers                                                                                                                                                                             |

### Who uses it

- **Playlist pitching and music marketing:** search playlists by genre or mood, keep the ones between 1,000 and 100,000 followers that Spotify doesn't own, and get the curator's followers, email, Instagram, other @handles and how recently they added a track.
- **Labels, A\&R and managers:** schedule artist links daily for monthly listeners, followers, world rank, top cities and play counts, with the change since the last run.
- **Catalog, royalty and rights teams:** paste ISRCs or UPCs and get the Spotify track or album with play counts, label and songwriter/producer credits.
- **Podcast advertisers and agencies:** search podcasts by topic and rank them by rating count and how recently they publish.
- **Developers and AI agents:** one Actor and one flat schema for every Spotify object, through the Apify API or MCP.

### How to use it

1. Paste Spotify links, ISRCs or UPCs into **Spotify links, IDs, ISRCs or UPCs**, or type keywords into **Search terms** and pick what to search for.
2. Click **Start**. Each link gives one row; each search term gives up to **Max results per search term** rows.
3. Download the results as JSON, CSV or Excel, or use the views: **Artists**, **Tracks**, **Playlists**, **Podcasts**.

#### Input examples

Artists, a playlist and a track by ISRC:

```json
{
    "startUrls": [
        "https://open.spotify.com/artist/3TVXtAsR1Inumwj472S9r4",
        "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M",
        "USUG11904206"
    ]
}
```

Find independent lofi playlists with 1,000 to 100,000 followers (curator outreach):

```json
{
    "searchTerms": ["lofi study", "chillhop"],
    "searchType": "playlists",
    "maxResultsPerSearch": 300,
    "minFollowers": 1000,
    "maxFollowers": 100000,
    "excludeSpotifyPlaylists": true,
    "maxItemsPerResult": 0
}
```

Daily artist tracking (run it on a schedule):

```json
{
    "startUrls": ["https://open.spotify.com/artist/3TVXtAsR1Inumwj472S9r4"],
    "compareWithPreviousRun": true
}
```

A quick list of 500 track search results without opening each one:

```json
{ "searchTerms": ["jazz"], "searchType": "tracks", "maxResultsPerSearch": 500, "scrapeDetails": false }
```

### Output examples

Real rows from 2026-10-08, shortened.

#### Artist

```json
{
    "type": "artist",
    "id": "3TVXtAsR1Inumwj472S9r4",
    "name": "Drake",
    "url": "https://open.spotify.com/artist/3TVXtAsR1Inumwj472S9r4",
    "verified": true,
    "monthlyListeners": 94687381,
    "followers": 117837479,
    "worldRank": 8,
    "popularity": 100,
    "topCities": [{ "city": "London", "region": "ENG", "country": "GB", "listeners": 2018639 }],
    "albumCount": 22,
    "singleCount": 65,
    "appearsOnCount": 911,
    "latestRelease": {
        "name": "HABIBTI (FOMO)",
        "type": "album",
        "releaseDate": "2026-10-02",
        "label": "OVO/Republic",
        "trackCount": 15
    },
    "topTracks": [{ "position": 1, "name": "One Dance", "playCount": 4504086419, "artistName": "Drake, Wizkid, Kyla" }],
    "relatedArtists": [{ "id": "1RyvyyTE3xzB2ZywiAwp0i", "name": "Future" }],
    "scrapedAt": "2026-10-08T14:12:43.285Z"
}
```

#### Track (from the ISRC `USUG11904206`)

```json
{
    "type": "track",
    "name": "Blinding Lights",
    "url": "https://open.spotify.com/track/0VjIjW4GlUZAMYd2vXMi3b",
    "playCount": 5623655578,
    "popularity": 91,
    "isrc": "USUG11904206",
    "artistName": "The Weeknd",
    "albumName": "After Hours",
    "albumType": "album",
    "releaseDate": "2020-03-20",
    "label": "Republic Records",
    "trackNumber": 9,
    "discNumber": 1,
    "languages": ["en"],
    "songwriters": "Max Martin, Oscar Holter, Abel Tesfaye, Ahmad Balshe, Jason \"DaHeala\" Quenneville",
    "producers": "Max Martin, Oscar Holter, The Weeknd",
    "credits": [{ "name": "Max Martin", "role": "Composer", "group": "Composition & Lyrics" }],
    "input": "USUG11904206"
}
```

#### Playlist (search result)

```json
{
    "type": "playlist",
    "name": "Lofi Study 2026",
    "url": "https://open.spotify.com/playlist/6zCID88oNjNv9zx6puDHKj",
    "followers": 624612,
    "trackCount": 237,
    "ownerName": "Lofi Girl",
    "ownerUrl": "https://open.spotify.com/user/chilledcow",
    "ownerFollowers": 1871428,
    "ownerPlaylistCount": 82,
    "isSpotifyOwned": false,
    "lastTrackAddedAt": "2026-09-29T11:52:01Z",
    "contacts": { "emails": [], "instagram": [], "handles": [], "links": ["https://bit.ly/lofi-sleep-spotify"] },
    "tracks": [
        {
            "position": 1,
            "name": "94",
            "artistName": "Mavine",
            "playCount": 3262855,
            "isrc": "GBKQU2184377",
            "popularity": 50,
            "addedAt": "2026-09-29T11:52:01Z"
        }
    ],
    "searchTerm": "lofi study",
    "searchRank": 2
}
```

#### Podcast

```json
{
    "type": "show",
    "name": "Lex Fridman Podcast",
    "publisher": "Lex Fridman",
    "rating": 4.75,
    "ratingCount": 83182,
    "topics": ["Technology"],
    "episodeCount": 503,
    "latestEpisodeDate": "2026-09-17",
    "episodes": [
        {
            "position": 1,
            "name": "#502 – Psychiatry, Insane Asylums, Mental Illness, ECT, Lobotomies, Freud & Jung",
            "releaseDate": "2026-09-17",
            "durationMs": 13409643,
            "video": true
        }
    ]
}
```

With **Compare with previous run**, rows also get `previous…` and `…Change` fields, e.g. `previousMonthlyListeners`, `monthlyListenersChange`, `playCountChange`, `followersChange`, and `previousScrapedAt`.

### How much does it cost?

**$2 per 1,000 results** (pay per event), with platform usage and proxies included and no start fee.

- A result is one row: an artist, track, album, playlist, podcast, episode or user profile, with all its data.
- Albums, playlists and podcasts include up to 100 tracks or episodes per result. A 250-track playlist with all tracks listed counts as 3 results.
- Links that aren't found, and search results removed by the playlist filters, are free.

| Example                                            | Results   | Cost        |
| -------------------------------------------------- | --------- | ----------- |
| 100 artists, daily                                 | 100 a day | $0.20 a day |
| 1,000 ISRCs                                        | 1,000     | $2.00       |
| 300 playlists for one keyword, without track lists | 300       | $0.60       |
| One 1,000-track playlist with every track          | 10        | $0.02       |

Set **Maximum cost per run** in the run options to cap a run; it stops cleanly at the limit.

### Spotify Scraper vs. the official Spotify Web API

|                                           | Spotify Web API | This Actor     |
| ----------------------------------------- | --------------- | -------------- |
| App registration and OAuth                | Required        | Not needed     |
| Exact play counts                         | ❌              | ✅ every track |
| Monthly listeners, world rank, top cities | ❌              | ✅             |
| Songwriter and producer credits           | ❌              | ✅             |
| Playlist owner followers and contacts     | ❌              | ✅             |
| Podcast ratings                           | ❌              | ✅             |
| ISRC and UPC lookup                       | ✅              | ✅             |

### Tips

- **Short on time?** Turn off **Open every search result** for a fast list of names and links, then scrape the ones you need.
- **Only need playlist metadata?** Set **Max tracks or episodes per result** to 0.
- **Many links?** Put them all in one run: up to 10 are read at once.
- **Not-found links** are listed in the log and in the run's `OUTPUT` record (Storage → Key-value store) with the reason.
- Want **one row per track** with play counts for whole discographies? Use [Spotify Play Count Scraper](https://apify.com/epicscrapers/spotify-play-count-scraper).

### Limitations

- Lyrics, audio features (tempo, key, danceability) and genres aren't public without a Spotify login, so they aren't included.
- Spotify returns about 200 results per search query. For more, the Actor adds related queries (e.g. "lofi playlist", "best lofi", "lofi 2026"), so later results can drift from the exact keyword.
- `lastTrackAddedAt` and `firstTrackAddedAt` come from the listed tracks and the playlist's last 100 tracks.
- Search results depend on the country of the proxy IP, like on Spotify.

### FAQ

**Is it legal to scrape Spotify?** The Actor reads only public data that Spotify shows to every visitor without logging in. Personal data (names, emails in playlist descriptions) is subject to GDPR and similar laws; only use it with a legitimate reason.

**How fresh is the data?** Every run reads Spotify live, so you get the numbers Spotify shows at that moment.

**Can I use it from code or an AI agent?** Yes, through the [Apify API](https://docs.apify.com/api/v2), the JavaScript and Python clients, or the Apify MCP server.

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("epicscrapers/spotify-scraper").call(run_input={
    "startUrls": ["https://open.spotify.com/artist/3TVXtAsR1Inumwj472S9r4", "USUG11904206"],
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["type"], item["name"], item.get("playCount") or item.get("monthlyListeners"))
```

**Something is missing or broken?** Open an issue on the Actor's Issues tab.

# Actor input Schema

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

One per line: artist, album, track, playlist, podcast (show), episode or user profile URLs (e.g. https://open.spotify.com/artist/3TVXtAsR1Inumwj472S9r4), spotify: URIs, bare IDs, ISRCs (e.g. USUG11904206) or album UPCs. Each link gives one row with all its data.

## `searchTerms` (type: `array`):

Keywords to search Spotify for, one per line (e.g. lofi study, drake). Each term gives up to "Max results per search term" rows of the type below.

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

What the search terms look for.

## `maxResultsPerSearch` (type: `integer`):

Stop after this many rows per search term. Spotify returns about 200 results per query; above that the Actor adds related queries ("lofi playlist", "best lofi", "lofi 2026"…) to find more.

## `scrapeDetails` (type: `boolean`):

Open each search result for its full data: play counts, monthly listeners, playlist followers, podcast ratings. Turn off for quick lists (name, link, artist, owner) without these numbers.

## `maxItemsPerResult` (type: `integer`):

How many tracks to list in each album and playlist row, episodes in each podcast row and playlists in each user row (newest episodes first). 0 lists none. Rows with more than 100 tracks or episodes count one result per 100.

## `includeIsrc` (type: `boolean`):

Add ISRC and popularity (0–100) to tracks, including tracks listed in albums and playlists, UPC to albums, and popularity to artists.

## `includeCredits` (type: `boolean`):

Add songwriters, producers, engineers and performers to track rows.

## `includeDiscography` (type: `boolean`):

Add every album, single and compilation of the artist (name, date, label, link). Without it, artist rows have the 10 top tracks, latest release and release counts.

## `compareWithPreviousRun` (type: `boolean`):

Remember the numbers between runs and add the previous value and the change: play counts, monthly listeners, followers, world rank, playlist followers, podcast ratings. Use it in a schedule (e.g. daily) to track growth.

## `minFollowers` (type: `integer`):

For playlist searches: skip playlists with fewer followers. Skipped playlists are free.

## `maxFollowers` (type: `integer`):

For playlist searches: skip playlists with more followers. 0 means no maximum.

## `excludeSpotifyPlaylists` (type: `boolean`):

For playlist searches: skip editorial and algorithmic playlists made by Spotify, which don't take submissions.

## Actor input object example

```json
{
  "startUrls": [
    "https://open.spotify.com/artist/3TVXtAsR1Inumwj472S9r4",
    "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M"
  ],
  "searchType": "tracks",
  "maxResultsPerSearch": 50,
  "scrapeDetails": true,
  "maxItemsPerResult": 100,
  "includeIsrc": true,
  "includeCredits": true,
  "includeDiscography": false,
  "compareWithPreviousRun": false,
  "minFollowers": 0,
  "maxFollowers": 0,
  "excludeSpotifyPlaylists": false
}
```

# Actor output Schema

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

No description

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

No description

## `summary` (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 = {
    "startUrls": [
        "https://open.spotify.com/artist/3TVXtAsR1Inumwj472S9r4",
        "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("epicscrapers/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 = { "startUrls": [
        "https://open.spotify.com/artist/3TVXtAsR1Inumwj472S9r4",
        "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("epicscrapers/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 '{
  "startUrls": [
    "https://open.spotify.com/artist/3TVXtAsR1Inumwj472S9r4",
    "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M"
  ]
}' |
apify call epicscrapers/spotify-scraper --silent --output-dataset

```

## MCP server setup

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