# Spotify Playlist Scraper: Tracks, Followers & Play Counts (`eduair94/spotify-playlist-scraper`) Actor

Export public Spotify playlists: followers, owner and every track with its play count and date added. Find playlists by keyword and see added or removed tracks between runs. Pay per playlist.

- **URL**: https://apify.com/eduair94/spotify-playlist-scraper.md
- **Developed by:** [Eduardo Airaudo](https://apify.com/eduair94) (community)
- **Categories:** Social media, Marketing, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 playlists

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?

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 Playlist Scraper

Export public Spotify playlists to JSON, CSV or Excel: the playlist's followers, owner and track count, then every track with its position, play count and date added. Paste playlist links or find playlists by keyword, run once or on a schedule, and see added or removed tracks since your last run. No Spotify account and no API key.

> Unofficial; not affiliated with Spotify. This Actor reads public playlists as the Spotify web player shows them to any visitor.

### What does Spotify Playlist Scraper do?

Each playlist you enter (or find with a keyword) gives you:

- **One playlist row** (`rowType: "playlist"`): `name`, `followers`, `totalTracks`, owner (`ownerName`, `ownerId`), `description`, cover (`imageUrl`), `isEditorial` (Spotify's own playlists such as Today's Top Hits) and `snapshotId`, Spotify's revision of the playlist.
- **One row per track** (`rowType: "track"`), in playlist order: `position`, `name`, `artists`, `playCount` (all-time Spotify streams), `addedAt`, `albumName`, `durationMs`, `explicit` and the track's Spotify link. Turn **Include tracks** off and you get the playlist rows only.
- **Keyword search** (`searchTerms`): the playlists Spotify's search returns for a term, each with the term and its place in the results.
- **Change tracking** (`trackChanges`): followers gained or lost since your previous run, and the songs added to or removed from every playlist since the last run that read it whole.

Whole playlists are read in batches of 500 entries, up to 10,000 tracks per playlist, so a 300-song playlist takes one request.

### How to scrape a Spotify playlist

1. Copy the playlist's link in Spotify (Share → Copy link to playlist) and paste it into **Playlists**, one per line. `spotify:playlist:` URIs, playlist IDs and spotify.link short links work too, and so does a list of links pasted on one line (separated by spaces, commas or semicolons).
2. Set **Max tracks per playlist** to at least the playlist's length if you want every song (the default reads the first 100).
3. Click **Start**, then open the **Playlists** or **Tracks** view in the Output tab, or download everything as JSON, CSV, Excel or HTML.

Each playlist's row comes first, followed by all of its tracks in playlist order; the next playlist starts after them. Every track row also carries `playlistId` and `playlistName`, so one export holds both. Filter by `rowType` in your spreadsheet to split them.

### Find Spotify playlists by keyword

Put keywords in **Search terms** (`searchTerms`): `lofi study`, `workout`, `indie pop`, a genre, a mood or an artist's name. Each term adds the first **Max playlists per search** (`maxPlaylistsPerSearch`) playlists Spotify finds, in Spotify's order, and each playlist row records its `searchTerm` and `searchRank` (1 = first result). Spotify ranks playlists per country: set **Search market** (`market`) to search as a listener in, for example, GB or MX would.

Keyword results mix Spotify's editorial playlists with playlists by curators, labels and listeners; `isEditorial` and `ownerName` tell them apart. A playlist that two terms (or a term and a link) both return is fetched and charged once. A playlist link typed under **Search terms** is read as a playlist, not searched as text.

### Track playlist changes: added and removed songs

1. Turn on **Track changes** (`trackChanges`) and set a **History store name** (`historyStoreName`), for example `editorial-watchlist`.
2. Set **Max tracks per playlist** at least as high as your longest playlist, so every run reads whole playlists.
3. Save the input as a task and schedule it daily or weekly.

From the second run on, each playlist row says how its followers moved since the last run (`previousFollowers`, `followersChange`, `previousScrapedAt`) and lists `tracksAdded` and `tracksRemoved` since the last complete run (`previousCompleteScrapedAt`), each as `{id, name, artists}`; each track row says whether the song was `added` or `kept` (`change`). The history is kept in a key-value store in your own Apify account, one record per playlist.

A complete run is one that read the whole playlist. `tracksRemoved` is only filled when this run and an earlier one both did: a song past **Max tracks per playlist** is not gone, just not read. A run that is not complete (Include tracks off, a lower **Max tracks per playlist**, a page Spotify did not answer) still updates the followers but keeps the last complete track list, so the next complete run compares with it. Give each schedule its own history store: two schedules that share a store and a playlist overwrite each other's record of it.

### Input

| Field | What it does | Default |
| --- | --- | --- |
| `playlists` | Playlist links (open.spotify.com/playlist/…, spotify.link short links too), `spotify:playlist:` URIs or playlist IDs, one per line. A repeated playlist is fetched and charged once. | none |
| `searchTerms` | Keywords that find playlists, one per line. | none |
| `maxPlaylistsPerSearch` | Playlists each search term adds, in Spotify's order (1 to 100). | 20 |
| `includeTracks` | One row per track besides the playlist row. Off: playlist rows only. | true |
| `maxTracksPerPlaylist` | Playlist entries read per playlist, in playlist order (1 to 10,000). | 100 |
| `trackChanges` | Compare each playlist with its previous run and add the change columns. | false |
| `historyStoreName` | The key-value store in your account that keeps the previous runs for **Track changes**. | spotify-playlist-history |
| `market` | Two-letter country code the keyword search runs in. | US |

Enter playlists, search terms or both. Example input:

```json
{
    "playlists": [
        "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M",
        "spotify:playlist:0vvXsWCC9xrXsKd4FyS8kM"
    ],
    "searchTerms": ["lofi study"],
    "maxPlaylistsPerSearch": 2,
    "maxTracksPerPlaylist": 500
}
```

### Output

A playlist row (Today's Top Hits, read on 2026-11-01):

```json
{
    "rowType": "playlist",
    "playlistId": "37i9dQZF1DXcBWIGoYBM5M",
    "name": "Today’s Top Hits",
    "followers": 33643877,
    "totalTracks": 50,
    "ownerName": "Spotify",
    "ownerId": "spotify",
    "description": "The hottest 50. Cover: Tame Impala",
    "isEditorial": true,
    "imageUrl": "https://i.scdn.co/image/ab67706f00000002960019ea66cba66a44fdd4c2",
    "url": "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M",
    "snapshotId": "AAAAAIT6ToT/+IebTegHazxc0z6HwIFk",
    "input": "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M",
    "searchTerm": null,
    "searchRank": null,
    "scrapedAt": "2026-11-01T08:00:01.512Z"
}
```

Its first track row:

```json
{
    "rowType": "track",
    "playlistId": "37i9dQZF1DXcBWIGoYBM5M",
    "playlistName": "Today’s Top Hits",
    "position": 1,
    "id": "7bxaFZ1O3cHkgLKMsdC3xR",
    "name": "Loser",
    "artists": ["Tame Impala"],
    "playCount": 369156638,
    "addedAt": "2026-08-07T04:02:23.096Z",
    "artistIds": ["5INjqkS1o8h1imAzPqGZBb"],
    "albumName": "Deadbeat",
    "albumId": "5WulAOx9ilWy1h8UGZ1gkI",
    "durationMs": 223069,
    "explicit": true,
    "imageUrl": "https://i.scdn.co/image/ab67616d0000b273208500450dcd0fd294d7bd3b",
    "url": "https://open.spotify.com/track/7bxaFZ1O3cHkgLKMsdC3xR",
    "scrapedAt": "2026-11-01T08:00:01.512Z"
}
```

| Playlist row field | Meaning |
| --- | --- |
| `rowType` | `playlist` here, `track` on track rows. |
| `playlistId`, `name`, `url` | The playlist's Spotify ID, name and page. |
| `followers` | How many Spotify users follow (save) the playlist. |
| `totalTracks` | Entries on the playlist, as Spotify counts them. |
| `ownerName`, `ownerId` | The owner's display name and Spotify username. |
| `description`, `imageUrl` | The description as plain text, and the cover. |
| `isEditorial` | `true` for Spotify's own playlists. |
| `snapshotId` | Spotify's revision of the playlist: a new value means tracks were added, removed or moved. |
| `input`, `searchTerm`, `searchRank` | The line you entered, or the search term that found the playlist and its place in the results. |
| `scrapedAt` | When the playlist was read. |
| `previousFollowers`, `followersChange`, `previousScrapedAt` | **Track changes**: followers at the last run, the difference, and when that run was. |
| `tracksAdded`, `tracksRemoved`, `previousCompleteScrapedAt` | **Track changes**: songs added and removed since the last complete run, and when that run was. |

| Track row field | Meaning |
| --- | --- |
| `playlistId`, `playlistName`, `position` | The playlist the track is on and its place there (1 = top). |
| `id`, `name`, `url` | The track's Spotify ID, name and page. |
| `artists`, `artistIds` | The credited artists and their Spotify IDs. |
| `playCount` | All-time Spotify play count (streams) of the track. |
| `addedAt` | When the track was added to the playlist. |
| `albumName`, `albumId`, `imageUrl` | The album the track is from, and its cover. |
| `durationMs`, `explicit` | Length in milliseconds and the explicit flag. |
| `change` | **Track changes**: `added` or `kept`. |

The Output tab has three views: **Playlists**, **Tracks**, and **Changes since the last run**. Apify views cannot filter rows, so with **Include tracks** on the Playlists view lists the track rows too: turn it off, or filter by `rowType`, for playlists only. The **Playlists and tracks (CSV)** link in the Output tab leaves out the nested `tracksAdded`, `tracksRemoved` and `artistIds` lists, which would spread over many columns; the JSON link and the regular dataset downloads keep them. Podcast episodes and local files on a playlist get no row, and the tracks around them keep their Spotify positions.

### How much does it cost to scrape Spotify playlists?

You pay per playlist, not per row. The `playlist` event covers the playlist row and up to 100 of its tracks; longer playlists add one `tracks-page` event for every further 100 tracks. Your price follows your Apify plan:

| Apify plan | `playlist`: a playlist with up to 100 tracks | `tracks-page`: each further 100 tracks |
| --- | --- | --- |
| Free | $0.003 ($3.00 per 1,000) | $0.0015 ($1.50 per 1,000) |
| Bronze | $0.0027 ($2.70 per 1,000) | $0.00135 ($1.35 per 1,000) |
| Silver | $0.0024 ($2.40 per 1,000) | $0.0012 ($1.20 per 1,000) |
| Gold, Platinum and Diamond | $0.002 ($2.00 per 1,000) | $0.001 ($1.00 per 1,000) |

Each run also has Apify's start fee of $0.00005, and Apify covers the first 5 seconds of every run's compute. There is no monthly rental and no charge for platform usage.

| Example (Free plan) | Events | Cost |
| --- | --- | --- |
| The prefilled run: 3 playlists, 20 tracks each | 3 `playlist` | $0.009 + $0.00005 start |
| Today's Top Hits with all 50 tracks | 1 `playlist` | $0.003 |
| A 300-track playlist | 1 `playlist` + 2 `tracks-page` | $0.006 |
| A 10,000-track playlist | 1 `playlist` + 99 `tracks-page` | $0.1515 |
| 1,000 playlists without tracks (`includeTracks` off) | 1,000 `playlist` | $3.00 |
| 50 playlists of up to 100 tracks, checked daily for 30 days | 1,500 `playlist` | $4.50 |

Never charged: playlists that do not exist or are private, links to tracks or albums, broken IDs, searches that find nothing, repeated playlists, and playlists Spotify did not answer for. Set a maximum cost per run and the Actor stays within it: every playlist it starts keeps its place in the budget, no new playlist or page starts once the rest of the budget cannot cover it, and it never charges more than your maximum. Tracks past the budget are left out, and the run summary counts the playlists cut short.

### FAQ

#### How many followers does a Spotify playlist have?

Spotify shows the follower count (the number of users who saved the playlist) on every public playlist, and `followers` holds it as an exact number. Today's Top Hits had 33,643,877 on 2026-11-01. With **Track changes** on and a daily schedule, `followersChange` gives you the daily growth of any playlist.

#### Can I scrape editorial playlists like Today's Top Hits?

Yes. Spotify's editorial and algorithmic playlists (IDs starting with `37i9dQZ`) work like any other public playlist, with followers and every track, and `isEditorial` marks them.

#### Why does the track order of editorial playlists change?

Spotify personalizes the order of some editorial playlists for each listener and each request, so two runs can list the same songs in a different order. The Actor reads up to 500 entries per request to get one consistent order; if pages of a very long playlist still overlap, repeated songs are left out (and not charged) and the run summary says so. To compare runs, use `tracksAdded` and `tracksRemoved` rather than `position`.

#### Why is a play count 0?

Spotify shows a play count only once a track passes 1,000 plays, so `playCount: 0` means fewer than 1,000 plays, not that nobody listened. New and niche songs read 0 until they cross the threshold. An empty `playCount` (null) means Spotify sent no count at all, which happens for tracks that are unavailable.

#### Can I scrape private playlists or my own library?

No. Only public playlists can be read. A private, deleted or mistyped playlist is listed in ERRORS with the reason and is not charged. Liked Songs and the rest of a personal library are not playlists, so they cannot be read either.

#### Do I need a Spotify account or API key?

No. You only need an Apify account; the Actor never asks for your Spotify login. Spotify's own Web API does not return play counts at all, which is why the `playCount` column is useful.

#### What happens with a wrong link or a search without results?

The run goes on. Each failed line is listed in the ERRORS record of the run's key-value store with the reason and `charged: false`, and the status message counts them. Temporary Spotify errors are retried, then tried once more at the end of the run (a page of a long playlist gets one more try after a short pause). A run fails only when it delivered no playlist because of such an error, or because its timeout ran out before any playlist was read, so Apify's retry and alert settings can react; nothing is charged then.

#### Is it legal to scrape Spotify playlists?

The Actor reads public playlist data that Spotify shows to every visitor: titles, followers, tracks and their public play counts. It collects no personal data about listeners. Make sure your use of the data complies with Spotify's terms and the laws that apply to you.

### Use it from the Apify API

Start a run and get the rows in one call (synchronous calls wait up to 5 minutes):

```bash
curl -X POST "https://api.apify.com/v2/acts/eduair94~spotify-playlist-scraper/run-sync-get-dataset-items?maxTotalChargeUsd=1" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"playlists": ["https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M"], "maxTracksPerPlaylist": 50}'
```

JavaScript, with the `apify-client` package:

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('eduair94/spotify-playlist-scraper').call({
    searchTerms: ['indie pop'],
    maxPlaylistsPerSearch: 10,
    includeTracks: false,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const playlist of items) console.log(playlist.searchRank, playlist.name, playlist.followers, playlist.ownerName);
```

Python, with the `apify-client` package:

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("eduair94/spotify-playlist-scraper").call(
    run_input={"playlists": ["https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M"], "maxTracksPerPlaylist": 100}
)
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    if row["rowType"] == "track":
        print(row["position"], row["name"], row["playCount"], row["addedAt"])
```

Schedules, webhooks and integrations (Google Sheets, Slack, Make, Zapier) work like for any Apify Actor, and AI agents can call it through Apify's MCP server.

### Use cases

- **Playlist pitching**: find the playlists that fit a release by keyword, rank them by `followers`, and check what kind of songs (and how many streams) each one carries before you pitch.
- **Curator research**: build a list of independent curators for a genre with `ownerName`, follower counts and track counts, and drop the editorial ones with `isEditorial`.
- **Label A\&R**: see which new songs editorial playlists add every week, and how many plays they already have.
- **Playlist monitoring**: a daily check of your placements: get told when a song is added or dropped (`tracksAdded`, `tracksRemoved`) and watch follower growth.
- **Music data analysis**: export full tracklists with play counts and add dates for research on playlists, genres and charts.

### Related Spotify scrapers

- [Spotify Scraper: Play Counts, Monthly Listeners & Playlists](https://apify.com/eduair94/spotify-scraper): tracks, albums, artists, charts, lyrics and podcasts, from links or keywords.
- [Spotify Play Count Scraper](https://apify.com/eduair94/spotify-play-count-scraper): play counts for every track of an artist's discography, an album or a playlist, one row per track.
- [Spotify Monthly Listeners Scraper](https://apify.com/eduair94/spotify-monthly-listeners-scraper): monthly listeners, followers, world rank and top cities, 50 artists per request.
- [Spotify Artist Scraper](https://apify.com/eduair94/spotify-artist-scraper): full artist profiles with biography, social links, top tracks and related artists.
- [Spotify Charts Scraper](https://apify.com/eduair94/spotify-charts-scraper): Top 200, top artists and top albums by country, daily or weekly, with streams.

# Actor input Schema

## `playlists` (type: `array`):

One playlist per line: an open.spotify.com/playlist/ link (spotify.link short links work too), a spotify:playlist: URI or a 22-character playlist ID. Editorial playlists such as Today's Top Hits work like any other public playlist. The same playlist entered twice is fetched and charged once.

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

Keywords that find playlists, one per line, as in Spotify's search box (for example lofi study, workout, indie pop). Each term adds the first playlists Spotify finds, in Spotify's order; `searchTerm` and `searchRank` on each playlist row say which term found it and where it ranked.

## `maxPlaylistsPerSearch` (type: `integer`):

How many playlists each search term adds, in Spotify's order (up to 100). Every playlist found is one playlist result.

## `includeTracks` (type: `boolean`):

On: one row per track with its position, play count, date added, artists, album and duration. Off: only the playlist rows (followers, owner, track count), one event per playlist.

## `maxTracksPerPlaylist` (type: `integer`):

How many playlist entries to read per playlist, in playlist order (up to 10,000). Raise it to export whole playlists. Podcast episodes and local files are skipped; the tracks keep their Spotify positions.

## `trackChanges` (type: `boolean`):

Compare each playlist with the last run that delivered it: playlist rows get `previousFollowers`, `followersChange`, `tracksAdded`, `tracksRemoved` and `previousScrapedAt`, and track rows get `change` (added or kept). Added and removed tracks compare whole playlists, so set Max tracks per playlist at least as high as the playlist is long. A playlist's first run leaves them empty.

## `historyStoreName` (type: `string`):

Name of the key-value store in your Apify account that keeps each playlist's followers and tracks between runs. Use one name per schedule (lower-case letters, digits and hyphens). Only read and written when Track changes is on.

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

Two-letter country code the keyword search runs in (US, GB, DE, BR, MX…): Spotify ranks playlists per country. Playlist links ignore it.

## Actor input object example

```json
{
  "playlists": [
    "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M"
  ],
  "searchTerms": [
    "lofi study"
  ],
  "maxPlaylistsPerSearch": 2,
  "includeTracks": true,
  "maxTracksPerPlaylist": 20,
  "trackChanges": false,
  "historyStoreName": "spotify-playlist-history",
  "market": "US"
}
```

# Actor output Schema

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

Every playlist of this run with its followers, owner and track count, each followed by its tracks with position, play count and date added.

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

The same rows as CSV for spreadsheets, without the nested lists tracksAdded, tracksRemoved and artistIds (they would spread over many columns; the JSON link has them). Filter by rowType to split playlists from tracks.

## `runSummary` (type: `string`):

Playlists planned and delivered, track rows, the events charged, repeats, failed inputs, warnings and the run outcome.

## `errors` (type: `string`):

Each playlist or search term that delivered nothing, with the reason; written only when an input failed. Never charged.

# 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 = {
    "playlists": [
        "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M"
    ],
    "searchTerms": [
        "lofi study"
    ],
    "maxPlaylistsPerSearch": 2,
    "maxTracksPerPlaylist": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("eduair94/spotify-playlist-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 = {
    "playlists": ["https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M"],
    "searchTerms": ["lofi study"],
    "maxPlaylistsPerSearch": 2,
    "maxTracksPerPlaylist": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("eduair94/spotify-playlist-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 '{
  "playlists": [
    "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M"
  ],
  "searchTerms": [
    "lofi study"
  ],
  "maxPlaylistsPerSearch": 2,
  "maxTracksPerPlaylist": 20
}' |
apify call eduair94/spotify-playlist-scraper --silent --output-dataset

```

## MCP server setup

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