# SoundCloud Charts, Search & Artist Catalog Scraper (`nimbryxo-studio/soundcloud-charts-search-and-artist-catalog`) Actor

Scrape SoundCloud without an API key: global and genre New & Hot charts, keyword search with real genre filters, full artist catalogs, playlist contents, comments, followers, engagement metrics, artwork, waveform and stream metadata.

- **URL**: https://apify.com/nimbryxo-studio/soundcloud-charts-search-and-artist-catalog.md
- **Developed by:** [Nimbryxo-studio](https://apify.com/nimbryxo-studio) (community)
- **Categories:** Social media, Automation, Developer tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.49 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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

## SoundCloud Charts, Search & Artist Catalog Scraper

Pull public SoundCloud data into one clean dataset: the current global New & Hot
chart, 20 genre trending lists, keyword search across tracks, artists, playlists and
albums, complete artist catalogs, playlist contents, track comments, and artist
followers. No SoundCloud account, cookie or API key is required.

### What this actor does

- **Search** tracks, users/artists, playlists or albums by keyword, with a real
  SoundCloud genre filter for tracks and playlists.
- **Charts** the global New & Hot list (up to 100 tracks) or one of 20 current
  genre trending lists (about 50 tracks each).
- **Artist catalog** exports the profile row plus uploaded tracks and, optionally,
  albums, playlists, top tracks and public web profiles.
- **URLs** resolves any public track, playlist/album or artist URL. Playlist URLs
  expand into every track, not just the first page. Artist URLs return the profile
  and uploaded tracks.
- **Comments** collects public comments for one or more tracks, including the
  commenter's profile fields and the time in the track.
- **Followers** collects an artist's followers or the accounts the artist follows.
- Empty fields are omitted from records. No `null`, blank strings or empty arrays
  are pushed.

### Output records

Every row has a `recordType`: `track`, `user`, `playlist` or `comment`. Existing
field names are preserved; the revamp adds fields beside them.

#### Track fields

| Field | Meaning |
|---|---|
| `recordType` | `track` |
| `title`, `url`, `trackId`, `urn` | Track identity and canonical page URL |
| `artist`, `artistUrl`, `artistId` | Uploader identity |
| `artistFollowers`, `artistVerified`, `artistCity`, `artistCountry`, `artistDescription` | Creator details when SoundCloud publishes them |
| `duration` | `M:SS` / `H:MM:SS` (unchanged legacy field) |
| `durationMs`, `durationSeconds` | Numeric duration |
| `playCount`, `likeCount`, `repostCount`, `commentCount`, `downloadCount` | Engagement snapshot |
| `genre`, `tags`, `description` | Uploader metadata when present |
| `uploadDate`, `lastModified`, `releaseDate` | ISO-8601 dates |
| `labelName`, `license`, `isrc`, `upc` | Release and rights metadata when present |
| `publisherArtist`, `albumTitle`, `writerComposer`, `explicit` | Publisher metadata when present |
| `streamable`, `downloadable`, `hasDownloadsLeft`, `policy`, `monetizationModel` | Source playback flags |
| `streamUrl` | Playable signed media URL when `resolveStreamUrls=true`; otherwise the stable API transcoding URL |
| `streamUrlApi` | Stable SoundCloud transcoding endpoint (not directly playable without a `client_id`) |
| `streamUrlProtocol`, `streamUrlMimeType`, `streamUrlPreset` | Stream format details |
| `streamUrlExpiresAt` | Expiry of the signed media URL (about two hours) |
| `streamUrlIsPreview` | `true` for a 30-second preview / `SNIP` track |
| `artworkUrl`, `artworkUrlOriginal` | Cover image at 500x500 and original size |
| `waveformUrl` | Waveform amplitude JSON (not an image) |
| `chartGenre`, `chartRank`, `chartScore`, `chartLastUpdated` | Chart context |
| `playlistId`, `playlistTitle`, `playlistUrl`, `playlistPosition` | Playlist context when a playlist is expanded |
| `sourceQuery`, `sourceType`, `sourceUrl` | What input produced the row |
| `scrapedAt` | ISO-8601 scrape time |

#### User / artist fields

`recordType=user`; keeps `title`, `url`, `trackId`, `artist`, `artistUrl`,
`playCount`, `likeCount`, `repostCount`, `description`, `artworkUrl`, `scrapedAt`.
Adds `userId`, `username`, `fullName`, `followersCount`, `followingsCount`,
`trackCount`, `playlistCount`, `commentsCount`, `verified`, `pro`, `city`,
`countryCode`, `lastModified`, `webProfiles`, `relationship` (followers mode),
`sourceArtistId`, `sourceArtistUsername`.

#### Playlist / album fields

`recordType=playlist`; keeps `title`, `url`, `trackId`, `artist`, `artistUrl`,
`duration`, `likeCount`, `repostCount`, `genre`, `description`, `uploadDate`,
`artworkUrl`, `scrapedAt`. Adds `playlistId`, `urn`, `trackCount`, `setType`,
`isAlbum`, `tags`, `releaseDate`, `lastModified`, `durationMs`, `labelName`.

#### Comment fields

`recordType=comment`; `commentId`, `body`, `createdAt`, `timestampMs`,
`timestampFormatted`, `trackId`, `trackTitle`, `trackUrl`, `userId`, `username`,
`userUrl`, `userFollowers`, `userCity`, `userCountry`, `scrapedAt`.

### Input

| Field | Type | Default | What it does |
|---|---|---|---|
| `mode` | select | `search` | `search`, `charts`, `artistTracks`, `byUrl`, `comments`, `followers` |
| `searchQueries` | string list | `[]` | One or more search keywords |
| `searchType` | select | `tracks` | `tracks`, `users`, `playlists`, `albums`, `all` |
| `chartGenre` | select | `all` | Global New & Hot or one of 20 genre trending lists |
| `searchGenre` | select | any genre | Real SoundCloud genre filter for track/playlist search |
| `sortBy` | select | `relevance` | `relevance`, `newest`, `mostPlayed`, `mostLiked` (client-side) |
| `minPlayCount`, `minLikeCount` | integer | `0` | Client-side thresholds after fetching |
| `artistUrls` | string list | `[]` | Artist URLs, usernames or numeric user IDs |
| `includeTracks` | boolean | `true` | Artist tracks |
| `includeAlbums` | boolean | `false` | Artist albums/EPs |
| `includePlaylists` | boolean | `false` | Artist playlists |
| `includeTopTracks` | boolean | `false` | Artist top tracks |
| `includeWebProfiles` | boolean | `false` | Public social/web profile links |
| `startUrls` | URL list | `[]` | Track, playlist or artist URLs / numeric track IDs |
| `includePlaylistTracks` | boolean | `true` | Expand every playlist track |
| `includeUserProfile` | boolean | `true` | Emit the profile row for artist URLs in `byUrl` |
| `trackUrls` | URL list | `[]` | Tracks for comments mode |
| `commentsSort` | select | `newest` | `newest`, `oldest`, `track-timestamp` |
| `relationship` | select | `followers` | `followers` or `followings` |
| `resolveStreamUrls` | boolean | `true` | Resolve signed playable stream URLs + expiry |
| `maxItems` | integer | `100` | Hard record cap (1-5000) |

### Examples

**Search tracks with a genre filter**

```json
{
  "mode": "search",
  "searchQueries": ["lofi", "ambient jazz"],
  "searchType": "tracks",
  "searchGenre": "Jazz & Blues",
  "maxItems": 100
}
```

**Global New & Hot chart**

```json
{ "mode": "charts", "chartGenre": "all", "maxItems": 100 }
```

**Trap trending list**

```json
{ "mode": "charts", "chartGenre": "trap", "maxItems": 50 }
```

**Full artist catalog**

```json
{
  "mode": "artistTracks",
  "artistUrls": ["https://soundcloud.com/chillhopdotcom"],
  "includeTracks": true,
  "includeAlbums": true,
  "includePlaylists": true,
  "maxItems": 500
}
```

**Expand a playlist**

```json
{
  "mode": "byUrl",
  "startUrls": ["https://soundcloud.com/chillhopdotcom/sets/chillhop-essentials-summer-2026"],
  "includePlaylistTracks": true,
  "maxItems": 300
}
```

**Track comments**

```json
{
  "mode": "comments",
  "trackUrls": ["https://soundcloud.com/user/track"],
  "commentsSort": "newest",
  "maxItems": 200
}
```

**Artist followers**

```json
{
  "mode": "followers",
  "artistUrls": ["https://soundcloud.com/chillhopdotcom"],
  "relationship": "followers",
  "maxItems": 500
}
```

### Charts: what is available

SoundCloud's current public chart surface is **New & Hot**, not the retired all-time
Top chart. The actor returns:

- the global New & Hot list (up to 100 tracks), and
- 20 current genre trending lists (about 50 tracks each).

The old per-genre chart endpoint and the all-time Top chart are no longer available
from SoundCloud's public API. Requests for the legacy `top` value are mapped to the
current global New & Hot list and the status message says so.

### Stream URLs, previews and rights

Stream metadata comes from SoundCloud's public transcodings. `streamUrl` is a
**signed** media URL and expires after about two hours; `streamUrlExpiresAt` records
the exact time. `streamUrlApi` is the stable API endpoint, but it is not playable on
its own without a `client_id`.

Not every track is fully playable: SoundCloud may return a 30-second preview
(`streamUrlIsPreview=true`), use DRM/encrypted transcodings, or disable downloads.
The actor reports the metadata it can see and never fabricates an audio file. This
actor does not download or rehost audio.

### Limitations

- Search returns at most **300 rows per query**. Use more queries or a genre filter
  to reach further.
- The all-time Top chart and regional/country charts are not available from the
  current public surface.
- Server-side BPM, duration, upload-date, license and access filters are not
  available on SoundCloud's public v2 search; the actor only exposes the real
  genre filter. `sortBy` and the minimum play/like thresholds are applied to the
  rows already fetched.
- SoundCloud does not publish a user join date or a user repost count in this API.
- BPM and musical key are not exposed for tracks.
- City/country, description, genre, tags, ISRC, UPC, label and release date are
  conditional; fields are omitted when SoundCloud does not provide them.
- Only public tracks, playlists and profiles are reachable. Private/unlisted
  content is out of scope.
- Huge follower lists can be expensive; use `maxItems` to cap them.

### FAQ

**Do I need a SoundCloud account or API key?** No. The actor reads the same public
pages and public v2 JSON the SoundCloud web player uses, with no login.

**Why is `streamUrl` sometimes missing?** SoundCloud may expose only encrypted/DRM
transcodings or a preview for that track. `streamUrlApi`, `policy` and the preview
flag still describe what is available.

**Why does a search stop at 300 rows?** That is SoundCloud's public search window
per query. Split the job into more queries or use `searchGenre` to partition it.

**Why is `waveformUrl` a JSON file?** SoundCloud's waveform field points to amplitude
JSON, not an image. It is kept under the existing field name for compatibility.

**Can I schedule monitoring?** Yes. Run the actor on a schedule and compare
`playCount`, `likeCount`, `repostCount` and `followersCount` snapshots. Monitoring
helpers are not part of this version; the dataset is designed for external diffing.

**Is this affiliated with SoundCloud?** No. This is an independent actor that reads
publicly visible data and is not endorsed by SoundCloud.

# Actor input Schema

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

Choose the intent. Keyword search, New & Hot charts, an artist catalog, specific URLs, track comments, or an artist's followers.

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

One or more keywords or artist names (mode=search). Example: lofi, techno, ambient jazz.

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

What kind of results to return (mode=search).

## `chartGenre` (type: `string`):

Global New & Hot returns up to 100 tracks. Genre values use SoundCloud's current trending-by-genre lists (about 50 tracks each).

## `searchGenre` (type: `string`):

Optional SoundCloud genre filter for track and playlist searches. Leave as any genre to search everything. This is a real SoundCloud filter, not a client-side guess.

## `sortBy` (type: `string`):

How to order the rows already fetched. SoundCloud search itself is relevance-ordered, so this is a client-side sort of that result set.

## `minPlayCount` (type: `integer`):

Drop track/playlist rows below this play count after fetching. 0 means no filter.

## `minLikeCount` (type: `integer`):

Drop track/playlist rows below this like count after fetching. 0 means no filter.

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

Artist profile URLs, usernames, or numeric user IDs. Used by artistTracks and followers modes.

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

Include the artist's uploaded tracks.

## `includeAlbums` (type: `boolean`):

Include the artist's albums/EPs as playlist rows.

## `includePlaylists` (type: `boolean`):

Include the artist's playlists as playlist rows.

## `includeTopTracks` (type: `boolean`):

Include SoundCloud's small top-tracks list for each artist.

## `includeWebProfiles` (type: `boolean`):

Add the artist's public social/web profile links to the profile row.

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

Track, playlist/album, or artist URLs. Numeric track IDs are also accepted. Used by mode=byUrl.

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

For playlist URLs, hydrate and emit every track (not just the first five).

## `includeUserProfile` (type: `boolean`):

For artist URLs in mode=byUrl, emit the profile row before the tracks.

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

Tracks whose public comments should be collected. Used by mode=comments.

## `commentsSort` (type: `string`):

How SoundCloud should order comments.

## `relationship` (type: `string`):

For mode=followers, collect the artist's followers or the accounts the artist follows.

## `resolveStreamUrls` (type: `boolean`):

Add a playable signed stream URL plus protocol, preview and expiry fields. Signed URLs expire after about two hours. Turn off for large runs if you only need the stable API endpoint.

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

Hard cap on dataset rows. SoundCloud search still returns at most 300 rows per query; charts and per-artist sections have their own source limits.

## Actor input object example

```json
{
  "mode": "search",
  "searchQueries": [
    "lofi"
  ],
  "searchType": "tracks",
  "chartGenre": "all",
  "searchGenre": "",
  "sortBy": "relevance",
  "minPlayCount": 0,
  "minLikeCount": 0,
  "artistUrls": [],
  "includeTracks": true,
  "includeAlbums": false,
  "includePlaylists": false,
  "includeTopTracks": false,
  "includeWebProfiles": false,
  "startUrls": [],
  "includePlaylistTracks": true,
  "includeUserProfile": true,
  "trackUrls": [],
  "commentsSort": "newest",
  "relationship": "followers",
  "resolveStreamUrls": true,
  "maxItems": 2
}
```

# Actor output Schema

## `soundcloud` (type: `string`):

Dataset containing every scraped SoundCloud track, artist, playlist/album and comment row.

# 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 = {
    "mode": "search",
    "searchQueries": [
        "lofi"
    ],
    "searchType": "tracks",
    "chartGenre": "all",
    "searchGenre": "",
    "sortBy": "relevance",
    "minPlayCount": 0,
    "minLikeCount": 0,
    "artistUrls": [],
    "includeTracks": true,
    "includeAlbums": false,
    "includePlaylists": false,
    "includeTopTracks": false,
    "includeWebProfiles": false,
    "startUrls": [],
    "includePlaylistTracks": true,
    "includeUserProfile": true,
    "trackUrls": [],
    "commentsSort": "newest",
    "relationship": "followers",
    "resolveStreamUrls": true,
    "maxItems": 2
};

