# Spotify Curators · Emails & Submit Links (`corent1robert/spotify-playlist-curator-leads`) Actor

Find unique Spotify playlist curators who published a submit email, Instagram or SubmitHub link. Niche search, min followers, last activity. One row per curator — not per playlist.

- **URL**: https://apify.com/corent1robert/spotify-playlist-curator-leads.md
- **Developed by:** [Corentin Robert](https://apify.com/corent1robert) (community)
- **Categories:** Lead generation, Social media
- **Stats:** 1 total users, 1 monthly users, 81.8% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $14.00 / 1,000 curator scrapeds

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

### What does Spotify Playlist Curator Leads do?

This Actor finds **playlist curators** on [Spotify](https://open.spotify.com) who **published a submit contact** in a playlist description (email, Instagram, SubmitHub, Groover, Ko-fi). It writes **one row per curator** (`owner.id`), not one row per playlist.

It does **not** scrape artist emails. It does **not** need a Spotify app key or login. Empty contact fields mean the curator did not publish one — not a failed scrape.

About **8–10 %** of playlists on a `{genre} submit` search show a public email. That is expected. Search **keeps paging to offset 1000** until Max curators is filled.

### Why scrape Spotify playlist curators?

Playlist pitching is a paid channel. Agencies, indie labels, and managers need a **contactable list**, not 200 “Chill Beats” rows from the same account.

- Build a sequencer file of curators in a niche (`indie pop submit`, `lofi submit`)
- Skip editorial Spotify lists, collaborative dumps, stubs, and mega-walls that never reply
- Keep only lists above a follower floor that still add tracks
- Export **JSON / CSV / Excel**, schedule a weekly refresh

On Apify you can **schedule** runs and call the Actor from the **API**.

### What data can this Spotify curator scraper extract?

| Field | Description |
|---|---|
| `curatorName`, `curatorId`, `profileUrl` | Playlist owner |
| `email`, `emails` | Public submit address(es) from descriptions |
| `instagram`, `submitLinks`, `websites` | Other public contacts |
| `playlistName`, `playlistUrl`, `followers`, `trackCount` | Sample playlist to mention in the pitch |
| `lastAddedAt`, `lastAddedDays` | When a track was last added (if the activity filter is on) |
| `collaborative`, `description`, `sourceQuery`, `market`, `scrapedAt` | Context |

Not extracted: private emails, Spotify inboxes, artist bios, full track dumps, private playlists.

### How to scrape Spotify curator emails

1. Open this Actor in Apify Console.
2. **Niche:** leave **Indie pop · submit** (or pick Lofi / Hip-hop / EDM…). These presets already contain `submit`.
3. Optional: extra keyword (`france`), exclude keywords (`radio`, `copyright`), or paste playlist / profile URLs.
4. **Pre-filters:** market, min/max followers, min tracks, required contact (**Email**), last track added (**6 months**), skip collaborative.
5. Leave **Max curators** at 20. The run **pages search to offset 1000** until 20 unique curators pass — it does not stop after 20 playlists.
6. Keep **Run options → Timeout** at least **1 hour** (Actor default is **4 hours**). A 5-minute timeout cannot fill 20 email curators; the Actor stops ~20s before abort, cuts HTTP calls at 12s, and keeps the dataset.
7. Start. Download JSON, CSV, or Excel. Use **Curators — Outreach** for the email columns.

See the **Input** tab for the visible options.

### How much does it cost?

**Pay-per-event.** Actor start is **$0.00005**. You pay per **unique curator** written to the dataset — not per playlist scanned. One SubmitHub credit is ~$1; this Actor is a list of public inboxes, not a dump of playlists.

**Free plan:** cap **20 curators**. Paid plans up to **2,000**.

| Apify plan | Per curator | Per 1,000 |
|---|---|---|
| Free | **$0.02** | **$20.00** |
| Bronze | **$0.018** | **$18.00** |
| Silver | **$0.016** | **$16.00** |
| Gold | **$0.014** | **$14.00** |
| Platinum | **$0.012** | **$12.00** |
| Diamond | **$0.01** | **$10.00** |

| Run | Approx. cost |
|---|---|
| Default / Free cap (20 curators) | **$0.40** |
| One niche + market (~50–80 curators) | **$1.00–$1.60** |
| 100 curators | **$2.00** |

Spotify search stops at offset 1,000, so a single keyword rarely fills 1,000 unique inboxes. A generic `lofi` search with **Email required** can scan many pages and still return few rows — use a `submit` niche. Set a **max total charge** on Apify.

Default memory is **512 MB** (HTTP only). Default timeout is **4 hours**. If you leave Run options at 5 minutes, the Actor stops ~35 seconds early with a partial dataset instead of a platform abort.

### Input

See the **Input** tab.

| Field | Why it exists (pitching ICP) |
|---|---|
| Niche | Genre pre-list. Preset `{genre} submit` queries that actually yield emails |
| Extra keyword | Append `france`, `female vocal`, or full custom search |
| URLs | Force specific playlists / profiles (profiles page the **whole** catalog) |
| Market | US vs FR vs BR catalog |
| Required contact | Email vs any (IG / SubmitHub) vs none |
| Min / max followers | Do not pitch 12-follower stubs or 2M walls that never reply |
| Min tracks | Skip empty / 3-track lists |
| Last track added | Drop dormant lists (3 / 6 / 12 months). **Any** skips extra track calls |
| Skip collaborative | One inbox, not a dump |
| Exclude keywords | Drop `radio`, `copyright`, `official soundtrack` |
| Max curators | Unique owners. Search pages until this cap or offset 1000 |

### Output

You can download **JSON, HTML, CSV, or Excel**.

```json
{
  "curatorName": "Example Curator",
  "email": "submit@example.com",
  "instagram": ["examplecurator"],
  "followers": 12000,
  "playlistName": "Indie Pop",
  "playlistUrl": "https://open.spotify.com/playlist/example",
  "profileUrl": "https://open.spotify.com/user/example"
}
```

### Tips

- Prefer niches that include **submit**. Mega-playlists rarely publish an email.
- Two playlists from the same owner become **one row**. Contacts from their other public playlists are merged (paginated).
- Last-activity uses first + last 50 tracks (Spotify does not sort by recency).
- No Spotify Client ID. If the public embed token disappears, the Actor needs an update.

### FAQ

#### Why so few emails?

Most curators do not publish one. On `{genre} submit` searches we measured **~8–10 %** of playlists. The Actor pages until Max curators, it does not invent addresses.

#### Is this the same as a Spotify playlist scraper?

No. Playlist scrapers dump tracks. This file is for **outreach**: unique owners with a public submit path.

#### Do I need a Spotify developer app?

No.

### Is it legal to scrape Spotify playlist descriptions?

This Actor only reads **public** playlist metadata and descriptions curators chose to show (including on the public embed). Use the export for legitimate pitching. Respect [Spotify’s terms](https://www.spotify.com/legal/end-user-agreement/) and do not spam. Personal data in public descriptions can still fall under GDPR — you need a legitimate interest.

### Support

Issues tab on this Actor, or <corentin@outreacher.fr>. Programmatic runs: **API** tab.

# Actor input Schema

## `niche` (type: `string`):

This is the category pre-list. Presets already include `submit` — that is what actually yields public emails. **Custom** uses the keyword field only. Editorial Spotify playlists are always skipped.

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

Optional extra terms appended to the niche (e.g. `france`, `female vocal`, `acoustic`). If Niche is **Custom**, this is the full search — include `submit` if you want emails.

## `playlistUrls` (type: `array`):

Optional. One `open.spotify.com/playlist/…` or `/user/…` per line. Profile URLs page the owner’s **whole** public catalog (not the first 50). Then keyword search fills Max curators.

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

Spotify search market. Pitch US playlists from the US catalog, FR from France, etc.

## `requireContact` (type: `string`):

**Email (default):** only curators with a public email in a playlist description — ready for a sequencer. After a hit, the Actor pages **all** of that owner’s public playlists to merge extra inboxes.

**Any contact:** email or Instagram or SubmitHub / Groover / Ko-fi.

**None:** also keep curators with no published contact (research only).

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

Skip tiny lists nobody streams. Default **500**. The sample playlist is the niche hit you would mention in the pitch.

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

Skip mega-walls that never reply (Today’s Top Hits clones). Independent curators who actually listen to pitches are rarely above **50–100k**. **0** = no cap.

## `minTracks` (type: `integer`):

Skip stub / empty lists. Default **20**. A 3-track playlist is not a curator you pitch.

## `lastActivity` (type: `string`):

Skip dormant lists. Uses first + last 50 tracks (playlist order is not recency). **6 months** is the useful default — a real curator at ~90 days would be dropped by 3 months. **Any** skips the extra track calls.

## `skipCollaborative` (type: `boolean`):

Collaborative dumps rarely have one person who reads submissions. Default **on**.

## `excludeKeywords` (type: `string`):

Drop playlists whose **name or description** contains these (comma or newline). Typical ICP skips: `radio`, `copyright`, `official soundtrack`. Editorial owner `spotify` is already always skipped.

## `maxCurators` (type: `integer`):

Unique `owner.id` rows. Default **20**. Playlists that already show an email in the search snippet are processed first. Search keeps paging to offset 1000 until this cap. Leave **Run options → Timeout** at 1 hour+ (Actor default is 4 hours). A 5-minute timeout stops early with a partial dataset — it no longer dies mid-search.

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

Throttle between Spotify HTTP calls.

## `maxRequestRetries` (type: `integer`):

Retries on 429 / 5xx.

## Actor input object example

```json
{
  "niche": "indie_pop",
  "playlistUrls": [],
  "market": "US",
  "requireContact": "email",
  "minFollowers": 500,
  "maxFollowers": 0,
  "minTracks": 20,
  "lastActivity": "6m",
  "skipCollaborative": true,
  "maxCurators": 20,
  "minDelayMs": 60,
  "maxRequestRetries": 5
}
```

# Actor output Schema

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

Name, email, followers, playlist

## `outreach` (type: `string`):

Email, Instagram, submit links

## `dataset` (type: `string`):

All curator rows

## `output` (type: `string`):

Curators scraped, skips, search pages

## `runLog` (type: `string`):

Live progress

# 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 = {
    "query": "",
    "playlistUrls": [],
    "excludeKeywords": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("corent1robert/spotify-playlist-curator-leads").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 = {
    "query": "",
    "playlistUrls": [],
    "excludeKeywords": "",
}

# Run the Actor and wait for it to finish
run = client.actor("corent1robert/spotify-playlist-curator-leads").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 '{
  "query": "",
  "playlistUrls": [],
  "excludeKeywords": ""
}' |
apify call corent1robert/spotify-playlist-curator-leads --silent --output-dataset

```

## MCP server setup

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

```

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/Wx0AdPS1LSsC52N6R/builds/EYYCX45ankus3Bo1s/openapi.json
