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 what a clean structured chart dataset should look like once you have one.
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.
Whatever you collect the charts with, the request only ever has four dimensions: the country (an ISO 3166-1 alpha-2 code such as US, GB, DE, BR, JP, or a global aggregation), the chart type (regional for the Top 200, viral for the Viral 50), the period (daily or weekly), and how many rows you want back.
The output worth storing is one flat record per chart entry:
{
"rank": 1,
"track_name": "Beauty And A Beat",
"artist_name": "Justin Bieber, Nicki Minaj",
"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"
}
Carrying country, chart_type, period and date on every row rather than in a wrapper object is what makes the dataset usable: a downstream pipeline can treat all chart pulls uniformly, load them into one date-partitioned warehouse table, and run the same diff and trend queries across every market. Keep track_id as the join key — track and artist names are not stable enough to group on.
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.None of the difficulty is in the schema above. It is in everything around it: headless browsers, DOM extraction logic that breaks every time the chart UI ships an update, proxy rotation, rate-limit retries, normalising a response shape that moves, and country-by-country geo handling. Budget for that ongoing maintenance rather than the initial build — the first working pull is a weekend; keeping it working across 70 markets is the actual commitment.