Skip to main content

How to Build a Playlist Generator with MusicAPI

Published on March 22, 2026

How to Build a Playlist Generator with MusicAPI

Building a playlist generator is one of the most rewarding projects for developers who want to combine music data with real application logic. Whether you're creating a mood-based mixtape tool or a recommendation engine for your users, MusicAPI gives you unified access to catalog data from Spotify, Apple Music, YouTube Music, and more through a single endpoint, making cross-platform playlist generation surprisingly straightforward.

Table of Contents

Quick Summary

TakeawayExplanation
Unified music API accessMusicAPI connects to Spotify, Apple Music, YouTube Music, and more via one API
Simple track searchSearch across platforms with a single request and consistent response format
Playlist creationProgrammatically create and populate playlists on any supported platform
Cross-platform syncMatch and transfer tracks between services using MusicAPI's matching engine
Production-ready codeComplete Python and JavaScript examples you can adapt for your own projects

What You Will Build

Project Overview

In this music API tutorial, you will build a playlist generator that can search for tracks across multiple streaming platforms, assemble them into a cohesive playlist based on genre or artist similarity, and save that playlist directly to a user's streaming account. The finished application works with Spotify, Apple Music, YouTube Music, Deezer, Tidal, and other platforms — all through MusicAPI's unified interface.

By the end of this tutorial, you will have a working playlist generator that:

  • Searches for tracks by genre, artist, or keyword
  • Builds playlists using smart filtering logic
  • Creates playlists on the user's chosen streaming platform
  • Supports cross-platform track matching for multi-service sync

Prerequisites And Setup

Before you start, make sure you have the following:

  • A MusicAPI account — Sign up at musicapi.com to get your API key
  • Python 3.8+ or Node.js 16+ installed on your machine
  • Basic knowledge of REST APIs and how to make HTTP requests
  • A connected streaming account — You will need at least one streaming service connected through MusicAPI's OAuth flow

Setting Up MusicAPI

Getting Your API Key

Head to the MusicAPI dashboard and create a new project. Your API key will be displayed on the project settings page. Store it securely — you will need it for every request.

MusicAPI uses a simple Bearer token authentication model. Every request includes your API key in the Authorization header:

Authorization: Bearer YOUR_API_KEY

Installing Dependencies

Python:

pip install requests

JavaScript (Node.js):

npm install axios

That is all you need. MusicAPI is a REST API, so any HTTP client works. We use requests for Python and axios for JavaScript throughout this tutorial because they keep the code clean and readable.

Searching For Tracks

Basic Track Search

The foundation of any playlist generator is track search. MusicAPI provides a unified search endpoint that queries across all connected platforms simultaneously.

Python:

import requests

API_KEY = "your_musicapi_key"
BASE_URL = "https://api.musicapi.com/v1"

def search_tracks(query, limit=20):
    """Search for tracks across all connected platforms."""
    response = requests.get(
        f"{BASE_URL}/search",
        headers={"Authorization": f"Bearer {API_KEY}"},
        params={
            "q": query,
            "type": "track",
            "limit": limit
        }
    )
    response.raise_for_status()
    return response.json()["tracks"]

# Search for upbeat pop tracks
results = search_tracks("upbeat pop hits")
for track in results:
    print(f"{track['name']} by {track['artist']}{track['platform']}")

JavaScript:

const axios = require('axios');

const API_KEY = 'your_musicapi_key';
const BASE_URL = 'https://api.musicapi.com/v1';

async function searchTracks(query, limit = 20) {
  const response = await axios.get(`${BASE_URL}/search`, {
    headers: { Authorization: `Bearer ${API_KEY}` },
    params: { q: query, type: 'track', limit }
  });
  return response.data.tracks;
}

// Search for upbeat pop tracks
const results = await searchTracks('upbeat pop hits');
results.forEach(track => {
  console.log(`${track.name} by ${track.artist}${track.platform}`);
});

Each track object in the response includes a name, artist, album, platform, platformId, and duration — giving you everything you need to build playlist logic.

Filtering And Refining Results

Raw search results are a starting point. A good playlist generator filters and ranks tracks to create a coherent listening experience. MusicAPI supports several filter parameters to narrow results before they reach your application:

Python:

def search_with_filters(query, genre=None, year_from=None, year_to=None, limit=20):
    """Search with optional genre and year filters."""
    params = {
        "q": query,
        "type": "track",
        "limit": limit
    }
    if genre:
        params["genre"] = genre
    if year_from:
        params["year_from"] = year_from
    if year_to:
        params["year_to"] = year_to

    response = requests.get(
        f"{BASE_URL}/search",
        headers={"Authorization": f"Bearer {API_KEY}"},
        params=params
    )
    response.raise_for_status()
    return response.json()["tracks"]

