Spotify Charts — the Top 200 of regional plays and the Viral 50 of fast-moving tracks — are the closest thing the modern streaming era has to a real-time pulse on music demand. The charts cover roughly 70 country markets plus a global aggregation, refresh daily and weekly, and surface both established hits and breakouts before any other public dataset catches them. They are the data layer that A&R scouts, label marketing teams, music supervisors, playlist curators, and music journalists watch constantly.
The trouble is that the charts only exist as a browser-rendered single-page application at charts.spotify.com. There is no public CSV download, no documented API, and no way to subscribe to a feed. If you want chart data programmatically — to build a dashboard, run a backtest, or simply diff today’s Top 50 against last week’s — you need a scraper. This post walks through why chart data matters, why pulling it manually does not scale, and how to call our hosted Spotify Charts scraper to get clean structured chart entries for any country and period without writing any code.
Spotify publishes charts for roughly 70 country markets plus a global aggregation, in two chart types (Top 200 regional, Viral 50) and two refresh cadences (daily, weekly). That is more than 280 distinct chart views, each refreshing on its own schedule. Anyone trying to monitor “what is happening in streaming today” at country granularity is not opening 280 browser tabs.
The pain stacks up fast in three places. First, the chart pages are JavaScript-rendered: a normal HTTP fetch to the chart URL returns an empty shell of an SPA, not chart entries, so naive scrapers fail silently. Second, chart entries themselves are loaded asynchronously after the page mounts, and the response shape is undocumented and can shift across regions. Third, even once you do extract the data, normalising it into a clean schema — rank, track, artist, peak position, weeks on chart, ISRC-adjacent identifiers, country, period, date — takes more engineering than most data teams want to own.
Music platforms increasingly restrict bulk programmatic access to their public surfaces, and chart pages can rate-limit or geo-gate aggressive callers. For production-scale music data collection across many regions, residential proxies are usually part of the answer — Oxylabs residential proxies are what we recommend for music platforms that restrict bulk data access; they enable reliable collection without tripping the protections that consumer IPs hit immediately.
Our Spotify Charts scraper takes a small JSON input describing which chart you want, and returns a clean array of chart entries. The input fields are country (an ISO 3166-1 alpha-2 country code such as US, GB, DE, BR, JP, or global for the global aggregation), chartType (regional for the Top 200, viral for the Viral 50), period (daily or weekly), and maxResults (1–200, default 50).
To get the current Global Top 10 daily chart, the input is:
{
"country": "global",
"chartType": "regional",
"period": "daily",
"maxResults": 10
}
The output is an array of records, one per chart entry, in the following shape:
[
{
"rank": 1,
"track_name": "Beauty And A Beat",
"artist_name": "Justin Bieber, Nicki Minaj",
"streams": 0,
"peak_position": 1,
"weeks_on_chart": 12,
"spotify_url": "https://open.spotify.com/track/6QFCMUUq1T2Vf5sFUXcuQ7",
"track_id": "6QFCMUUq1T2Vf5sFUXcuQ7",
"country": "global",
"chart_type": "regional",
"period": "daily",
"date": "2026-05-03",
"source": "spotify-charts"
},
{
"rank": 2,
"track_name": "SWIM",
"artist_name": "BTS",
"spotify_url": "https://open.spotify.com/track/...",
"country": "global",
"chart_type": "regional",
"period": "daily",
"date": "2026-05-03"
}
]
To get the German weekly Top 50, the input changes only the country and period fields:
{
"country": "DE",
"chartType": "regional",
"period": "weekly",
"maxResults": 50
}
To pull the German Viral 50 daily chart instead, switch chartType to viral:
{
"country": "DE",
"chartType": "viral",
"period": "daily",
"maxResults": 50
}
Output records carry the same schema regardless of country or chart type, which means a downstream pipeline can treat all chart pulls uniformly: load into the same warehouse table, partition by country, chart_type, period, and date, and run the same diff and trend queries on top.
chartType=regional and period=daily, and append the results to a date-partitioned dataset. Diff against yesterday for movers.track_id, and surface tracks that are appearing on three or more country viral charts simultaneously — that is the leading indicator of a global breakout.regional + weekly with maxResults=200 across the markets that matter to you; this is the steady backbone for catalogue analysis, label market-share reporting, and longer-horizon trend stories.track_id trivial.Calling the hosted actor means you do not write or maintain any of the messy parts: no headless browsers, no DOM extraction logic that breaks every time the chart UI ships an update, no proxy rotation, no rate-limit retry logic, no normalisation of a moving response shape, no country-by-country geo handling. You send a small JSON input; you get a clean array of chart entries back. If chart data starts mattering to your team, that is the integration boundary you want.