# Spotify Artist Scraper - Listeners & Followers (`usestring/spotify-artists`) Actor

Look up Spotify artists by ID, URI or open.spotify.com URL and get exact numbers: monthly listeners and follower count as integers rather than the rounded 100.6M the page prints, plus verified status, artist image and the top-tracks list with a play count on every track. No API credentials.

- **URL**: https://apify.com/usestring/spotify-artists.md
- **Developed by:** [String](https://apify.com/usestring) (community)
- **Categories:** Social media, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 Artist Scraper — exact monthly listeners and followers

This Actor collects public Spotify artist data by artist ID or `open.spotify.com` URL. It returns
**exact** monthly listeners, follower count and top-track play counts — `100593317`, not the rounded
"100.6M" the artist page displays.

No Spotify account, login, API key or client credentials are used. The anonymous token the Actor
reads is the one Spotify's own public embed page hands out.

### What it returns

| Field | Type | Notes |
| --- | --- | --- |
| `artistId` | string | Spotify's 22-character artist ID — stable, use it to de-duplicate |
| `name` | string | Artist name |
| `monthlyListeners` | number | **Exact**, e.g. `100593317` — the page shows "100.6M" |
| `followerCount` | number | **Exact** integer, not a rounded display figure |
| `isVerified` | boolean | Whether Spotify shows the artist as verified |
| `topTracks` | object\[] | `{ trackId, name, playCount }` — `playCount` is an exact integer, e.g. `2801945011` |
| `imageUrl` | string | Artist avatar, the widest of the sizes Spotify ships |
| `artistUrl` | string | `https://open.spotify.com/artist/<artistId>` |
| `sourceUrl`, `collectedAt` | string | Provenance for every row |

### Input

```json
{ "artists": ["4gzpq5DPGxSnKTe4SA8HAU", "https://open.spotify.com/artist/06HL4z0CvFAxyc27GXpf02"] }
```

| Field | Description |
| --- | --- |
| `artists` | Spotify artist IDs, `spotify:artist:<id>` URIs or `open.spotify.com` artist URLs. Required, 1–200. |
| `maxItems` | Cap on dataset items. Default 1000. Free plans stop at 250 requests and 250 results — see below. |
| `concurrency` | Artists fetched in parallel. Default 5. |

An ID, a URI and a full URL for the same artist collapse to one fetch, so a mixed list is never
billed twice. A value that is not a 22-character Spotify ID — an artist's name, for example — is
rejected before it costs a fetch and is reported as a failure.

### How it reads exact figures

The Spotify artist page renders nothing server-side: an ordinary fetch returns the web-player shell,
and a crawler user-agent upgrades that only to Open Graph tags whose listener count is already
rounded for display. The exact figures come from the same `queryArtistOverview` call the web player
itself makes.

That call needs an anonymous bearer token and a persisted-query hash, both of which the public pages
hand out. **This Actor reads them once per run** — three fetches in total: the `open.spotify.com`
shell, the web-player bundle it links, and one `/embed/artist/` page — and then issues one request
per artist. The three-fetch bootstrap is per run, not per artist, so it amortises across a large
artist list.

If that bootstrap fails, the run fails as one error rather than reporting every artist as a
separately broken target.

### Use cases

- A\&R and artist scouting, ranked by exact monthly listeners rather than a rounded display figure
- Tracking artist and catalogue growth over time by re-running on a schedule
- Label, distributor and playlist reporting across a roster
- Comparing follower count against monthly listeners to gauge audience conversion
- Enriching a music or rights database with verified status and artist imagery

### Reliability

Every field comes from Spotify's own GraphQL response rather than from rendered markup, so a value
is either present and exact or absent — the counts do not change between runs for the same artist
beyond Spotify's own updates.

An artist ID Spotify does not know answers with an empty record. That is treated as a failed target
and recorded under `failures` in the run's `SUMMARY`, rather than reaching the dataset as an all-null
row counted as a success. A run in which every artist failed exits with an error.

### Frequently asked questions

**Do I need a Spotify account, API key or client credentials?** No. This Actor uses the anonymous
access token that Spotify's own public `/embed/` page mints server-side, so no login, no developer
app and no client secret is involved.

**Are the monthly listeners exact or rounded?** Exact. This Actor returns `monthlyListeners` as an
integer such as `100593317`, where the Spotify artist page renders "100.6M". `followerCount` and
every `topTracks[].playCount` are exact integers too.

**How do I get Spotify artist follower counts?** Supply the artist's 22-character Spotify ID (or its
`open.spotify.com` URL) in the `artists` input, and each dataset row returns `followerCount`
alongside `monthlyListeners` for that artist.

**Can I search Spotify by artist name?** No. The Spotify Artist Scraper takes artist IDs, URIs or
artist URLs — you supply the artists, it does not do discovery. A name is rejected as an invalid
target before any fetch is spent on it.

**How many artists can one run collect?** Up to 200 per run, which is the ceiling on the `artists`
input.

**Does it return albums, full discographies or playlists?** No. This Actor returns artist-level
fields plus the top-tracks list Spotify shows on the artist page.

### Limitations

Artist-level data only: no full discography, no album or playlist listings, no track audio features,
and no search or discovery. `genres` and `popularity` are Spotify Web API fields with no counterpart
anywhere in the public web player's data — they are carried in the JSON as `[]` and `null` so the
dataset keeps one column set per artist, and they are not part of the table view. Only
`spotify.com` URLs are accepted.

### Free plan limit

Runs started from an Apify **free plan** stop at **250 requests and 250 results**, and the run
reports that it reached the limit. Any paid plan runs the full input and `maxItems` you set. The
`artists` input already caps at 200, so in practice a free-plan run is bounded by that ceiling
rather than by the 250 limit.

The limit exists because this Actor fetches through our own infrastructure, which Apify does not
cover for free-plan runs. It binds on requests as well as results so that a large input list cannot
spend those fetches for rows the run will not return.

# Actor input Schema

## `artists` (type: `array`):

Spotify artist IDs or open.spotify.com artist URLs.

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

Global cap on dataset items. Runs started from an Apify free plan stop at 250 requests and 250 results; any paid plan runs the full amount.

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

Targets fetched in parallel.

## Actor input object example

```json
{
  "artists": [
    "4gzpq5DPGxSnKTe4SA8HAU"
  ],
  "maxItems": 1000,
  "concurrency": 5
}
```

# Actor output Schema

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

Collect public Spotify artists by ID or URL - exact monthly listeners, followers, top-track play counts and verified status.

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

Item count, failure count and every target that failed, with its error.

# 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 = {
    "artists": [
        "4gzpq5DPGxSnKTe4SA8HAU"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("usestring/spotify-artists").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 = { "artists": ["4gzpq5DPGxSnKTe4SA8HAU"] }

# Run the Actor and wait for it to finish
run = client.actor("usestring/spotify-artists").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 '{
  "artists": [
    "4gzpq5DPGxSnKTe4SA8HAU"
  ]
}' |
apify call usestring/spotify-artists --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,usestring/spotify-artists"
        }
    }
}

```

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/y53QfRlxIsUkrAseS/builds/jh1QS6MG67vjFvK0X/openapi.json