# Find indie rock tracks from the last two years
tracks = search_with_filters("indie rock", genre="rock", year_from=2024)

Building The Playlist Logic

Genre-Based Playlist Generation

A genre-based playlist generator searches for tracks in a specific genre and assembles them into a balanced mix. The key is variety — you want different artists, tempos, and release years to keep the playlist interesting.

Python:

import random

def generate_genre_playlist(genre, track_count=25):
    """Generate a playlist based on a genre with artist diversity."""
    search_queries = [
        f"best {genre} songs",
        f"new {genre} music",
        f"popular {genre} tracks",
        f"classic {genre} hits"
    ]

    all_tracks = []
    seen_artists = set()

    for query in search_queries:
        results = search_tracks(f"{query}", limit=30)
        for track in results:
            # Ensure artist diversity: max 2 tracks per artist
            artist = track["artist"].lower()
            if seen_artists.get(artist, 0) < 2 if isinstance(seen_artists, dict) else artist not in seen_artists:
                all_tracks.append(track)
                seen_artists.add(artist)

    # Shuffle and trim to desired count
    random.shuffle(all_tracks)
    return all_tracks[:track_count]

playlist = generate_genre_playlist("electronic", track_count=20)
print(f"Generated playlist with {len(playlist)} tracks")

JavaScript:

async function generateGenrePlaylist(genre, trackCount = 25) {
  const queries = [
    `best ${genre} songs`,
    `new ${genre} music`,
    `popular ${genre} tracks`,
    `classic ${genre} hits`
  ];

  const allTracks = [];
  const artistCount = {};

  for (const query of queries) {
    const results = await searchTracks(query, 30);
    for (const track of results) {
      const artist = track.artist.toLowerCase();
      // Max 2 tracks per artist for variety
      if ((artistCount[artist] || 0) < 2) {
        allTracks.push(track);
        artistCount[artist] = (artistCount[artist] || 0) + 1;
      }
    }
  }

  // Shuffle and trim
  const shuffled = allTracks.sort(() => Math.random() - 0.5);
  return shuffled.slice(0, trackCount);
}

const playlist = await generateGenrePlaylist('electronic', 20);
console.log(`Generated playlist with ${playlist.length} tracks`);

Artist-Based Discovery

Another common pattern is building playlists around a seed artist. You find related artists and pull tracks from each one to create a discovery-focused listening experience.

Python:

def get_related_artists(artist_id):
    """Get artists similar to the given artist."""
    response = requests.get(
        f"{BASE_URL}/artists/{artist_id}/related",
        headers={"Authorization": f"Bearer {API_KEY}"}
    )
    response.raise_for_status()
    return response.json()["artists"]

def generate_artist_radio(seed_artist_name, track_count=20):
    """Build a playlist around a seed artist and related artists."""
    # Find the seed artist
    search_results = search_tracks(seed_artist_name, limit=5)
    if not search_results:
        return []

    seed_artist_id = search_results[0]["artistId"]
    related = get_related_artists(seed_artist_id)

    playlist_tracks = []

    # Add top tracks from the seed artist
    seed_tracks = search_tracks(f"{seed_artist_name} top tracks", limit=5)
    playlist_tracks.extend(seed_tracks[:3])

    # Add tracks from related artists
    for artist in related[:8]:
        artist_tracks = search_tracks(f"{artist['name']} popular", limit=5)
        playlist_tracks.extend(artist_tracks[:2])

    random.shuffle(playlist_tracks)
    return playlist_tracks[:track_count]

radio_playlist = generate_artist_radio("Daft Punk", track_count=15)

Creating And Saving Playlists

Creating A Playlist On The Target Platform

Once you have assembled your track list, the next step is creating an actual playlist on the user's streaming platform. MusicAPI handles the platform-specific API calls behind the scenes.

Python:

def create_playlist(user_id, name, description="", platform="spotify"):
    """Create a new empty playlist on the specified platform."""
    response = requests.post(
        f"{BASE_URL}/playlists",
        headers={
            "Authorization": f"Bearer {API_KEY}",
            "Content-Type": "application/json"
        },
        json={
            "userId": user_id,
            "name": name,
            "description": description,
            "platform": platform,
            "public": True
        }
    )
    response.raise_for_status()
    return response.json()["playlist"]

new_playlist = create_playlist(
    user_id="user_123",
    name="Weekend Electronic Mix",
    description="Auto-generated electronic playlist for the weekend"
)
print(f"Created playlist: {new_playlist['id']}")

JavaScript:

