# Spotify Songs Scraper (`maximedupre/spotify-songs-scraper`) Actor

Search public Spotify tracks with one or more keywords and choose the number of tracks per keyword. Get structured rows with track, artist, album, cover art, duration, explicit status, playability, availability, and Spotify links.

- **URL**: https://apify.com/maximedupre/spotify-songs-scraper.md
- **Developed by:** [Maxime Dupré](https://apify.com/maximedupre) (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 $1.75 / 1,000 tracks

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

### 🎵 Find public Spotify tracks by keyword

For music researchers, playlist planners, and developers, this Actor searches public Spotify tracks from one or more keywords and saves structured track rows. You get track and artist details, album context, cover art, duration, explicit status, playability, availability, and Spotify links in one dataset.

- Search a broad music phrase with [**Spotify Songs Scraper**](https://apify.com/maximedupre/spotify-songs-scraper/examples/spotify-songs-scraper) and save matching track rows.
- Run [**Spotify Music Search**](https://apify.com/maximedupre/spotify-songs-scraper/examples/spotify-music-search) for a music phrase and collect Spotify track details.
- Use [**Spotify Track Search**](https://apify.com/maximedupre/spotify-songs-scraper/examples/spotify-track-search) to find tracks for a specific song or style.
- Try [**Spotify Song Search**](https://apify.com/maximedupre/spotify-songs-scraper/examples/spotify-song-search) when you need song titles, artists, and album context.
- Use [**Spotify Songs**](https://apify.com/maximedupre/spotify-songs-scraper/examples/spotify-songs) to build a structured track list from a keyword.

#### 🎧 Spotify track rows

Each saved row keeps the submitted keyword with the track it found. Track identity, artist profiles, album details, cover-art links, duration, explicit status, and availability stay together for later review or data work.

#### ▶️ Search public Spotify tracks

Add one or more keywords and start a run. Each keyword is searched separately. Set `maxResultsPerKeyword` to stop each search after a chosen number. Leave it empty to return all available results until the source is exhausted. When the same source track matches more than one keyword, the first eligible match is saved and later matches are ignored. Open the default dataset to read the rows or use its API link.

#### ⚙️ Input

**Input fields**

`keywords` is required. `maxResultsPerKeyword` is optional.

| Field | Type | What it does |
| --- | --- | --- |
| `keywords` | array of strings | Adds one or more words or phrases for separate Spotify track searches. |
| `maxResultsPerKeyword` | integer | Limits saved tracks for each keyword. Leave it empty to return all available results until the source is exhausted. |

**Example input**

This example uses the public input from a successful current-beta run.

```json
{
  "keywords": [
    "jazz piano"
  ]
}
```

#### 🧾 Output

**Run output**

| Field | Type | What it does |
| --- | --- | --- |
| `tracks` | string link | Opens the returned track rows in the default dataset. |

The default dataset uses one row shape for saved tracks. The dotted paths below show nested fields.

**Dataset row fields**

| Field | Type | What it does |
| --- | --- | --- |
| `keyword` | string | Shows the keyword linked to the saved track. |
| `track` | object | Holds the track title, stable identity, and public links. |
| `track.id` | string | Shows the stable Spotify track ID. |
| `track.title` | string | Shows the track title. |
| `track.spotifyUrl` | URL string | Links to the canonical Spotify track page. |
| `track.webUrl` | URL string | Links to the public web page for the track. |
| `artists` | array of objects | Lists the artists linked to the track. |
| `artists[].id` | string | Shows the stable Spotify artist ID. |
| `artists[].name` | string | Shows the artist name. |
| `artists[].spotifyUrl` | URL string | Links to the canonical Spotify artist profile. |
| `artists[].webUrl` | URL string | Links to the public web page for the artist. |
| `artists[].isVerified` | boolean | Shows the public artist verification flag when available. |
| `album` | object | Holds album identity, name, and release date when available. |
| `album.id` | string | Shows the stable Spotify album ID. |
| `album.name` | string | Shows the album name. |
| `album.releaseDate` | string | Shows the public album release date when available. |
| `coverArt` | array of objects | Lists album cover image links and available sizes. |
| `coverArt[].url` | URL string | Links to one album cover image. |
| `coverArt[].width` | integer | Shows the image width in pixels when available. |
| `coverArt[].height` | integer | Shows the image height in pixels when available. |
| `durationMs` | integer | Shows the track duration in milliseconds. |
| `isExplicit` | boolean | Shows whether the track is marked as explicit. |
| `availability` | object | Holds playability and source availability flags. |
| `availability.isPlayable` | boolean | Shows whether Spotify reports that the track can be played. |
| `availability.isAvailable` | boolean | Shows whether the track is available from the source. |

**Genuine current-beta row**

This is a full row from the successful current-beta run that used the example input above.

```json
{
  "keyword": "jazz piano",
  "track": {
    "id": "1YQWosTIljIvxAgHWTp7KP",
    "title": "Take Five",
    "spotifyUrl": "https://open.spotify.com/track/1YQWosTIljIvxAgHWTp7KP",
    "webUrl": "https://open.spotify.com/track/1YQWosTIljIvxAgHWTp7KP"
  },
  "artists": [
    {
      "id": "4iRZAbYvBqnxrbs6K25aJ7",
      "name": "The Dave Brubeck Quartet",
      "spotifyUrl": "https://open.spotify.com/artist/4iRZAbYvBqnxrbs6K25aJ7",
      "webUrl": "https://open.spotify.com/artist/4iRZAbYvBqnxrbs6K25aJ7"
    }
  ],
  "album": {
    "id": "0nTTEAhCZsbbeplyDMIFuA",
    "name": "Time Out",
    "releaseDate": "1959-12-14T00:00:00Z"
  },
  "coverArt": [
    {
      "url": "https://image-cdn-fa.spotifycdn.com/image/ab67616d00001e02b6bd44cf06bf8f4d5ce1e080",
      "width": 300,
      "height": 300
    },
    {
      "url": "https://image-cdn-fa.spotifycdn.com/image/ab67616d00004851b6bd44cf06bf8f4d5ce1e080",
      "width": 64,
      "height": 64
    },
    {
      "url": "https://image-cdn-fa.spotifycdn.com/image/ab67616d0000b273b6bd44cf06bf8f4d5ce1e080",
      "width": 640,
      "height": 640
    }
  ],
  "durationMs": 328831,
  "isExplicit": false,
  "availability": {
    "isPlayable": true,
    "isAvailable": true
  }
}
```

#### 💳 Pricing

This Actor uses pay-per-event pricing. A track event covers each track saved to the default dataset. Check the Apify pricing panel for the current tier price.

#### 🔌 Integrations

Read the returned rows in the Apify dataset or through its API link. You can export the structured dataset in the formats offered by Apify.

https://www.youtube.com/watch?v=bNACk1\_S\_6w\&list=PLObrtcm1Kw6MUrlLNDbK9QRg8VDJg0gOW\&index=4

#### ❓ FAQ

##### What happens when the same track matches more than one keyword?

The Actor saves the first eligible match and ignores later matches for the same source track. The saved row keeps the keyword linked to that first match.

##### What does leaving Results per keyword empty do?

It returns all available results until the source is exhausted. Set a positive number when you want each keyword search to stop earlier.

##### Can I submit more than one keyword?

Yes. Add several values to `keywords`. Each value is searched separately, and each saved row shows the keyword linked to it.

##### Which fields are in a track row?

Rows include track IDs and links, artist IDs and profiles, album details, cover-art links, duration, explicit status, playability, and availability.

##### Does this Actor search playlists or albums?

Tracks are the primary search target. Album and artist data is context for each track, so this Actor does not search playlists, albums, artists, or user profiles as primary targets.

##### Can I download audio or create playlists?

No. The Actor returns public track data and links. It does not download audio, create or edit playlists, or provide lyrics or audio analysis.

##### Can I use the returned data through an API?

Yes. The returned track data is available in a structured Apify dataset for download and API use.

### 📝 Changelog

**0.0: Initial release**

### 🆘 Support

For issues, questions, or feature requests, [file a ticket](https://console.apify.com/actors/maximedupre~spotify-songs-scraper/issues) and I'll fix or implement it in less than 24h 🫡

### 🔗 Related Actors

- [Spotify Downloader](https://apify.com/maximedupre/spotify-downloader) - Download metadata and media links for a track media workflow.
- [YouTube Music Scraper](https://apify.com/maximedupre/youtube-music-scraper) - Search another public music source for songs, albums, artists, and playlists.
- [SoundCloud Scraper](https://apify.com/maximedupre/soundcloud-scraper) - Collect public tracks and related SoundCloud data for cross-source research.
- [Billboard](https://apify.com/maximedupre/billboard) - Compare song or album entries with current or historical chart ranks.
- [YouTube Music Downloader](https://apify.com/maximedupre/youtube-music-downloader) - Save audio from direct public YouTube Music or YouTube links.

**Made with ❤️ by Maxime Dupré**

# Actor input Schema

## `keywords` (type: `array`):

Add one or more words or phrases. The Actor searches each value separately and shows the keyword linked to each saved track.

## `maxResultsPerKeyword` (type: `integer`):

Set the number of tracks to save for each keyword. Leave this empty to return all available results until the source is exhausted.

## Actor input object example

```json
{
  "keywords": [
    "jazz piano",
    "ambient study"
  ],
  "maxResultsPerKeyword": 25
}
```

# Actor output Schema

## `tracks` (type: `string`):

Link to the returned Spotify track rows in the default dataset.

# 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 = {
    "keywords": [
        "jazz piano"
    ],
    "maxResultsPerKeyword": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("maximedupre/spotify-songs-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 = {
    "keywords": ["jazz piano"],
    "maxResultsPerKeyword": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("maximedupre/spotify-songs-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 '{
  "keywords": [
    "jazz piano"
  ],
  "maxResultsPerKeyword": 10
}' |
apify call maximedupre/spotify-songs-scraper --silent --output-dataset

```

## MCP server setup

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