Skip to main content

How to Build a Music Listening Stats Dashboard with Cross-Service Data

Published on July 19, 2026

How to Build a Music Listening Stats Dashboard with Cross-Service Data

Most music listeners use more than one streaming service. They have a Spotify account for curated playlists, Apple Music for lossless audio, YouTube Music for live recordings, and maybe Tidal or Deezer for specific catalogs. Their real listening profile lives across all of these platforms.

Building a dashboard that shows a user's combined music stats requires pulling data from each service, normalizing different response formats, and handling authentication for every platform. That is a significant engineering investment when done from scratch.

This tutorial walks through how to build a cross-service music listening stats dashboard using a single API integration. You will learn what data is available, how to fetch and normalize it, and how to display it in a useful way.

Why Developers Need Cross-Service Listening Data

A listening stats dashboard built on a single service only shows part of the picture. Users who split their time across Spotify, Apple Music, and YouTube Music get incomplete analytics from any one platform alone.

Cross-service listening data matters for several use cases:

  • Music analytics apps: Show users their true top artists, genres, and tracks across all platforms, not just one.
  • Playlist intelligence tools: Recommend new music based on a user's full listening history, not a partial view.
  • Artist dashboards: Help musicians understand where their fans actually listen, across every streaming service.
  • Social music features: Let users share their real music identity, combining stats from every service they use.

The problem is not a lack of data. Each streaming platform exposes some combination of favorite tracks, play counts, listening history, and user profiles through their APIs. The problem is that each platform returns this data in different formats, through different authentication flows, with different rate limits and permissions.

What Data Is Available: Play Counts, Favorites, and History

The specific data points you can pull vary by service. Here is a breakdown of what the major streaming platforms expose through their APIs, and how MusicAPI normalizes access to them.

Data TypeSpotifyApple MusicYouTube MusicTidalDeezerSoundCloud
Favorite/liked tracksYesYesYesYesYesYes
User playlistsYesYesYesYesYesYes
User profileYesYesYesYesYesYes
Playlist track detailsYesYesYesYesYesYes
Play count (per track)LimitedNoNoNoNoYes (public)
Full listening historyRecently played onlyNoNoNoNoNo

A few things to notice:

  • Favorite tracks are the most universally available data point. Nearly every service exposes a user's saved/liked tracks through its API.
  • Play counts are inconsistent. Spotify provides limited play count data. SoundCloud exposes public play counts. Most other services do not expose per-user play counts at all.
  • Listening history is the most restricted data type. Only Spotify offers a "recently played" endpoint, and it is limited to the last 50 tracks.

For a stats dashboard, your best foundation is favorite tracks and user playlists. These are consistently available across services and give you enough signal to calculate top artists, genre distributions, and cross-platform overlaps.

MusicAPI provides normalized access to favorite tracks, playlists, playlist tracks, and user profiles across all supported services. You write one API call, and the response structure is identical whether the data comes from Spotify, Apple Music, or Tidal.

Fetching Favorite Tracks from Multiple Services with One API

Without a unified API, fetching a user's favorite tracks from three services means writing three separate integrations. Each one needs its own OAuth flow, its own request format, and its own response parser.

With MusicAPI, the code looks the same for every service. Here is how you fetch favorite tracks from multiple platforms using the same endpoint:

// Authenticate users via MusicAPI's unified OAuth first
// See: https://musicapi.com/docs/user-authentication/getting-started

const services = ['spotify', 'apple_music', 'youtube_music', 'tidal'];

async function getFavoriteTracks(userToken, service) {
  const response = await fetch('https://api.musicapi.com/v1/me/favorites/tracks', {
    headers: {
      'Authorization': `Bearer ${userToken}`,
      'X-Music-Service': service
    }
  });
  return response.json();
}

// Fetch from all connected services in parallel
const allFavorites = await Promise.all(
  services.map(service => getFavoriteTracks(userToken, service))
);

// Each response has the same normalized structure
// [{ id, title, artist, album, duration, service }, ...]