async function createPlaylist(userId, name, description = '', platform = 'spotify') {
  const response = await axios.post(`${BASE_URL}/playlists`, {
    userId,
    name,
    description,
    platform,
    public: true
  }, {
    headers: {
      Authorization: `Bearer ${API_KEY}`,
      'Content-Type': 'application/json'
    }
  });
  return response.data.playlist;
}

const newPlaylist = await createPlaylist(
  'user_123',
  'Weekend Electronic Mix',
  'Auto-generated electronic playlist for the weekend'
);
console.log(`Created playlist: ${newPlaylist.id}`);

Adding Tracks To Your Playlist

With the playlist created, add tracks to it using the playlist tracks endpoint:

Python:

def add_tracks_to_playlist(playlist_id, track_ids):
    """Add a list of tracks to an existing playlist."""
    response = requests.post(
        f"{BASE_URL}/playlists/{playlist_id}/tracks",
        headers={
            "Authorization": f"Bearer {API_KEY}",
            "Content-Type": "application/json"
        },
        json={"trackIds": track_ids}
    )
    response.raise_for_status()
    return response.json()

# Add generated tracks to the playlist
track_ids = [track["platformId"] for track in playlist]
result = add_tracks_to_playlist(new_playlist["id"], track_ids)
print(f"Added {result['addedCount']} tracks to playlist")

JavaScript:

async function addTracksToPlaylist(playlistId, trackIds) {
  const response = await axios.post(
    `${BASE_URL}/playlists/${playlistId}/tracks`,
    { trackIds },
    {
      headers: {
        Authorization: `Bearer ${API_KEY}`,
        'Content-Type': 'application/json'
      }
    }
  );
  return response.data;
}

const trackIds = playlist.map(track => track.platformId);
const result = await addTracksToPlaylist(newPlaylist.id, trackIds);
console.log(`Added ${result.addedCount} tracks to playlist`);

Cross-Platform Playlist Sync

Matching Tracks Across Services

One of MusicAPI's most powerful features for building a playlist generator is cross-platform track matching. If a user has playlists on Spotify but wants to listen on Apple Music, you can match tracks between services automatically.

Python:

def match_track_cross_platform(track_id, source_platform, target_platform):
    """Find the equivalent track on a different platform."""
    response = requests.get(
        f"{BASE_URL}/tracks/{track_id}/match",
        headers={"Authorization": f"Bearer {API_KEY}"},
        params={
            "sourcePlatform": source_platform,
            "targetPlatform": target_platform
        }
    )
    response.raise_for_status()
    match = response.json()
    return match.get("matchedTrack")

def sync_playlist_to_platform(playlist_tracks, source_platform, target_platform):
    """Sync a full playlist from one platform to another."""
    matched_tracks = []
    unmatched = []

    for track in playlist_tracks:
        matched = match_track_cross_platform(
            track["platformId"], source_platform, target_platform
        )
        if matched:
            matched_tracks.append(matched)
        else:
            unmatched.append(track)

    return matched_tracks, unmatched

matched, missing = sync_playlist_to_platform(
    playlist, "spotify", "apple_music"
)
print(f"Matched: {len(matched)}, Missing: {len(missing)}")

Handling Missing Tracks Gracefully

Not every track exists on every platform. A production-grade playlist generator needs to handle missing tracks without breaking the user experience.

Python:

def sync_with_fallback(playlist_tracks, source_platform, target_platform):
    """Sync playlist with search-based fallback for unmatched tracks."""
    synced = []
    failed = []

    for track in playlist_tracks:
        # Try direct match first
        matched = match_track_cross_platform(
            track["platformId"], source_platform, target_platform
        )

        if matched:
            synced.append(matched)
            continue

        # Fallback: search by name and artist on target platform
        query = f"{track['name']} {track['artist']}"
        search_results = search_tracks(query, limit=3)
        target_results = [
            t for t in search_results
            if t["platform"] == target_platform
        ]

        if target_results:
            synced.append(target_results[0])
        else:
            failed.append(track)

    return synced, failed

Putting It All Together

Full Working Example

Here is a complete Python script that ties everything together into a functional playlist generator:

Python:

import requests
import random

API_KEY = "your_musicapi_key"
BASE_URL = "https://api.musicapi.com/v1"

def search_tracks(query, limit=20):
    response = requests.get(
        f"{BASE_URL}/search",
        headers={"Authorization": f"Bearer {API_KEY}"},
        params={"q": query, "type": "track", "limit": limit}
    )
    response.raise_for_status()
    return response.json()["tracks"]