// Run the Actor and wait for it to finish
const run = await client.actor("nimbryxo-studio/soundcloud-charts-search-and-artist-catalog").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 = {
    "mode": "search",
    "searchQueries": ["lofi"],
    "searchType": "tracks",
    "chartGenre": "all",
    "searchGenre": "",
    "sortBy": "relevance",
    "minPlayCount": 0,
    "minLikeCount": 0,
    "artistUrls": [],
    "includeTracks": True,
    "includeAlbums": False,
    "includePlaylists": False,
    "includeTopTracks": False,
    "includeWebProfiles": False,
    "startUrls": [],
    "includePlaylistTracks": True,
    "includeUserProfile": True,
    "trackUrls": [],
    "commentsSort": "newest",
    "relationship": "followers",
    "resolveStreamUrls": True,
    "maxItems": 2,
}

# Run the Actor and wait for it to finish
run = client.actor("nimbryxo-studio/soundcloud-charts-search-and-artist-catalog").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 '{
  "mode": "search",
  "searchQueries": [
    "lofi"
  ],
  "searchType": "tracks",
  "chartGenre": "all",
  "searchGenre": "",
  "sortBy": "relevance",
  "minPlayCount": 0,
  "minLikeCount": 0,
  "artistUrls": [],
  "includeTracks": true,
  "includeAlbums": false,
  "includePlaylists": false,
  "includeTopTracks": false,
  "includeWebProfiles": false,
  "startUrls": [],
  "includePlaylistTracks": true,
  "includeUserProfile": true,
  "trackUrls": [],
  "commentsSort": "newest",
  "relationship": "followers",
  "resolveStreamUrls": true,
  "maxItems": 2
}' |
apify call nimbryxo-studio/soundcloud-charts-search-and-artist-catalog --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nimbryxo-studio/soundcloud-charts-search-and-artist-catalog"
        }
    }
}
```

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/xauSnBo64ZqngihHG/builds/kzMuZBsSVkEqN6Prx/openapi.json
