# Spotify Scraper: Playlists, Albums, Artists & Tracks Metadata (`hyperbach/spotify-scraper`) Actor

Scrape Spotify metadata by link: every track of a playlist or an album, an artist's top tracks and releases, single tracks. Track id, name, artists, album, release date, duration, explicit, track number, play count, preview and cover URLs; playlist owner and followers. No login.

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

## Pricing

from $0.50 / 1,000 track or releases

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 Scraper: Playlists, Albums, Artists & Tracks Metadata

**Spotify metadata by link, logged out: every track of a playlist or an album, an artist's top tracks and releases, and single tracks — the track id and URL, name, artists, album, release date, duration, the explicit flag, disc and track number, the play count, the 30-second preview URL and the cover URL, with the playlist's name, owner and followers on a playlist's tracks — several links in one run, a max per link.** One free `list` row per link carries a completeness verdict: COMPLETE (every item of Spotify's count), CAPPED (your limit) or PARTIAL. No login, no API key, no browser, proxies handled for you. Never the audio.

### Why this Spotify scraper

- **Playlists, albums, artists and tracks in one run.** Paste open.spotify.com links (with `/intl-xx/`, `/embed/` or `?si=`, as you copy them) or `spotify:` URIs, one a line. A playlist gives its tracks, an album its tracks, an artist its top tracks and its releases, a track its own row. Each link gets its own cap (`maxItemsPerUrl`), and the run's cap sits on top (`maxItems`).
- **The play count on every track.** Spotify's all-time stream count comes with each track of a playlist, an album or an artist, beside the album, the release date, the duration, the explicit flag and the disc and track number.
- **Whole playlists, checked.** A playlist is read page after page in Spotify's own order until every item of Spotify's count is read: the free `list` row says COMPLETE with the count (a 421-track playlist in one page, measured 2026-10-23). A track the playlist lists twice is delivered once; podcast episodes are counted and skipped.
- **Playlist context on every track.** A playlist's tracks carry the playlist's name, owner and follower count and the date each track was added; an artist's list row carries its followers, monthly listeners and world rank.
- **Honest runs.** An id Spotify does not know is a free `not_found` row, checked twice; a link that is not Spotify a free `invalid` row. Every link gets a row.

### Who it's for

- **Music marketers and labels** — the tracks of the playlists that matter to an artist, with each track's play count and the playlist's followers, read again every week.
- **Playlist curators and researchers** — whole playlists with the date each track was added, the owner and the follower count, to follow what a playlist adds and drops.
- **Music data apps** — an artist's releases and top tracks, or an album's tracks, with release dates, durations, track numbers, covers and preview URLs.

### Quick start

**The four kinds of link, 10 rows each**

```json
{
  "startUrls": [
    "https://open.spotify.com/track/0VjIjW4GlUZAMYd2vXMi3b",
    "https://open.spotify.com/album/4yP0hdKOZPNshxUOjY0cZj",
    "https://open.spotify.com/artist/06HL4z0CvFAxyc27GXpf02",
    "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M"
  ],
  "maxItemsPerUrl": 10
}
```

**Every track of a playlist**

```json
{
  "startUrls": [
    "https://open.spotify.com/playlist/37i9dQZF1DX4UtSsGT1Sbe"
  ],
  "maxItemsPerUrl": 0
}
```

**An artist's whole discography (releases only)**

```json
{
  "startUrls": [
    "https://open.spotify.com/artist/1Xyo4u8uXC1ZmMpatF05PJ"
  ],
  "artistRows": "releases",
  "maxItemsPerUrl": 0
}
```

### Output

One row per track or release (and one free list row per link):