def create_playlist(user_id, name, description, platform):
    response = requests.post(
        f"{BASE_URL}/playlists",
        headers={
            "Authorization": f"Bearer {API_KEY}",
            "Content-Type": "application/json"
        },
        json={
            "userId": user_id,
            "name": name,
            "description": description,
            "platform": platform
        }
    )
    response.raise_for_status()
    return response.json()["playlist"]

def add_tracks_to_playlist(playlist_id, track_ids):
    response = requests.post(
        f"{BASE_URL}/playlists/{playlist_id}/tracks",
        headers={
            "Authorization": f"Bearer {API_KEY}",
            "Content-Type": "application/json"
        },
        json={"trackIds": track_ids}
    )
    response.raise_for_status()
    return response.json()

def build_playlist(genre, user_id, platform="spotify", count=25):
    """End-to-end playlist generation pipeline."""
    print(f"Searching for {genre} tracks...")

    queries = [f"best {genre}", f"new {genre}", f"top {genre} hits"]
    all_tracks = []
    seen = set()

    for q in queries:
        for track in search_tracks(q, limit=30):
            key = f"{track['name'].lower()}_{track['artist'].lower()}"
            if key not in seen:
                all_tracks.append(track)
                seen.add(key)

    random.shuffle(all_tracks)
    selected = all_tracks[:count]

    print(f"Found {len(selected)} unique tracks. Creating playlist...")

    playlist = create_playlist(
        user_id=user_id,
        name=f"{genre.title()} Mix — Auto Generated",
        description=f"A curated {genre} playlist generated with MusicAPI",
        platform=platform
    )

    track_ids = [t["platformId"] for t in selected]
    result = add_tracks_to_playlist(playlist["id"], track_ids)

    print(f"Playlist created with {result['addedCount']} tracks!")
    return playlist

# Run the generator
my_playlist = build_playlist(
    genre="lo-fi hip hop",
    user_id="user_123",
    platform="spotify",
    count=20
)

JavaScript:

const axios = require('axios');

const API_KEY = 'your_musicapi_key';
const BASE_URL = 'https://api.musicapi.com/v1';
const headers = { Authorization: `Bearer ${API_KEY}` };

async function buildPlaylist(genre, userId, platform = 'spotify', count = 25) {
  console.log(`Searching for ${genre} tracks...`);

  const queries = [`best ${genre}`, `new ${genre}`, `top ${genre} hits`];
  const allTracks = [];
  const seen = new Set();

  for (const q of queries) {
    const response = await axios.get(`${BASE_URL}/search`, {
      headers,
      params: { q, type: 'track', limit: 30 }
    });

    for (const track of response.data.tracks) {
      const key = `${track.name.toLowerCase()}_${track.artist.toLowerCase()}`;
      if (!seen.has(key)) {
        allTracks.push(track);
        seen.add(key);
      }
    }
  }

  const shuffled = allTracks.sort(() => Math.random() - 0.5).slice(0, count);
  console.log(`Found ${shuffled.length} unique tracks. Creating playlist...`);

  const { data: { playlist } } = await axios.post(`${BASE_URL}/playlists`, {
    userId,
    name: `${genre.charAt(0).toUpperCase() + genre.slice(1)} Mix — Auto Generated`,
    description: `A curated ${genre} playlist generated with MusicAPI`,
    platform
  }, { headers: { ...headers, 'Content-Type': 'application/json' } });

  const trackIds = shuffled.map(t => t.platformId);
  const { data: result } = await axios.post(
    `${BASE_URL}/playlists/${playlist.id}/tracks`,
    { trackIds },
    { headers: { ...headers, 'Content-Type': 'application/json' } }
  );

  console.log(`Playlist created with ${result.addedCount} tracks!`);
  return playlist;
}

buildPlaylist('lo-fi hip hop', 'user_123', 'spotify', 20);

Next Steps And Ideas

Now that you have a working playlist generator, here are some ideas to take it further:

  • Add mood detection — Use track audio features (tempo, energy, valence) to generate mood-specific playlists like "Chill Evening" or "Morning Workout"
  • Build a web interface — Wrap your generator in a simple web app using Flask (Python) or Express (Node.js) so users can create playlists from their browser
  • Schedule recurring playlists — Set up a cron job that generates fresh playlists weekly using new releases and trending tracks
  • Implement collaborative filtering — Analyze listening history across your user base to recommend tracks that similar listeners enjoy
  • Add cross-platform sync — Let users mirror their favorite playlists across all their streaming accounts automatically

MusicAPI handles the complex platform integrations so you can focus on building great playlist experiences. Check out the full API documentation for additional endpoints covering user libraries, playback history, and audio features.


Ready to build your own playlist generator? Sign up for MusicAPI and start building today — the free tier includes enough requests to prototype and test your application.