Notice that the endpoint, headers, and response shape are identical for every service. The only thing that changes is the X-Music-Service header value. This is the core value of a unified music API: you write the integration once and it works across all platforms.

Building a music stats dashboard that pulls from multiple services? MusicAPI handles the OAuth, normalization, and rate limiting so you can focus on the dashboard itself.

Code Example: Building a Stats Aggregation Pipeline

Once you have favorite tracks from multiple services, you need to aggregate them into meaningful stats. Here is a practical pipeline that calculates top artists and genre distribution from cross-service data.

// Step 1: Fetch favorites from all connected services
const connectedServices = user.connectedServices; // ['spotify', 'apple_music', 'tidal']

const tracksByService = {};
for (const service of connectedServices) {
  const data = await getFavoriteTracks(user.token, service);
  tracksByService[service] = data.tracks;
}

// Step 2: Deduplicate tracks across services
// Users often favorite the same song on multiple platforms
function deduplicateTracks(tracksByService) {
  const seen = new Map();
  const allTracks = [];

  for (const [service, tracks] of Object.entries(tracksByService)) {
    for (const track of tracks) {
      // Create a normalized key: lowercase title + artist
      const key = `${track.title.toLowerCase()}::${track.artist.toLowerCase()}`;

      if (seen.has(key)) {
        // Track exists on multiple services — add the service to its list
        seen.get(key).services.push(service);
      } else {
        const entry = { ...track, services: [service] };
        seen.set(key, entry);
        allTracks.push(entry);
      }
    }
  }

  return allTracks;
}

// Step 3: Calculate artist frequency
function getTopArtists(tracks, limit = 10) {
  const artistCounts = {};

  for (const track of tracks) {
    const artist = track.artist;
    artistCounts[artist] = (artistCounts[artist] || 0) + 1;
  }

  return Object.entries(artistCounts)
    .sort(([, a], [, b]) => b - a)
    .slice(0, limit)
    .map(([artist, count]) => ({ artist, count }));
}

// Step 4: Calculate cross-platform overlap
function getCrossPlatformTracks(tracks) {
  return tracks
    .filter(t => t.services.length > 1)
    .sort((a, b) => b.services.length - a.services.length);
}

// Run the pipeline
const deduplicated = deduplicateTracks(tracksByService);
const topArtists = getTopArtists(deduplicated);
const crossPlatform = getCrossPlatformTracks(deduplicated);

console.log(`Total unique favorites: ${deduplicated.length}`);
console.log(`Top artist: ${topArtists[0].artist} (${topArtists[0].count} tracks)`);
console.log(`Tracks favorited on 2+ services: ${crossPlatform.length}`);

This pipeline produces three key metrics for your dashboard:

  1. Total unique favorites across all services (deduplicated)
  2. Top artists ranked by how many times they appear in the user's favorites
  3. Cross-platform tracks that the user liked on multiple services (strong signal of true preference)

Normalizing Data Across Spotify, Apple Music, YouTube Music, and More

The hardest part of building cross-service features is not the business logic. It is getting all the data into the same shape.

Without a unified API, here is what you deal with:

FieldSpotify FormatApple Music FormatYouTube Music Format
Track titletrack.nameattributes.namesnippet.title
Artist nametrack.artists[0].nameattributes.artistNamesnippet.channelTitle
Durationtrack.duration_ms (milliseconds)attributes.durationInMilliscontentDetails.duration (ISO 8601)
Albumtrack.album.nameattributes.albumNameN/A (varies)
Track IDtrack.id (Spotify URI)id (catalog ID)id.videoId

Every field name is different. Duration formats are inconsistent. Artist data is nested differently. And this is just three services. Add Tidal, Deezer, SoundCloud, Amazon Music, Qobuz, Audiomack, Audius, Boomplay, and Napster, and you are writing dozens of field mappers.

MusicAPI does this normalization for you. Every supported service returns the same response structure:

{
  "id": "normalized-id",
  "title": "Track Title",
  "artist": "Artist Name",
  "album": "Album Name",
  "duration": 234,
  "service": "spotify"
}

