# Music Streaming Metrics Scraper (`kamal_pardeshi/music-streaming-metrics-audit`) Actor

Get music performance metrics from YouTube Music, Spotify, JioSaavn, and Gaana in one place. Provide track URLs and retrieve available play, view, engagement, and track metrics in a structured dataset ready for analysis, Google Sheets, APIs, or automation workflows.

- **URL**: https://apify.com/kamal\_pardeshi/music-streaming-metrics-audit.md
- **Developed by:** [Kamal Pardeshi](https://apify.com/kamal_pardeshi) (community)
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 4.00 out of 5 stars

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-usage

## 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

### What does Music Streaming Metrics do?

This V1 Actor accepts public track URLs from [Spotify](https://open.spotify.com), [JioSaavn](https://www.jiosaavn.com), [YouTube Music](https://music.youtube.com), and [Gaana](https://gaana.com). It returns identity-checked metrics and metadata. It is currently an **audit build**, not a production-validated Store product.

### Why use it?

The Actor keeps each input URL independent, preserves duplicate input entries, and reports a failure without discarding the rest of the batch. It does not search for songs or match recordings between services. Outputs can be consumed through the Apify dataset API.

### What data can it extract?

| Field | Meaning |
|---|---|
| Spotify streamCount | Exact playcount/playCount from a track entity matching the requested ID |
| JioSaavn playCount | API play\_count for a song whose canonical URL token matches the request |
| YouTube viewCount | Player count after videoId validation |
| YouTube likeCount / commentCount | Exact integers from the main video action bar / explicit comments header, when exposed |
| Gaana favoriteCount | Track-level total\_favourite\_count, separate from artist favourites and likes |
| Gaana playCountDisplay | The original play\_ct display label, for example 35M+ or <100K; exact playCount remains null |
| trackIdentity | Verified platform ID and available title, artists, album, ISRC and duration |
| metadata.metricStatus | Explains metrics absent from the inspected response |
| diagnostics | Per-tier runtime and observed response bytes; billing fields remain null |

Null is not zero. Rounded counts are not converted into invented exact values. A YouTube uploader is recorded as channelName, not assumed to be the recording artist. ISRC requires an explicit ISRC field and a valid ISRC format; arbitrary platform IDs are never reused as ISRC. Metadata not established from the matched entity remains null. Spotify title and artists are bound to the matched entity; no external recording catalog validation is performed.

### How to run

1. Install dependencies with `npm ci` and Chromium with `npx playwright install chromium`.
2. Build with `npm run build`.
3. Save input to `storage/key_value_stores/default/INPUT.json`.
4. Run `apify run --user-agent apify-codex-plugin/apify-actor-development`.
5. Inspect the dataset and the `AUDIT_SUMMARY` key-value record.

Apify Cloud uses the included Dockerfile and Actor schema. An authenticated account with the selected proxy entitlement is needed only when a proxy tier is attempted.

### Input

See the input tab for configuration options.

In the Console form, use **+ Add URL** to enter each song URL in a text field. The URL-list editor stores entries as `{ "url": "https://..." }` objects. Update saved JSON inputs to this object format: Apify's URL editor validation expects it. The extraction code still understands legacy string entries when invoked without that form validation. Enter individual song URLs; remote URL-list files are not supported.

```json
{
  "urls": [
    { "url": "https://open.spotify.com/track/7qiZfU4dY1lWllzX7mPBI3" },
    { "url": "https://www.jiosaavn.com/song/tum-hi-ho/EToxUyFpcwQ" },
    { "url": "https://music.youtube.com/watch?v=dQw4w9WgXcQ" },
    { "url": "https://gaana.com/song/manjha" }
  ],
  "network": {
    "spotify": ["direct", "datacenter", "residential"],
    "jiosaavn": ["direct", "datacenter", "datacenter-in", "residential"],
    "youtube": ["direct", "datacenter", "residential"],
    "gaana": ["direct", "datacenter", "residential"]
  },
  "spotifyMode": "E"
}
```

Residential uses India. Indian datacenter availability depends on the account and proxy pool; configuration failure is not proof a site requires residential access. Tiers are lazy and platform-specific. Only recognized blocking or transient transport errors advance tiers. Identity errors and parser failures do not trigger costly residential retries. Specify a single tier to benchmark it in isolation. Direct success never creates a proxy.

### Spotify benchmark modes

A uses an unblocked browser and a fresh session per track. It is a repaired control, not the original unbuildable implementation. B blocks images, fonts, media, prefetch and service workers with a fresh session per track. C additionally blocks selected analytics/advertising endpoints. D reuses the browser and context for the batch. E also attempts HTTP replay of an observed single-track GraphQL operation using the context's cookies and captured headers, refreshing through the browser if replay fails. E is the local default after the 100-request fixture test; broader catalog validation remains necessary. Tokens are kept in memory and never saved to the dataset.

By default Spotify first inspects the public HTML initialState for a matching track count. It starts a browser only when that count is absent. Required application scripts are retained. Broad script blocking can prevent token bootstrapping and is intentionally avoided. The browser stops after a verified count arrives, without waiting for Spotify's entire UI to finish rendering.

### Output

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel. Each input produces one row, with streamCount, playCount, viewCount, likeCount, commentCount, favoriteCount and playCountDisplay at the top level, preserving the latest website edits. `status` is success when the platform's primary count is verified (track favourites for Gaana), partial when identity is verified but that count is missing, or error when extraction/identity verification fails. A success does not promise every optional metric is available.

Gaana is fetched over HTTP without starting a browser. Track identity is bound to the requested song slug and a consistent numeric track ID. The Actor reports the site's display label without converting rounded values into exact plays. The undocumented popularity field is not used. Missing metrics remain null, with reasons in metadata.metricStatus. Gaana support has only a small live-song smoke test, not broad catalogue validation.

### How much will it cost?

Use completed, platform-isolated cloud runs for billing. `responseBodyBytes` measures decoded HTTP response payloads; `browserEncodedDownloadBytes` measures completed browser downloads. Neither is residential billed bandwidth. Failed/unfinished transfers and protocol overhead can be absent. Cloud startup, memory allocation, storage, and transfer charges must be included before setting Store prices.

The audit report records actual results and limitations. Do not infer production economics from a two-track local sample or extrapolate a blended platform cost.

### Tests and troubleshooting

Run `npm test` for identity, numeric parsing, URL validation, and fallback regression tests. On a sandbox that forbids test subprocesses, Node 22+ can use `node --test --test-isolation=none test/*.test.cjs`.

Private endpoints and frontend schemas may change. A missing count is not evidence of zero usage. YouTube comments may require an additional continuation request; this version reports their absence from the initial page explicitly rather than declaring comments disabled. Failed proxy setup is reported as a request failure, not a successful empty result. Use the Issues tab for reproducible inputs and the API tab for programmatic access.

# Actor input Schema

## `urls` (type: `array`):

Use + Add URL to enter Spotify, JioSaavn, YouTube Music or Gaana song URLs. For JSON input, use entries like {"url":"https://gaana.com/song/manjha"}. Enter individual URLs, not URL-list files. Unsupported song URLs fail independently.

## `network` (type: `object`):

Ordered tiers per spotify, jiosaavn, youtube, gaana: direct, datacenter, datacenter-in, residential. Only retryable failures advance tiers.

## `spotifyMode` (type: `string`):

E replays observed, verified single-track queries after browser bootstrap. D remains available for browser-only session comparison.

## `spotifyHttpFirst` (type: `boolean`):

Disable only for controlled browser benchmarks.

## Actor input object example

```json
{
  "network": {
    "spotify": [
      "direct",
      "datacenter",
      "residential"
    ],
    "jiosaavn": [
      "direct",
      "datacenter",
      "datacenter-in",
      "residential"
    ],
    "gaana": [
      "direct",
      "datacenter",
      "residential"
    ],
    "youtube": [
      "direct",
      "datacenter",
      "residential"
    ]
  },
  "spotifyMode": "E",
  "spotifyHttpFirst": true
}
```

# Actor output Schema

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

Structured music performance metrics for all successfully processed track URLs.

# 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 = {
    "network": {
        "spotify": [
            "direct",
            "datacenter",
            "residential"
        ],
        "jiosaavn": [
            "direct",
            "datacenter",
            "datacenter-in",
            "residential"
        ],
        "gaana": [
            "direct",
            "datacenter",
            "residential"
        ],
        "youtube": [
            "direct",
            "datacenter",
            "residential"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("kamal_pardeshi/music-streaming-metrics-audit").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 = { "network": {
        "spotify": [
            "direct",
            "datacenter",
            "residential",
        ],
        "jiosaavn": [
            "direct",
            "datacenter",
            "datacenter-in",
            "residential",
        ],
        "gaana": [
            "direct",
            "datacenter",
            "residential",
        ],
        "youtube": [
            "direct",
            "datacenter",
            "residential",
        ],
    } }

# Run the Actor and wait for it to finish
run = client.actor("kamal_pardeshi/music-streaming-metrics-audit").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 '{
  "network": {
    "spotify": [
      "direct",
      "datacenter",
      "residential"
    ],
    "jiosaavn": [
      "direct",
      "datacenter",
      "datacenter-in",
      "residential"
    ],
    "gaana": [
      "direct",
      "datacenter",
      "residential"
    ],
    "youtube": [
      "direct",
      "datacenter",
      "residential"
    ]
  }
}' |
apify call kamal_pardeshi/music-streaming-metrics-audit --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,kamal_pardeshi/music-streaming-metrics-audit"
        }
    }
}
```

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/7jPfKW7Pn7JnNfzPG/builds/KRenFMwAuz51g9ftF/openapi.json
