# Spotify Play Count & Insights Scraper (`brilliant_gum/spotify-insights-scraper`) Actor

Exact stream counts, monthly listeners, world rank, full discography PLUS historical trend tracking, related artists, playlists, contact info (emails/socials), revenue estimates, lyrics and podcasts. Drop-in superset of beatanalytics/spotify-play-count-scraper.

- **URL**: https://apify.com/brilliant\_gum/spotify-insights-scraper.md
- **Developed by:** [Yuliia Kulakova](https://apify.com/brilliant_gum) (community)
- **Categories:** Developer tools, Social media, Lead generation
- **Stats:** 13 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 entity scrapeds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#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 Play Count & Insights Scraper

Exact **stream counts**, **monthly listeners**, **world rank** and the **full discography graph** straight from Spotify — the data the official Web API hides — **plus** historical trend tracking, related artists, playlists, lead-gen contact info, lyrics and podcasts.

A **drop-in superset** of `beatanalytics/spotify-play-count-scraper`: the same inputs work unchanged, and it returns the same fields and many more.

![banner](https://i.imgur.com/hVgRiFG.png)

***

### What you get

| | |
|---|---|
| **Exact play counts** | Per-track stream counts that the Spotify Web API doesn't expose. |
| **Audience signals** | Monthly listeners, followers, world rank, top cities (with listener counts per city). |
| **Full discography** | Albums, singles, popular releases, "Appears On", "Featuring" — with per-track streams. |
| **Related artists graph** | "Fans also like" with optional enrichment (monthly listeners + followers per related artist) and graph-crawl depth. |
| **Playlist attribution** | "Discovered On" — which editorial/user playlists are driving the streams. |
| **Historical trends** | Persisted snapshots + automatic deltas + stream velocity per day across scheduled runs. |
| **Lead-gen contact info** | Emails (from bio) + categorised social links + website. |
| **Revenue estimates** | Per-artist royalty range from the industry-standard $0.003–0.005 per-stream payout band. |
| **Lyrics** | Time-synced lyrics per track (requires your `sp_dc` cookie — see FAQ). |
| **Podcasts** | Show metadata + paginated episode list (name, duration, release date). |
| **Full playlist contents** | Owner, follower count, paginated track list with `addedAt` timestamps. |
| **Original-actor compatibility** | Optional flat `play_counts.csv` export matching `beatanalytics/spotify-play-count-scraper`. |

Works without configuration — proxies are included, auth is self-healing, and the actor is resilient to Spotify's periodic web-player rotations.

***

### Use cases

- **Music marketer / A\&R** — scout rising artists by city, by monthly-listener velocity, by playlist co-occurrence.
- **Independent label / Manager** — pull contact info and audience size for outreach targeting.
- **Music journalist / Analyst** — cite exact stream counts with provenance.
- **Royalty analyst** — estimate revenue from streams using transparent payout assumptions.
- **Playlist curator** — see which playlists already feature an artist.
- **Data engineer** — schedule the actor and feed a clean time-series into your warehouse.
- **Podcast aggregator** — pull show metadata + full episode catalogue.

***

### Quick start

Paste a Spotify URL — that's the whole minimum input:

```json
{
  "urls": ["https://open.spotify.com/artist/06HL4z0CvFAxyc27GXpf02"]
}
```

You get an artist record with monthly listeners, followers, world rank, top 10 tracks (with stream counts), top 5 cities, full discography lists, biography, external links, contact info, and analytics — all in one record.

***

### Common inputs

**Crawl all albums of an artist (full per-track streams):**

```json
{
  "urls": ["https://open.spotify.com/artist/06HL4z0CvFAxyc27GXpf02"],
  "followAlbums": true
}
```

**Scrape by keyword instead of URL:**

```json
{
  "searchQueries": ["Taylor Swift", "phonk", "lofi beats"],
  "searchType": "track",
  "maxSearchResults": 5
}
```

**Resolve a playlist fully (with follower count):**

```json
{
  "urls": ["https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M"],
  "includePlaylists": true
}
```

**Related-artists graph with monthly-listener enrichment:**

```json
{
  "urls": ["https://open.spotify.com/artist/3TVXtAsR1Inumwj472S9r4"],
  "includeRelatedArtists": true,
  "relatedArtistsDepth": 1,
  "enrichRelatedArtists": true,
  "includeDiscoveredOnPlaylists": true
}
```

**Historical trend tracking — schedule daily/weekly:**

```json
{
  "urls": ["https://open.spotify.com/artist/06HL4z0CvFAxyc27GXpf02"],
  "enableHistory": true,
  "historyDatasetName": "my-spotify-history"
}
```

From the second run onwards every record carries a `history.delta` block with `streamChange`, `listenerChange`, `streamVelocityPerDay`, and a `trend` (`up` / `down` / `flat`).

**Podcast show + episode catalogue:**

```json
{
  "urls": ["https://open.spotify.com/show/2MAi0BvDc6GTFvKFPXnkCL"],
  "includePodcasts": true
}
```

***

### Inputs reference

#### Compatible with `beatanalytics/spotify-play-count-scraper`

| Field | Type | Default | Description |
|---|---|---|---|
| `urls` | array | — | Spotify URLs/URIs (artist, album, track, playlist, show, episode) |
| `followAlbums` | boolean | false | For each artist URL, also crawl every album |
| `followSingles` | boolean | false | For each artist URL, also crawl every single/EP |
| `followPopularReleases` | boolean | false | Crawl Spotify's curated "popular releases" |
| `scrapePreviewUrls` | boolean | false | Include 30s preview URLs alongside play counts |

#### Added in this actor

| Field | Type | Default | Description |
|---|---|---|---|
| `searchQueries` | array | — | Scrape by keyword instead of URL |
| `searchType` | enum | `artist` | `artist` / `album` / `track` / `playlist` / `all` |
| `maxSearchResults` | int | 5 | Results per search query |
| `includeRelatedArtists` | boolean | false | Add "Fans also like" graph |
| `relatedArtistsDepth` | int | 0 | Crawl related artists as their own records (0–3) |
| `includeDiscoveredOnPlaylists` | boolean | false | Playlist attribution per artist |
| `includePlaylists` | boolean | false | Resolve full playlist contents + follower count |
| `includeLyrics` | boolean | false | Time-synced lyrics (needs `spDcCookie`) |
| `includePodcasts` | boolean | false | Resolve shows + episodes |
| `includeAnalytics` | boolean | **true** | Engagement, revenue range, momentum, concentration |
| `includeContactInfo` | boolean | **true** | Emails + categorized socials + website |
| `includeAppearsOn` | boolean | false | "Appears On" + "Featuring" discography |
| `includeConcerts` | boolean | false | Concerts (best-effort — see FAQ) |
| `enrichRelatedArtists` | boolean | false | Add monthly listeners + followers to each related artist |
| `writePlayCountsCsv` | boolean | false | Emit flat `play_counts.csv` to the key-value store |
| `enableHistory` | boolean | false | Persist snapshots + compute trends/velocity |
| `historyDatasetName` | string | `spotify-history` | Named store reused across scheduled runs |
| `spDcCookie` | string (secret) | — | `sp_dc` cookie for lyrics |
| `proxyConfiguration` | object | auto | Optional. Proxies are included automatically — leave empty unless overriding. |
| `maxConcurrency` | int | 4 | Parallel workers |
| `minDelayMs` | int | 350 | Throttle between requests |

***

### Output

Every record carries `type`, `id`, `url`, `name`, `scrapedAt`. Type-specific fields are layered on top.

**Artist record:** `verified`, `followers`, `monthlyListeners`, `worldRank`, `topCities[]`, `topTracks[]`, `albums[]`, `singles[]`, `popularReleases[]`, `relatedArtists[]`, `discoveredOnPlaylists[]`, `biography`, `externalLinks[]`, `totalTopTrackStreams`, `followerToListenerRatio`, `contactInfo`, `analytics`, `history` (when enabled).

**Album:** albumType, releaseDate, label, copyright, full `tracks[]` (each with `streamCount`), `totalAlbumStreams`.

**Track:** `streamCount`, duration, contentRating, trackNumber, album metadata, artists.

**Playlist:** owner, follower count, paginated `tracks[]` with `addedAt`.

**Show:** publisher, description, totalEpisodes, paginated `episodes[]` with name + duration + releaseDate.

#### Analytics block

```json
{
  "engagementRate": 1.56,
  "topTrackConcentration": 0.08,
  "topTrackStreams": 17637107878,
  "estimatedTopTrackRevenueUSD": { "low": 52911324, "high": 88185539, "currency": "USD" },
  "streamPayoutAssumption": { "low": 0.003, "high": 0.005, "currency": "USD" },
  "discoveryPlaylistCount": 11,
  "momentum": { "streamVelocityPerDay": 0, "trend": "flat" }
}
```

#### History block (with `enableHistory`)

```json
{
  "firstSeen": "2026-05-01T00:00:00Z",
  "snapshotCount": 12,
  "previous": { "at": "...", "monthlyListeners": 1000000, "totalStreams": 500000000 },
  "delta": {
    "daysElapsed": 1.0,
    "streamChange": 1250000,
    "streamVelocityPerDay": 1250000,
    "trend": "up"
  },
  "series": [ { "at": "...", "monthlyListeners": 0, "totalStreams": 0 } ]
}
```

***

### Pricing

Simple pay-per-event:

| Event | Cost |
|---|---|
| Actor start | $0.01 |
| Each scraped entity (artist / album / track / playlist / show / episode) | $0.02 |

**Example run costs:**

| What you scrape | Calculation | Cost |
|---|---|---|
| 1 artist with analytics + contact info | $0.01 + 1 × $0.02 | **$0.03** |
| 10 artists | $0.01 + 10 × $0.02 | **$0.21** |
| 100 artists daily (trend tracking) | $2.01 / run | **~$60 / month** |
| 500 tracks (bulk play-count audit) | $0.01 + 500 × $0.02 | **$10.01** |
| 5,000 entities (catalog sweep) | $0.01 + 5,000 × $0.02 | **$100.01** |

Compare: Chartmetric / Soundcharts start at $250–350/month per seat and don't expose per-track play counts at all.

***

### FAQ

**Does this work without configuration?**
Yes. Paste a URL and run.

**Why does lyrics require a cookie?**
Spotify gates the lyrics endpoint behind a logged-in session. To use lyrics, paste your `sp_dc` cookie value (F12 → Application → Cookies → `sp_dc` on `open.spotify.com`) into the input field. Without it, every other feature still works.

**Are concerts complete?**
No — Spotify gates most concert data behind a logged-in session. Anonymous runs often return an empty list or partial entries with only an id. Use `includeConcerts: true` only when you specifically need the best-effort data.

**Why no genres?**
Spotify removed the `genres` array from the artist endpoint in 2024. Nobody has it via this API surface anymore.

**Are the revenue estimates accurate?**
They're a range based on the publicly cited Spotify net payout band of $0.003–0.005 per stream. We never claim a precise number — we always report a range, and we surface the `streamPayoutAssumption` so you can recompute with your own band.

**Can I export to CSV / Excel?**
Yes. Apify automatically offers CSV, JSON, Excel, XML, and HTML export on every dataset. Additionally, `writePlayCountsCsv: true` writes a flat `play_counts.csv` to the key-value store matching the original scraper's shape.

**Will repeated runs over-charge me for the same entity?**
Each run is metered independently. If you re-scrape the same artist daily, that's one billable entity per run. The historical store deduplicates time-series points so trend data stays clean.

**What's the difference vs `beatanalytics/spotify-play-count-scraper`?**
Drop-in superset. Same inputs, same field names — plus related artists, "Discovered On" playlists, lyrics, podcasts, search by query, contact info, analytics block, historical trends, and "Appears On" / "Featuring".

***

### Legal

This actor scrapes only publicly available Spotify data. It is **not affiliated with, endorsed by, or sponsored by Spotify**. Use responsibly and respect Spotify's Terms of Service and applicable laws.

***

Maintained by **brilliant\_gum** on Apify.

# Actor input Schema

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

Spotify URLs of artists, albums or tracks to scrape. Accepts open.spotify.com links and spotify: URIs. Leave empty if you use 'Search queries' instead.

## `followAlbums` (type: `boolean`):

For each artist URL, also crawl every full album and return per-track play counts.

## `followSingles` (type: `boolean`):

For each artist URL, also crawl every single / EP.

## `followPopularReleases` (type: `boolean`):

For each artist URL, also crawl Spotify's curated 'popular releases'.

## `scrapePreviewUrls` (type: `boolean`):

Include 30-second audio preview URLs for tracks (alongside, not instead of, play counts).

## `searchQueries` (type: `array`):

NEW: scrape by keyword instead of URL. Each query is searched on Spotify and the top results are scraped. Pair with 'Search type' and 'Max search results'.

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

Which entity type to return for 'Search queries'.

## `maxSearchResults` (type: `integer`):

How many top results to scrape per search query.

## `includeRelatedArtists` (type: `boolean`):

NEW: add the related-artists graph to each artist record. Solves the #1 missing-field complaint.

## `relatedArtistsDepth` (type: `integer`):

0 = only list related artists on the record. 1+ = also scrape those related artists as their own records (graph crawl). Use with care, expands runs quickly.

## `includeDiscoveredOnPlaylists` (type: `boolean`):

NEW: which editorial/user playlists are driving an artist's streams (playlist attribution).

## `includePlaylists` (type: `boolean`):

NEW: for playlist URLs / search results, return full track listing, owner, and follower count (paginated past 100 tracks).

## `includeLyrics` (type: `boolean`):

NEW: time-synced lyrics per track (requires a valid 'sp\_dc cookie').

## `includePodcasts` (type: `boolean`):

NEW: resolve show & episode URLs (show metadata + episode list, episode metadata).

## `includeAnalytics` (type: `boolean`):

BONUS: per-artist analytics — engagement/loyalty rate, top-track concentration, estimated royalty revenue range, discovery reach, and momentum (from history). Turns raw numbers into decisions.

## `includeContactInfo` (type: `boolean`):

BONUS: emails (from bio) + categorized social links (Instagram/TikTok/YouTube/…) + website. Solves the marketer 'who do I contact' pain that competitors sell separately.

## `includeAppearsOn` (type: `boolean`):

BONUS: releases the artist appears on and playlists/releases featuring them — fuller discography graph.

## `includeConcerts` (type: `boolean`):

BONUS: upcoming concerts (venue, city, date). Note: Spotify gates most concert data behind a logged-in session, so anonymous runs often return an empty list.

## `enrichRelatedArtists` (type: `boolean`):

BONUS: fetch monthly listeners + rank for each related artist (adds one request per related artist).

## `writePlayCountsCsv` (type: `boolean`):

BONUS/compat: also emit a flat play\_counts.csv (artist\_url, artist\_name, album\_url, album\_name, track\_url, track\_name, play\_count) to the key-value store, matching the original actor.

## `enableHistory` (type: `boolean`):

THE killer feature: persist a timestamped snapshot every run into a named dataset, then compute deltas (daily stream change) and stream velocity vs the previous run. Run this actor on a schedule to build the time-series Spotify never gives you.

## `historyDatasetName` (type: `string`):

Named key-value store / dataset to persist snapshots into. Reused across scheduled runs to compute trends. Defaults to 'spotify-history'.

## `spDcCookie` (type: `string`):

Value of the 'sp\_dc' cookie from a logged-in open.spotify.com session. Only needed for lyrics. Stored as a secret.

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

Optional. Proxies are included and configured automatically — leave this empty unless you want to use your own.

## `maxConcurrency` (type: `integer`):

Parallel request workers. Keep low (3-5) to avoid 429s.

## `minDelayMs` (type: `integer`):

Throttle to look human and avoid rate limits.

## Actor input object example

```json
{
  "urls": [
    "https://open.spotify.com/artist/06HL4z0CvFAxyc27GXpf02",
    "https://open.spotify.com/album/1NAmidJlEaVgA3MpcPFYGq",
    "spotify:track:0VjIjW4GlUZAMYd2vXMi3b"
  ],
  "followAlbums": false,
  "followSingles": false,
  "followPopularReleases": false,
  "scrapePreviewUrls": false,
  "searchQueries": [
    "Taylor Swift",
    "phonk",
    "lofi beats"
  ],
  "searchType": "artist",
  "maxSearchResults": 5,
  "includeRelatedArtists": false,
  "relatedArtistsDepth": 0,
  "includeDiscoveredOnPlaylists": false,
  "includePlaylists": false,
  "includeLyrics": false,
  "includePodcasts": false,
  "includeAnalytics": true,
  "includeContactInfo": true,
  "includeAppearsOn": false,
  "includeConcerts": false,
  "enrichRelatedArtists": false,
  "writePlayCountsCsv": false,
  "enableHistory": false,
  "historyDatasetName": "spotify-history",
  "maxConcurrency": 4,
  "minDelayMs": 350
}
```

# Actor output Schema

## `summary` (type: `string`):

Counts of scraped entities and links to the persistent stores.

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

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

# Run the Actor and wait for it to finish
run = client.actor("brilliant_gum/spotify-insights-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "urls": [
    "https://open.spotify.com/artist/06HL4z0CvFAxyc27GXpf02"
  ]
}' |
apify call brilliant_gum/spotify-insights-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=brilliant_gum/spotify-insights-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/ex5Dj3pYHsieC5jTi/builds/bbwrXKhoTyjccX6al/openapi.json
