Published on May 23, 2026

Building a music player used to mean picking one streaming service and locking yourself into its SDK. Today, users expect access to tracks from the services they already pay for. A music player API gives you the data layer to make that happen: track metadata, artwork, playback URLs, and user libraries, all through standard REST calls instead of platform-specific SDKs.
This guide walks you through what a music player API provides, how to normalize data across streaming services, and how to build a custom audio player step by step with real code examples.
A music player API is a REST interface that exposes streaming service data for use in your own applications. It gives you programmatic access to track metadata (title, artist, album, duration, artwork), search functionality, user playlists, liked tracks, and playback preview URLs. Developers reach for a music player API when they need to integrate music data into a custom UI without rebuilding authentication, pagination, and response parsing for every streaming platform individually.
The feature set you need depends on what you are building. At minimum, most music player integrations require track search, metadata retrieval, and some form of playback URL. More advanced builds add queue management, user library access, and cross-service functionality.
Here is how the three main approaches compare:
| Feature | Native SDKs (per service) | Unified API (MusicAPI) | Build from Scratch |
|---|---|---|---|
| Track search | Yes (per SDK) | Yes (one endpoint, 20 services) | Yes (you build each) |
| Metadata retrieval | Yes (different formats) | Yes (normalized response) | Yes (you normalize) |
| Preview/playback URLs | Varies by SDK | Yes (when available) | You handle each |
| User playlists | Yes (per SDK auth) | Yes (one auth flow) | Yes (you build each) |
| Liked tracks | Yes (per SDK auth) | Yes (one auth flow) | Yes (you build each) |
| Cross-service support | No (one SDK = one service) | Yes (12 authenticated, 20 public) | You build and maintain |
| OAuth handling | You implement per service | Handled for you | You implement per service |
| Time to first integration | Days to weeks per service | Minutes | Weeks to months |
Native SDKs give you deep access to a single platform, but every additional service multiplies your auth code, response parsing, and maintenance burden. Building from scratch offers maximum control at maximum cost. A unified music player API sits in the middle: one integration, normalized responses, and broad service coverage.
MusicAPI connects to 20 streaming services through a single REST API. Public endpoints (search, metadata) work across all 20 services. Authenticated endpoints (playlists, liked tracks, user profiles) cover 12 services including Spotify, Apple Music, YouTube, Tidal, Deezer, Amazon Music, SoundCloud, and more.
The key advantage for building a music player: every response follows the same schema regardless of which streaming service the data comes from. A track object from Spotify looks identical to a track object from Tidal or Deezer in MusicAPI's response format.
Here is a search request that works across any supported service:
const response = await fetch('https://api.musicapi.com/public/search', {
method: 'POST',
headers: {
'Authorization': 'Basic YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
query: 'Bohemian Rhapsody',
type: 'track',
sources: ['spotify', 'apple-music', 'tidal', 'deezer']
})
});
const data = await response.json();
The response returns a normalized track object from each service:
{
"tracks": [
{
"source": "spotify",
"status": "success",
"type": "track",
"data": {
"externalId": "4u7EnebtmKWzUH433cf5Qv",
"name": "Bohemian Rhapsody",
"artistNames": ["Queen"],
"albumName": "A Night at the Opera",
"imageUrl": "https://i.scdn.co/image/...",
"previewUrl": "https://p.scdn.co/mp3-preview/...",
"isrc": "GBUM71029604",
"duration": 354947,
"url": "https://open.spotify.com/track/..."
}
},
{
"source": "tidal",
"status": "success",
"type": "track",
"data": {
"externalId": "56450803",
"name": "Bohemian Rhapsody",
"artistNames": ["Queen"],
"albumName": "A Night At The Opera",
"imageUrl": "https://resources.tidal.com/images/...",
"previewUrl": "https://listen.tidal.com/...",
"isrc": "GBUM71029604",
"duration": 354000,
"url": "https://tidal.com/browse/track/..."
}
}
]
}
Same fields, same structure, regardless of source. No per-service response parsing. No conditional logic to extract artist names from different nested objects. MusicAPI handles the per-service OAuth and response normalization so you can focus on your player UI. Check out all available endpoints to see what data you can pull into your player.
Let's build a functional audio player in React that pulls track data from multiple streaming services, displays metadata, and handles playback controls. This walkthrough covers authentication, data fetching, UI rendering, and playback state management.
Before fetching user-specific data like playlists and liked tracks, you need to authenticate users with their streaming service accounts. MusicAPI provides a unified auth flow that works across all supported services.
First, redirect your user to MusicAPI's auth endpoint:
const accountSlug = 'your-account-slug';
const returnUrl = encodeURIComponent('https://yourapp.com/callback');
// Redirect the user to authenticate with their streaming service
window.location.href =
`https://auth.musicapi.com/${accountSlug}/callback?returnUrl=${returnUrl}`;
You can optionally pass a musicService parameter to skip the service selection screen:
// Pre-select Spotify
window.location.href =
`https://auth.musicapi.com/${accountSlug}/callback?returnUrl=${returnUrl}&musicService=spotify`;
After the user completes authentication, they return to your callback URL with a user UUID. Store this UUID; you will use it for all subsequent authenticated API calls.
// In your callback handler
const urlParams = new URLSearchParams(window.location.search);
const userUUID = urlParams.get('uuid');
// Store for future API calls
localStorage.setItem('musicapi_user_uuid', userUUID);
With the user authenticated, you can now fetch their music data. Here is a React hook that fetches a user's liked tracks:
import { useState, useEffect } from 'react';
function useLikedTracks(userUUID) {
const [tracks, setTracks] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function fetchTracks() {
const response = await fetch(
`https://api.musicapi.com/api/${userUUID}/liked/tracks`,
{
headers: {
'Authorization': 'Basic YOUR_API_KEY'
}
}
);
const data = await response.json();
setTracks(data.results);
setLoading(false);
}
if (userUUID) fetchTracks();
}, [userUUID]);
return { tracks, loading };
}
The response gives you everything your player needs to render a track list:
{
"results": [
{
"id": "4u7EnebtmKWzUH433cf5Qv",
"name": "Bohemian Rhapsody",
"isrc": "GBUM71029604",
"duration": 354947,
"imageUrl": "https://i.scdn.co/image/ab67616d...",
"previewUrl": "https://p.scdn.co/mp3-preview/...",
"album": {
"name": "A Night at the Opera",
"artists": [{ "name": "Queen" }]
},
"artists": [{ "name": "Queen" }],
"dateAdded": "2024-03-15T10:30:00Z"
}
],
"nextParam": "offset=50",
"totalItems": 342
}
You can also fetch user playlists and their tracks using the same pattern:
// Fetch user's playlists
const playlists = await fetch(
`https://api.musicapi.com/api/${userUUID}/playlists`,
{ headers: { 'Authorization': 'Basic YOUR_API_KEY' } }
).then(res => res.json());
// Fetch tracks from a specific playlist
const playlistTracks = await fetch(
`https://api.musicapi.com/api/${userUUID}/playlists/${playlistId}/tracks`,
{ headers: { 'Authorization': 'Basic YOUR_API_KEY' } }
).then(res => res.json());
Now let's build the player component. This component displays the current track's metadata and artwork:
function MusicPlayer({ track, isPlaying, onPlayPause, onNext, onPrevious }) {
if (!track) return null;
const artistName = track.artists?.[0]?.name || 'Unknown Artist';
const duration = formatDuration(track.duration);
return (
<div className="music-player">
<img
src={track.imageUrl}
alt={`${track.album?.name} cover`}
className="album-art"
/>
<div className="track-info">
<h3 className="track-name">{track.name}</h3>
<p className="artist-name">{artistName}</p>
<p className="album-name">{track.album?.name}</p>
</div>
<div className="controls">
<button onClick={onPrevious} aria-label="Previous track">⏮</button>
<button onClick={onPlayPause} aria-label={isPlaying ? 'Pause' : 'Play'}>
{isPlaying ? '⏸' : '▶'}
</button>
<button onClick={onNext} aria-label="Next track">⏭</button>
</div>
<span className="duration">{duration}</span>
</div>
);
}
function formatDuration(ms) {
if (!ms) return '0:00';
const minutes = Math.floor(ms / 60000);
const seconds = Math.floor((ms % 60000) / 1000);
return `${minutes}:${seconds.toString().padStart(2, '0')}`;
}
The final piece: managing playback state with the HTML5 Audio API. This hook connects MusicAPI's preview URLs to actual audio playback:
import { useState, useRef, useCallback } from 'react';
function useAudioPlayer(tracks) {
const audioRef = useRef(new Audio());
const [currentIndex, setCurrentIndex] = useState(0);
const [isPlaying, setIsPlaying] = useState(false);
const [progress, setProgress] = useState(0);
const currentTrack = tracks[currentIndex] || null;
const play = useCallback(() => {
if (!currentTrack?.previewUrl) return;
const audio = audioRef.current;
if (audio.src !== currentTrack.previewUrl) {
audio.src = currentTrack.previewUrl;
}
audio.play();
setIsPlaying(true);
}, [currentTrack]);
const pause = useCallback(() => {
audioRef.current.pause();
setIsPlaying(false);
}, []);
const playPause = useCallback(() => {
isPlaying ? pause() : play();
}, [isPlaying, play, pause]);
const next = useCallback(() => {
const nextIndex = (currentIndex + 1) % tracks.length;
setCurrentIndex(nextIndex);
audioRef.current.src = tracks[nextIndex]?.previewUrl || '';
if (isPlaying) audioRef.current.play();
}, [currentIndex, tracks, isPlaying]);
const previous = useCallback(() => {
const prevIndex = currentIndex === 0
? tracks.length - 1
: currentIndex - 1;
setCurrentIndex(prevIndex);
audioRef.current.src = tracks[prevIndex]?.previewUrl || '';
if (isPlaying) audioRef.current.play();
}, [currentIndex, tracks, isPlaying]);
const seek = useCallback((percent) => {
const audio = audioRef.current;
audio.currentTime = (percent / 100) * audio.duration;
}, []);
return {
currentTrack,
isPlaying,
progress,
playPause,
next,
previous,
seek
};
}
Putting it all together in your app:
function App() {
const userUUID = localStorage.getItem('musicapi_user_uuid');
const { tracks, loading } = useLikedTracks(userUUID);
const player = useAudioPlayer(tracks);
if (loading) return <div>Loading your music...</div>;
return (
<div className="app">
<TrackList
tracks={tracks}
onSelect={(index) => player.selectTrack(index)}
/>
<MusicPlayer
track={player.currentTrack}
isPlaying={player.isPlaying}
onPlayPause={player.playPause}
onNext={player.next}
onPrevious={player.previous}
/>
</div>
);
}
Not building a fully custom player? MusicAPI also offers an embeddable player widget that you can drop into any page with a single line of code.
A music player API is not just for standalone music apps. Here are five use cases where streaming service data powers a better product:
Fitness apps. Pull a user's workout playlists from their connected streaming service and sync BPM-matched tracks to exercise intensity. The user stays in your app while hearing music from the library they already built.
Social music sharing. Let users share what they are listening to, build collaborative playlists, or vote on tracks in a group session. Fetching playlist data from multiple services means friends on different platforms can still participate.
DJ and mixing tools. Access track metadata, BPM, duration, and ISRC codes to build beat-matching interfaces, setlist planners, or transition tools. The normalized response format means your matching logic works the same regardless of the source service.
In-game music. Give players control over their in-game soundtrack by connecting their streaming account. Fetch their playlists, display album art as game textures, and tie playback controls to the game UI.
Podcast and music hybrid apps. Combine podcast RSS feeds with a user's music library in a single player experience. Use MusicAPI for the music layer and your own feeds for podcasts, with one unified playback interface.
A music player API is a programmatic interface that gives developers access to streaming music data: track metadata, search, user playlists, liked songs, and playback preview URLs. Instead of building direct integrations with each streaming platform, you call a REST API and receive structured JSON responses with the track information your application needs.
Yes. With a unified API like MusicAPI, you connect once and access data from 20 streaming services through the same endpoints. Users authenticate with whichever service they use, and your code stays the same regardless of the source.
MusicAPI provides a single OAuth flow that works across all supported streaming services. You redirect users to MusicAPI's auth endpoint, they log in with their streaming account, and you receive a user UUID for subsequent API calls. No need to register as a developer on each platform's portal or manage multiple OAuth implementations.
Track responses include the track name, artist names, album name, duration (in milliseconds), album artwork URL, preview/playback URL (when available), ISRC code, and a direct link to the track on its source service. Playlist and library endpoints return similar structured data with pagination support. See the full endpoint reference for complete response schemas.
Yes. MusicAPI offers a free tier so you can test the integration, explore endpoints, and build your player before committing to a paid plan. Check the pricing page for current plan details and rate limits.
MusicAPI handles rate limiting at the service level so you do not hit individual platform limits directly. Cache track metadata on your end for data you display repeatedly (album art, track names) and use pagination parameters to avoid fetching more data than your UI needs at once.
A custom audio player gives your users the experience they want, with the streaming service they already use. MusicAPI provides the data layer: normalized track metadata, cross-service search, user libraries, and a single auth flow for 12+ authenticated services.
Ready to skip months of OAuth and SDK work? Start your free MusicAPI trial and connect 10+ streaming services with one unified API.