| field | meaning |
|---|---|
| `row_type` | `track` (one track, charged), `album` (one release of an artist, charged) or `list` (the link's row with the walk's verdict; free). |
| `input_index` | The 1-based position of the link this row answers in `startUrls`. |
| `input_value` | The link as you gave it. |
| `input_type` | What the link is: `playlist`, `album`, `artist` or `track` (empty for a value that is not a Spotify link). |
| `input_id` | The link's Spotify id (22 letters and digits). |
| `input_url` | The link on open.spotify.com, as a URL you can open. |
| `status` | A list row: `ok`, `not_found`, `invalid`, `duplicate`, `failed` or `not_read` (see the FAQ). A track or album row: `ok`. |
| `status_detail` | Why a list row is not `ok`, in a sentence. |
| `scraped_at` | When the row was read (UTC). |
| `position` | The row's place in the link's own list: the playlist's order, the album's order, the top-tracks rank (1-10), the releases' order (newest first); 1 for a track link. |
| `track_id` | The track's Spotify id. |
| `track_url` | The track on open.spotify.com. |
| `track_uri` | The track's Spotify URI (`spotify:track:<id>`). |
| `name` | The track's name; on an album row the release's name; on a list row the playlist's, album's, artist's or track's name. |
| `artists` | The track's artists, in Spotify's order; on an album row the artist of the link. |
| `artist_ids` | The Spotify ids of `artists`, in the same order. |
| `album_id` | The Spotify id of the track's album (or of the release, on an album row). |
| `album_url` | The album on open.spotify.com. |
| `album_name` | The album's name. |
| `album_type` | `album`, `single`, `ep` or `compilation`, when the answer names it (an album's tracks, an artist's top tracks and releases, a track link). |
| `label` | The record label, on an album's tracks and on an album link's list row. |
| `release_date` | The album's release date: `YYYY-MM-DD`, or `YYYY-MM` / `YYYY` when Spotify knows only the month or the year. |
| `duration_ms` | The track's length in milliseconds. |
| `explicit` | True when Spotify marks the track explicit. |
| `disc_number` | The disc the track is on (1 for most albums; empty on a track link). |
| `track_number` | The track's number on its disc. |
| `play_count` | Spotify's play count of the track (all-time streams; Spotify shows 0 until a track passes 1,000). |
| `preview_url` | The 30-second preview's URL from the link's embed player: every track of an album, an artist's top tracks, a track link, and the first 100 tracks of a playlist (later tracks have none). Never the audio file itself. |
| `cover_url` | The album cover (the largest size, 640 px); on a list row the playlist's, album's or artist's image. |
| `playable` | False when Spotify marks the track or release not playable for the reader's country. |
| `added_at` | A playlist's track: when it was added to the playlist (UTC). |
| `total_tracks` | An album row: the release's number of tracks; an album link's list row: the album's. |
| `playlist_id` | A playlist's track: the playlist's id. |
| `playlist_name` | A playlist's track: the playlist's name. |
| `playlist_owner` | A playlist's track: the owner's display name (`Spotify` for Spotify's own playlists). |
| `playlist_owner_id` | A playlist's track: the owner's Spotify user id. |
| `playlist_followers` | A playlist's track: the playlist's followers. |
| `owner` | A playlist's list row: the owner's display name. |
| `owner_id` | A playlist's list row: the owner's Spotify user id. |
| `followers` | A list row: the playlist's or the artist's followers. |
| `monthly_listeners` | An artist's list row: Spotify's monthly listeners. |
| `world_rank` | An artist's list row: Spotify's world rank, when the artist has one. |
| `items_count` | A list row: Spotify's own count of the link's list (a playlist's items, an album's tracks, an artist's top tracks and releases). |
| `items_delivered` | A list row: the track and release rows delivered for the link. |
| `pages_read` | A list row: the pages of the list read. |
| `repeats_skipped` | A list row: tracks skipped because the same list already listed them (a playlist can hold a track twice). |
| `other_items_skipped` | A list row: items that are not tracks (podcast episodes, local files, items Spotify no longer serves): counted, not delivered. |
| `verdict` | A list row: `COMPLETE` (every item of Spotify's count, or Spotify's own end of the list), `CAPPED` (your limit) or `PARTIAL` (a refusal, an empty page below the count, or the time limit stopped it). |
| `verdict_detail` | A list row: the verdict in a sentence, with the counts. |

Example record:

```json
{
  "row_type": "track",
  "input_index": 2,
  "input_value": "https://open.spotify.com/album/4yP0hdKOZPNshxUOjY0cZj",
  "input_type": "album",
  "input_id": "4yP0hdKOZPNshxUOjY0cZj",
  "input_url": "https://open.spotify.com/album/4yP0hdKOZPNshxUOjY0cZj",
  "status": "ok",
  "status_detail": null,
  "scraped_at": "2026-10-23T06:39:05Z",
  "position": 1,
  "track_id": "6b5P51m8xx2XA6U7sdNZ5E",
  "track_url": "https://open.spotify.com/track/6b5P51m8xx2XA6U7sdNZ5E",
  "track_uri": "spotify:track:6b5P51m8xx2XA6U7sdNZ5E",
  "name": "Alone Again",
  "artists": [
    "The Weeknd"
  ],
  "artist_ids": [
    "1Xyo4u8uXC1ZmMpatF05PJ"
  ],
  "album_id": "4yP0hdKOZPNshxUOjY0cZj",
  "album_url": "https://open.spotify.com/album/4yP0hdKOZPNshxUOjY0cZj",
  "album_name": "After Hours",
  "album_type": "album",
  "label": "Republic Records",
  "release_date": "2020-03-20",
  "duration_ms": 250053,
  "explicit": true,
  "disc_number": 1,
  "track_number": 1,
  "play_count": 233244354,
  "preview_url": "https://p.scdn.co/mp3-preview/77e54c6064335e259d0f571768af5f96c22304d4",
  "cover_url": "https://i.scdn.co/image/ab67616d0000b2738863bc11d2aa12b54f5aeb36",
  "playable": true,
  "added_at": null,
  "total_tracks": null,
  "playlist_id": null,
  "playlist_name": null,
  "playlist_owner": null,
  "playlist_owner_id": null,
  "playlist_followers": null,
  "owner": null,
  "owner_id": null,
  "followers": null,
  "monthly_listeners": null,
  "world_rank": null,
  "items_count": null,
  "items_delivered": null,
  "pages_read": null,
  "repeats_skipped": null,
  "other_items_skipped": null,
  "verdict": null,
  "verdict_detail": null
}
```

### Pricing

**Pay for the tracks and releases a run delivers**, plus one run start; no platform usage is billed to you. The row price falls with your Apify plan.

| event | unit | Free | Starter | Scale | Business |
|---|---|---|---|---|---|
| Track or release (`result`) | per 1,000 | $1.00 | $0.85 | $0.70 | $0.50 |
| Run start (`start`) | per run | $0.001 | $0.001 | $0.001 | $0.001 |

A track or release row is **$1.00 per 1,000** on the Free plan ($0.001 a row). Each run that delivers a charged row also pays the **run start, $0.001 once**; a run that delivers no charged row pays nothing at all. So one playlist of 100 tracks costs $0.101 on the Free plan, and several links in one run share one start. The free `list` row of every link, a value that is not a Spotify link (`invalid`), an id Spotify does not know (`not_found`), a repeated link (`duplicate`), a link left at the cap or the time limit (`not_read`) and a refusal the run could not pass (`failed`) are never charged. A run that stops early (a timeout, an abort) is charged for the rows it delivered. `maxItems` counts the charged rows; before the first request the log names the price of each row at your plan and the most the run can cost. Enterprise plans have their own rates: the Actor's Pricing tab shows the price for your plan.

### Usage patterns

- **Links** — `startUrls` takes open.spotify.com links of playlists (`/playlist/<id>`), albums (`/album/<id>`), artists (`/artist/<id>`) and tracks (`/track/<id>`), with or without `/intl-xx/`, `/embed/` and `?si=`, and `spotify:<kind>:<id>` URIs. Podcasts, users and short spotify.link links are not read (a free `invalid` row says so).
- **What a row is** — `row_type` = `track`: one track, in the link's own order (`position`). `row_type` = `album`: one release of an artist (albums, singles, EPs and compilations, newest first). `row_type` = `list`: the free row of one link — its name, owner or followers, `items_count` (Spotify's own count), `items_delivered`, `pages_read`, `repeats_skipped`, `other_items_skipped`, the `verdict` with its `verdict_detail`, and the `status` with its reason.
- **How far a link goes** — `maxItemsPerUrl` (default 100; 0 = every track or release the link serves) stops each playlist, album or artist after that many rows. A playlist or an album is read to Spotify's count; an artist gives its top tracks (Spotify lists up to 10) and then its releases, as `artistRows` chooses. `maxItems` caps the charged rows of the whole run.

### Input configuration

| field | type | default | what it does |
|---|---|---|---|
| `startUrls` | `array` |  | Spotify links to read, one a line: a playlist (`https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M`: its tracks), an album (its tracks), an artist (its top tracks and its releases) or a track (its own row). Links with `/intl-xx/`, `/embed/` or `?si=` and `spotify:track:<id>` URIs work too. A link that is not a Spotify playlist, album, artist or track (a podcast, a user, a short spotify.link) gets a free `invalid` row; a link given twice a free `duplicate` row. |
| `maxItemsPerUrl` | `integer` | `100` | Stop each playlist, album or artist after this many rows (tracks, or an artist's top tracks and releases together). 0 = every track or release the link serves. A track link is one row. |
| `artistRows` | `both` / `top_tracks` / `releases` | `"both"` | What an artist link gives: its top tracks (up to 10, Spotify's own list) and then its releases (albums, singles, EPs and compilations, newest first), the top tracks only, or the releases only. |
| `maxItems` | `integer` | `0` | Stop the whole run after this many track and release rows (the charged rows). 0 = no run cap; each link still stops at its own limit above. |

### Errors

**A run does not fail because of your input.** When an input cannot be used — a date that is not a date, an id in the wrong form, two settings that contradict each other — the run ends **Succeeded**, charges nothing, and says what to change:

- the status message starts with `INPUT REJECTED`;
- the dataset holds one row, `{"error": true, "code": "…", "message": "…"}`, and no results;
- the key-value store record `ERROR` holds the same object.

From code, check `error` on the first row before reading results.

A value that is not a Spotify playlist, album, artist or track link (a podcast, a user page, a short spotify.link link) is not an error: it gets one free `list` row with `status` invalid that says why, and the run goes on with the others. A run that ends **Failed** is a fault on our side, never your input; it charges nothing, and we are alerted.

### FAQ

**Which status is which?**

A list row's `status` is `ok` (rows served), `not_found` (Spotify has no playlist, album, artist or track with that id; checked on two connections), `invalid` (an empty value, or a value that is not a Spotify playlist, album, artist or track link), `duplicate` (the same link again in the input: read once), `failed` (Spotify refused every try; free) or `not_read` (left at `maxItems`, the charge limit or the run's time limit). A track or album row's `status` is `ok`.

**Does it give the popularity score or the ISRC?**

No. Spotify serves the popularity score and the ISRC through its developer Web API, which refuses a logged-out reader (measured 2026-10-23); the web player serves the play count (all-time streams) instead, and that is on every track row.

**Does every track have a preview URL?**

Every track of an album, an artist's top tracks and a track link have one when Spotify offers a preview. A playlist's embed player lists its first 100 tracks, so later tracks of a long playlist have no preview URL. The actor never downloads the audio.

**Does it need a Spotify account or API key?**

No. Everything is read from Spotify's public pages and its web player, logged out.

### Integration

#### JavaScript

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('hyperbach/spotify-scraper').call({"startUrls": ["https://open.spotify.com/track/0VjIjW4GlUZAMYd2vXMi3b", "https://open.spotify.com/album/4yP0hdKOZPNshxUOjY0cZj", "https://open.spotify.com/artist/06HL4z0CvFAxyc27GXpf02", "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M"], "maxItemsPerUrl": 10});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

#### Python

```python
from apify_client import ApifyClient
client = ApifyClient('YOUR_TOKEN')
run = client.actor('hyperbach/spotify-scraper').call(run_input={'startUrls': ['https://open.spotify.com/track/0VjIjW4GlUZAMYd2vXMi3b', 'https://open.spotify.com/album/4yP0hdKOZPNshxUOjY0cZj', 'https://open.spotify.com/artist/06HL4z0CvFAxyc27GXpf02', 'https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M'], 'maxItemsPerUrl': 10})
items = client.dataset(run['defaultDatasetId']).list_items().items
```

#### CLI

```bash
apify call hyperbach/spotify-scraper --input '{"startUrls": ["https://open.spotify.com/track/0VjIjW4GlUZAMYd2vXMi3b", "https://open.spotify.com/album/4yP0hdKOZPNshxUOjY0cZj", "https://open.spotify.com/artist/06HL4z0CvFAxyc27GXpf02", "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M"], "maxItemsPerUrl": 10}'
```

#### REST

```bash
curl -X POST "https://api.apify.com/v2/acts/hyperbach~spotify-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H 'Content-Type: application/json' -d '{"startUrls": ["https://open.spotify.com/track/0VjIjW4GlUZAMYd2vXMi3b", "https://open.spotify.com/album/4yP0hdKOZPNshxUOjY0cZj", "https://open.spotify.com/artist/06HL4z0CvFAxyc27GXpf02", "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M"], "maxItemsPerUrl": 10}'
```

### Support

apify@hyperbach.com

*This page is generated from the Actor's schemas and a live sample — it cannot describe a field the Actor does not have.*

# Actor input Schema

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

Spotify links to read, one a line: a playlist (`https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M`: its tracks), an album (its tracks), an artist (its top tracks and its releases) or a track (its own row). Links with `/intl-xx/`, `/embed/` or `?si=` and `spotify:track:<id>` URIs work too. A link that is not a Spotify playlist, album, artist or track (a podcast, a user, a short spotify.link) gets a free `invalid` row; a link given twice a free `duplicate` row.

## `maxItemsPerUrl` (type: `integer`):

Stop each playlist, album or artist after this many rows (tracks, or an artist's top tracks and releases together). 0 = every track or release the link serves. A track link is one row.

## `artistRows` (type: `string`):

What an artist link gives: its top tracks (up to 10, Spotify's own list) and then its releases (albums, singles, EPs and compilations, newest first), the top tracks only, or the releases only.

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

Stop the whole run after this many track and release rows (the charged rows). 0 = no run cap; each link still stops at its own limit above.

## Actor input object example

```json
{
  "startUrls": [
    "https://open.spotify.com/track/0VjIjW4GlUZAMYd2vXMi3b",
    "https://open.spotify.com/album/4yP0hdKOZPNshxUOjY0cZj",
    "https://open.spotify.com/artist/06HL4z0CvFAxyc27GXpf02",
    "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M"
  ],
  "maxItemsPerUrl": 10,
  "artistRows": "both",
  "maxItems": 50
}
```

# Actor output Schema

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

All scraped records in the default dataset. One row per track or release (and one free list row per link):

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

How the run went: rows charged, free rows, links by status, the walk per link (rows delivered, pages read, repeats and other items skipped, Spotify's count, the verdict), the source counters (calls, served, refused, exits, rotations, tokens, bytes) and the memory watch.

# 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/track/0VjIjW4GlUZAMYd2vXMi3b",
        "https://open.spotify.com/album/4yP0hdKOZPNshxUOjY0cZj",
        "https://open.spotify.com/artist/06HL4z0CvFAxyc27GXpf02",
        "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M"
    ],
    "maxItemsPerUrl": 10,
    "maxItems": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("hyperbach/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/track/0VjIjW4GlUZAMYd2vXMi3b",
        "https://open.spotify.com/album/4yP0hdKOZPNshxUOjY0cZj",
        "https://open.spotify.com/artist/06HL4z0CvFAxyc27GXpf02",
        "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M",
    ],
    "maxItemsPerUrl": 10,
    "maxItems": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("hyperbach/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/track/0VjIjW4GlUZAMYd2vXMi3b",
    "https://open.spotify.com/album/4yP0hdKOZPNshxUOjY0cZj",
    "https://open.spotify.com/artist/06HL4z0CvFAxyc27GXpf02",
    "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M"
  ],
  "maxItemsPerUrl": 10,
  "maxItems": 50
}' |
apify call hyperbach/spotify-scraper --silent --output-dataset

```

## MCP server setup

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