Same field names. Same types. Same nesting. Your aggregation code (like the pipeline above) works without any per-service conditionals.

Displaying Stats: Charting Libraries and Dashboard Patterns

Once your data pipeline is running, you need to present the stats. Here are proven patterns for music listening dashboards.

Recommended charting libraries

LibraryBest ForFramework
RechartsSimple bar/line charts, quick setupReact
Chart.jsLightweight, canvas-based chartsFramework-agnostic
D3.jsCustom, complex visualizationsFramework-agnostic
NivoPre-built chart components with themesReact
Apache EChartsLarge datasets, interactive chartsFramework-agnostic

Dashboard components that work well for music stats

Top Artists Bar Chart: Horizontal bar chart showing the user's top 10 artists by favorite count. Color-code bars by the primary service where each artist was favorited.

Service Distribution Pie Chart: Show what percentage of a user's total favorites come from each streaming service. This tells users where they are most active.

Cross-Platform Overlap Venn Diagram: Visualize tracks that appear on multiple services. Use D3.js or a dedicated Venn library for this.

Timeline View: If you pull playlist data alongside favorites, plot when playlists were created or last modified across services. This shows listening trends over time.

// Example: Recharts data structure for a top artists chart
import { BarChart, Bar, XAxis, YAxis, Tooltip } from 'recharts';

const chartData = topArtists.map(({ artist, count }) => ({
  name: artist,
  favorites: count
}));

function TopArtistsChart() {
  return (
    <BarChart width={600} height={300} data={chartData} layout="vertical">
      <XAxis type="number" />
      <YAxis type="category" dataKey="name" width={120} />
      <Tooltip />
      <Bar dataKey="favorites" fill="#1DB954" />
    </BarChart>
  );
}

Performance tip

Fetch data from all services in parallel (as shown in the pipeline example) and cache the normalized results. Most listening stats do not change minute-to-minute. A 15-minute cache keeps your dashboard responsive without hammering the APIs. MusicAPI's rate limiting is already centralized, but caching on your side reduces latency for returning users.

FAQ

What is a music listening stats API?

A music listening stats API provides access to user data from streaming platforms: favorite tracks, playlists, play counts, and listening history. Each streaming service has its own API for this data. A unified API like MusicAPI normalizes this data across 12+ services into a single endpoint and response format.

Can I get a user's listening history from multiple streaming services?

Full listening history is limited. Only Spotify offers a "recently played" endpoint (capped at 50 tracks). Most other services do not expose listening history at all. However, you can build a useful stats dashboard using favorite tracks and playlists, which are available across all major platforms through MusicAPI.

How do I authenticate users across multiple music services?

Each streaming service has its own OAuth flow. Building and maintaining these separately takes months. MusicAPI's unified authentication handles OAuth for all supported services through a single flow. Users connect their accounts once, and your app gets a single token that works across platforms.

What charting library should I use for a music dashboard?

For React apps, Recharts offers the fastest setup with clean defaults. Chart.js works well for framework-agnostic projects. D3.js gives you full control for custom visualizations like Venn diagrams or force-directed genre graphs. Choose based on your framework and how custom your charts need to be.

How do I handle duplicate tracks across services?

Create a normalized key from the track title and artist name (both lowercase). When the same song appears in favorites on multiple services, merge the entries and track which services it appeared on. This deduplication step is critical for accurate stats. The code example in this post demonstrates this pattern.

Is play count data available across all services?

No. Play count availability varies significantly. Spotify provides limited play count data. SoundCloud exposes public play counts. Most other services (Apple Music, YouTube Music, Tidal, Deezer) do not expose per-user play counts through their APIs. Base your dashboard metrics on favorite tracks and playlists for the most consistent cross-service coverage.

How much does it cost to build a cross-service music dashboard?

The API costs depend on your scale. MusicAPI offers tiered pricing that starts with a free trial. The real cost savings come from engineering time: building and maintaining 12 separate service integrations takes months. A unified API reduces that to days.


Ready to skip months of OAuth and SDK work? Start your free MusicAPI trial and connect 10+ streaming services with one unified API.