# SoundCloud Scraper — Tracks, Artists, Playlists & Comments (`teodor_banea/soundcloud-scraper`) Actor

Export public SoundCloud tracks, artists, playlists, albums, trending charts and comments: plays, likes, reposts, comments, genre, tags, ISRC, label and release data. Search beyond the 300-result cap, artist catalogs, playlists with all tracks. No login, no API key.

- **URL**: https://apify.com/teodor_banea/soundcloud-scraper.md
- **Developed by:** [Banea Teodor](https://apify.com/teodor_banea) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 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.

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

## SoundCloud Scraper — Tracks, Artists, Playlists & Comments

### What does SoundCloud Scraper do?

SoundCloud Scraper exports public data from [SoundCloud](https://soundcloud.com): **tracks** from a keyword search (with genre, date, duration and license filters), **artists**, **playlists and albums**, **whole artist catalogs**, **SoundCloud's trending charts** (all music and 19 genres) and **track comments**. Every track comes with plays, likes, reposts, comments and downloads, genre and tags, upload / posted / release dates, and the release metadata labels fill in: ISRC, UPC, label, publisher, writer / composer, album and P-line.

No login, no SoundCloud account, no API key and no browser needed.

### Why use this Actor?

- **More than 300 search results.** SoundCloud stops every search at 300 results. When you ask for more, the Actor splits a track search by posted date, genre and duration automatically and removes the duplicates — e.g. 1,000 different "techno" tracks posted in the last week.
- **Release metadata for music research.** ISRC, UPC / EAN, label, publisher, writer / composer, album, release title, P-line, explicit flag, buy link — the fields A\&R, label and rights teams need, as clean columns.
- **Clean, typed rows.** Counters are integers (`null` when the artist hides them, never a fake 0), dates are ISO 8601 UTC, tags are a real list (multi-word tags kept together), descriptions are plain text without HTML.
- **Complete lists.** Artist catalogs, playlists ("Include playlist tracks" delivers every track, not only the first five) and comments are read to the end — 400 comments on a 400-comment track.
- **Privacy-minded by default.** Artist rows carry username, counters, verification, Pro tier and country; name, city, bio and links only when you switch them on. E-mail addresses are never delivered.

### How much does it cost?

You pay **$0.005 per run** plus **$1.50 per 1,000 rows** (tracks, artists, playlists or comments). Platform usage and proxy are included.

| Run | Rows | Cost |
|---|---|---|
| 30 "lofi hip hop" tracks (the prefilled input) | 30 | $0.05 |
| 1,000 "techno" tracks posted in the last week (split searches) | 1,000 | $1.51 |
| The all-music trending chart + 5 genre lists | ~340 | ~$0.52 |
| Every track of 10 artists posted since 2025 | ~500 | ~$0.76 |
| All comments of a track with 1,000 comments | 1,000 | $1.51 |
| 100 track / artist / playlist URLs | 100 | $0.155 |

### Input

| Field | Description | Example |
|---|---|---|
| `mode` | `search`, `startUrls`, `artistCatalog`, `trending` or `comments`. | `"search"` |
| `searchQueries` | Words to search for, one search per line. | `["lofi hip hop"]` |
| `searchType` | `tracks`, `users` (artists), `playlists` or `albums`. | `"tracks"` |
| `genreOrTag` | Track searches: keep one genre or tag. | `"techno"` |
| `createdWithin` | Track searches: `any`, `lastHour`, `lastDay`, `lastWeek`, `lastMonth`, `lastYear` (SoundCloud's posted date). | `"lastWeek"` |
| `duration` / `license` | Track searches: `short` / `medium` / `long` / `epic`; `toShare`, `toUseCommercially`, `toModifyCommercially`, `ccBy`. | `"long"` |
| `maxResultsPerQuery` | Results per query (playlists / albums for those searches); above 300 track searches are split automatically. 0 = all. | `1000` |
| `startUrls` | Track, artist, playlist / album or `discover/sets/trending-by-genre:<genre>` URLs (up to 1,000). | `["https://soundcloud.com/forss/flickermood"]` |
| `includePlaylistTracks` | Also deliver every track of each playlist / album (with `sourcePlaylistId`) — for playlist / album URLs in Start URLs and for playlist / album searches. The tracks count toward `maxResults`: playlists are read one at a time, tracks in playlist order, so a playlist is complete only when `maxResults` leaves room for all its tracks (the status names any playlist cut short). | `false` |
| `artistUrls` | Artist URLs or usernames for the artist catalog (up to 1,000). | `["forss"]` |
| `uploadedAfter` | Artist catalog: stop at the first track posted before this date or period. | `"2025-01-01"` |
| `maxTracksPerArtist` | Newest tracks per artist; 0 = all. | `200` |
| `trendingGenres` | `all-music` (chart, ~100) and / or genres (`house`, `hip-hop`, `pop`… ~50 each). | `["all-music", "house"]` |
| `trackUrls` / `maxCommentsPerTrack` | Comments mode: tracks and comments per track (0 = all). | `500` |
| `includeArtistDetails` | Add full name, city, bio and web profile links to artist rows. | `false` |
| `maxResults` | Rows of the whole run; 0 = all (capped at 10,000). | `200` |

#### Which modes give a complete listing?

- **Artist catalog, playlists with "Include playlist tracks" (when Maximum results leaves room for all their tracks), comments, start URLs** — complete: every public item, read to the last page. An artist's track count on SoundCloud includes private tracks, so a catalog can be shorter than that number.
- **Search** — SoundCloud ranks results by relevance and returns at most 300 per search. Splitting (date windows + genres) reaches far more, but search is a discovery tool, not a census: very common words have millions of matches.
- **Trending** — a snapshot of SoundCloud's current trending lists (about 100 tracks for all music, about 50 per genre), refreshed by SoundCloud during the day.

### Output

Every row has a `rowType` — `track`, `user` (artist), `playlist` (playlists and albums) or `comment` — and every key of its type; missing values are `null`. The dataset tabs *Tracks*, *Artists*, *Playlists & albums* and *Comments* show each type as a table. Example track row (fictitious):

```json
{
    "rowType": "track",
    "trackId": 1234567890,
    "urn": "soundcloud:tracks:1234567890",
    "title": "Example Track (Original Mix)",
    "url": "https://soundcloud.com/example-artist/example-track",
    "artistId": 987654321,
    "artistUsername": "Example Artist",
    "artistUrl": "https://soundcloud.com/example-artist",
    "artistVerified": true,
    "artistFollowers": 125000,
    "createdAt": "2026-10-21T14:30:00.000Z",
    "postedAt": "2026-10-21T15:00:00.000Z",
    "releaseDate": "2026-10-24T00:00:00.000Z",
    "durationSec": 391,
    "genre": "Techno",
    "tags": ["melodic techno", "berlin"],
    "descriptionText": "Out now on Example Records.",
    "playCount": 48210,
    "likeCount": 1530,
    "repostCount": 212,
    "commentCount": 87,
    "downloadCount": 64,
    "license": "all-rights-reserved",
    "downloadable": false,
    "labelName": "Example Records",
    "artistCredit": "Example Artist, Example Guest",
    "isrc": "XX0002600001",
    "upc": "0000000000000",
    "publisher": "Example Publishing",
    "writerComposer": "EXAMPLE, Jane",
    "albumTitle": "Example Album",
    "releaseTitle": "Example EP",
    "pLine": "℗ 2026 Example Records",
    "explicit": false,
    "policy": "ALLOW",
    "monetizationModel": "NOT_APPLICABLE",
    "purchaseUrl": "https://example.com/buy",
    "purchaseTitle": "Buy on Example Store",
    "artworkUrl": "https://i1.sndcdn.com/artworks-example-t500x500.jpg",
    "waveformUrl": "https://wave.sndcdn.com/example_m.json",
    "sourceMode": "search",
    "sourceQuery": "melodic techno",
    "sourcePlaylistId": null,
    "trendingGenre": null,
    "trendingRank": null,
    "scrapedAt": "2026-10-23T12:00:00.000Z"
}
```

- **Artist rows**: `userId`, `username`, `url`, `avatarUrl`, `followers`, `followings`, `trackCount`, `playlistCount`, `likeCount`, `verified`, `proTier` (`none`, `pro`, `proUnlimited`, `creatorMidTier`), `countryCode`; `fullName`, `city`, `bio`, `webProfiles` (`[{network, url}]`) only with "Include artist details".
- **Playlist rows**: `playlistId`, `title`, `url`, `isAlbum`, `setType`, owner, `trackCount`, `durationSec`, `likeCount`, `repostCount`, `genre`, `tags`, `descriptionText`, `releaseDate`, `labelName`, `createdAt`, `publishedAt`, `artworkUrl`, `trackIds` (every track id, in order).
- **Comment rows**: `commentId`, `trackId`, `trackUrl`, `body`, `createdAt`, `timestampSec` (second of the track the comment was left at), `authorUserId`, `authorUsername`, `authorUrl`.

Notes: `createdAt` is the upload time, `postedAt` the time the track went public (the date SoundCloud shows, used by the date filter and the catalog date). `policy` (ALLOW / MONETIZE / SNIP / BLOCK) depends on the listener's country — runs on the Apify platform see it as from the US. Audio streams and downloads are not part of the output.

### Tips and tricks

- **Big searches**: set `maxResultsPerQuery` above 300 (e.g. 1,000) and a `createdWithin` window; the Actor splits the search by posted date, genre and duration, and the run log and the final status say how many searches were needed. When the splits run out before your limit, the status says so ("926 of 1,000 asked — SoundCloud's split searches returned no more"). Several specific queries ("melodic techno", "hard techno") reach more tracks than one broad word.
- **Label / A\&R research**: search with `genreOrTag` + `createdWithin: lastWeek`, then filter rows on `labelName`, `isrc` or `artistFollowers`.
- **Artist monitoring**: `artistCatalog` with `uploadedAfter` set to your last run date returns only the new tracks. Each run always delivers (and bills) one artist row per artist, even when the artist posted nothing new — so 50 artists checked daily cost 50 rows a day plus the new tracks.
- **Comments**: newest threads first, each reply right after its parent comment; `maxCommentsPerTrack` keeps big tracks cheap. A track with 50,000 comments takes about 250 requests to read in full.
- Problems (dead URLs, unavailable playlist tracks) are listed in the `ERRORS` record of the run's key-value store; dead URLs cost one quick request and no row.

### Scheduling

The Actor stores nothing in your account between runs. For a recurring feed, schedule a run with a matching window — e.g. a daily track search with `createdWithin: lastDay`, or a weekly artist catalog with `uploadedAfter: "7 days"` (each artist still gives one artist row per run) — and de-duplicate downstream by `trackId` / `commentId`.

### Integrations

Send the rows to Google Sheets, Airtable, Slack, a webhook or Zapier / Make with Apify integrations, or read them through the Apify API (JSON, CSV, Excel). Join tracks to artists on `artistId` = `userId` and comments to tracks on `trackId`.

### Personal data

Artist rows are reduced to public profile facts (username, counters, verification, Pro tier, country). Name, city, bio and links are opt-in. Comment authors and track artists are reduced to id, username and profile URL. E-mail addresses are removed from every text field and never delivered; follower / liker lists are not exported. Use the data in line with GDPR and SoundCloud's terms.

### Disclaimer

This Actor reads only public SoundCloud pages and data, without logging in. It is not affiliated with or endorsed by SoundCloud.

# Changelog

This Actor's version history is a separate document: https://apify.com/teodor_banea/soundcloud-scraper/changelog.md

# Actor input Schema

## `mode` (type: `string`):

Choose what the run collects. Search: tracks, artists, playlists or albums matching your words. Start URLs: the tracks, artists, playlists, albums or trending lists you paste. Artist catalog: every track of the artists you list. Trending: SoundCloud's trending charts. Comments: the comments of the tracks you list.

## `searchQueries` (type: `array`):

Enter the words to search for, one search per line. A result found by several queries is delivered once, under the first query (sourceQuery).

## `searchType` (type: `string`):

Choose what the search returns: tracks, artists (users), playlists or albums.

## `genreOrTag` (type: `string`):

Keep only tracks with this genre or tag (e.g. "techno", "Hip-hop & Rap"). Track searches only.

## `createdWithin` (type: `string`):

Keep only tracks posted within this period (SoundCloud's "posted" date, which can be later than the upload date for tracks made public later). Track searches only.

## `duration` (type: `string`):

Keep only tracks of this length: short (under 2 min), medium (2-10 min), long (10-30 min) or epic (over 30 min). Track searches only.

## `license` (type: `string`):

Keep only tracks with a Creative Commons license that allows this use. Track searches only.

## `maxResultsPerQuery` (type: `integer`):

Limit the results of each search query. Above 300, track searches are split automatically (by posted date and genre). Set to 0 for as many as SoundCloud gives.

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

Enter SoundCloud page URLs: tracks (https://soundcloud.com/artist/track), artists (https://soundcloud.com/artist), playlists and albums (https://soundcloud.com/artist/sets/name) or genre trending lists (https://soundcloud.com/discover/sets/trending-by-genre:house). Up to 1,000 per run.

## `includePlaylistTracks` (type: `boolean`):

Also deliver every track of each playlist / album as a track row (with sourcePlaylistId): for playlist and album URLs here and for playlist / album searches. Costs one row per track; the tracks count toward Maximum results.

## `artistUrls` (type: `array`):

Enter artist page URLs (https://soundcloud.com/artist) or usernames. Each gives one artist row plus the artist's tracks, newest first. Up to 1,000 per run.

## `uploadedAfter` (type: `string`):

Stop each artist's catalog at the first track posted before this date (YYYY-MM-DD) or period (e.g. "6 months").

## `maxTracksPerArtist` (type: `integer`):

Limit the tracks taken from each artist (newest first). Set to 0 for all.

## `trendingGenres` (type: `array`):

Choose the trending lists: all music (about 100 tracks) and / or a genre (about 50 tracks each). Each track carries its trendingGenre and trendingRank.

## `trackUrls` (type: `array`):

Enter the track URLs (https://soundcloud.com/artist/track) whose comments you want. Up to 1,000 per run.

## `maxCommentsPerTrack` (type: `integer`):

Limit the comments taken from each track. Set to 0 for all.

## `includeArtistDetails` (type: `boolean`):

Add the full name, city, bio and web profile links to artist rows (one extra request per artist). Off by default: artist rows carry username, counts, verification, Pro tier and country only.

## `maxResults` (type: `integer`):

Limit the rows of the whole run (tracks, artists, playlists and comments together). Set to 0 for all (capped at 10,000 per run).

## Actor input object example

```json
{
  "mode": "search",
  "searchQueries": [
    "lofi hip hop",
    "melodic techno"
  ],
  "searchType": "tracks",
  "genreOrTag": "techno",
  "createdWithin": "any",
  "duration": "any",
  "license": "any",
  "maxResultsPerQuery": 300,
  "startUrls": [
    "https://soundcloud.com/forss/flickermood",
    "https://soundcloud.com/discover/sets/trending-by-genre:house"
  ],
  "includePlaylistTracks": false,
  "artistUrls": [
    "https://soundcloud.com/forss"
  ],
  "uploadedAfter": "2025-01-01",
  "maxTracksPerArtist": 200,
  "trendingGenres": [
    "all-music"
  ],
  "trackUrls": [
    "https://soundcloud.com/forss/flickermood"
  ],
  "maxCommentsPerTrack": 500,
  "includeArtistDetails": false,
  "maxResults": 30
}
```

# Actor output Schema

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

Every row of the run as JSON.

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

Tracks: title, artist, dates, plays, likes, reposts, comments, genre, tags, release metadata.

## `artists` (type: `string`):

Artists: username, followers, tracks, verification, Pro tier, country.

## `playlists` (type: `string`):

Playlists and albums: owner, track count, duration, likes, reposts, track ids.

## `comments` (type: `string`):

Comments: track, text, time, second in the track, author.

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

The same rows as a CSV download.

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

URLs, artists or pages that could not be read. Only present when something went wrong.

# 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 = {
    "searchQueries": [
        "lofi hip hop"
    ],
    "startUrls": [
        "https://soundcloud.com/forss/flickermood"
    ],
    "maxResults": 30
};

// Run the Actor and wait for it to finish
const run = await client.actor("teodor_banea/soundcloud-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 = {
    "searchQueries": ["lofi hip hop"],
    "startUrls": ["https://soundcloud.com/forss/flickermood"],
    "maxResults": 30,
}

# Run the Actor and wait for it to finish
run = client.actor("teodor_banea/soundcloud-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 '{
  "searchQueries": [
    "lofi hip hop"
  ],
  "startUrls": [
    "https://soundcloud.com/forss/flickermood"
  ],
  "maxResults": 30
}' |
apify call teodor_banea/soundcloud-scraper --silent --output-dataset

```

## MCP server setup

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