DEV Community

Freqblog
Freqblog

Posted on

Spotify's audio_features API died in 2024. Here's what I built to replace it

Spotify's audio_features API died in 2024. Here's what I built to replace it.

If you've used spotipy to pull BPM, key, energy or danceability for tracks, you've already hit the wall. Spotify quietly deprecated their audio-features endpoint in November 2024. No replacement. No migration path. Just a 403.

I needed these features for an algo trading dashboard project (don't ask). After finding nothing usable in the market, I built my own.

What the market looked like

I spent a week evaluating alternatives:

MeloData — Essentia-based (same engine I ended up using), but ISRC-only lookup. If you don't have an ISRC for every track, you're stuck. Priced per-request at $0.002 which sounds cheap until you're running a catalog.

GetSongBPM — Free, name-based, but only BPM and key. No energy, loudness, mood, danceability. Missing half the fields I needed.

Cyanite — Mood-focused, $0.01/track, upload-only. Great for what it does but expensive at scale and no name-based lookup.

Soundcharts / Chartmetric — Enterprise ($250+/mo), overkill, different problem space.

AcousticBrainz — What I actually wanted. Shut down in 2022.

None of them did what Spotify did: give you all the audio features for a track just by passing artist + title.

What I built

A REST API with name-based lookup, file upload analysis, and 17+ fields per track:

  • BPM + confidence
  • Musical key + mode (major/minor) + Open Key notation
  • Time signature
  • Energy, loudness (dBFS)
  • Danceability, valence, acousticness, instrumentalness, liveness, speechiness
  • Mood (happy/sad/aggressive/relaxed/party)
  • Genre, gender (vocal type), timbre
  • Popularity score

Stack:

  • MTG-Essentia RhythmExtractor2013 for BPM, KeyExtractor for key
  • Librosa for energy, loudness, and the Phase 2 descriptors
  • AcousticBrainz 7.5M-track fallback for mood, genre, highlevel features
  • FastAPI + SQLite (WAL mode) for caching — cache hits return in < 100ms
  • Zero disk writes — audio processed from io.BytesIO

The migration

If you were using Spotify's audio-features, the switch looks like this:

Before (Spotify):

import spotipy

sp = spotipy.Spotify(auth_manager=SpotifyClientCredentials())
features = sp.audio_features("4uLU6hMCjMI75M1A2tKUQC")[0]
print(features["tempo"], features["key"], features["energy"])
Enter fullscreen mode Exit fullscreen mode

After (FreqBlog API):

import requests

resp = requests.get(
    "https://api.freqblog.com/lookup",
    params={"track": "Blinding Lights", "artist": "The Weeknd"},
    headers={"X-API-Key": "your_api_key"}
)
features = resp.json()
print(features["bpm"], features["key"], features["energy"])
Enter fullscreen mode Exit fullscreen mode

Field mapping:

Spotify FreqBlog API
tempo bpm
key (0-11 int) key ("C-Major", "F#-Minor")
energy energy (0-1)
loudness loudness (dBFS)
danceability danceability (0-1)
valence valence (0-1)
instrumentalness instrumentalness (0-1)
mode mode ("major"/"minor")
speechiness speechiness (0-1)
time_signature time_signature (int)

Plus fields Spotify never had: mood, genre, open_key (Camelot notation), timbre, popularity.

Pre-analyzed catalog + fallback

The API doesn't re-analyze everything on every call. There's a nightly ingest that pulls from Apple Music charts (GB/US/AU Top 100, IE/CA Top 50) plus ~100 genre seed categories. Anything in the catalog returns in under 100ms.

For anything not in the catalog, it falls back to the AcousticBrainz 7.5M-track dataset for highlevel features. As a last resort, it can analyze an uploaded audio file directly.

BPM and Key search endpoints

Two endpoints the original Spotify API never had:

# Find tracks near 128 BPM
GET /bpm?q=128&tolerance=2&limit=10

# Find tracks in 8A (Am) by Camelot wheel key
GET /key?q=8A&limit=10
Enter fullscreen mode Exit fullscreen mode

Useful for DJ tools, playlist generation, music recommendation engines.

MCP server

I also shipped an MCP server (music-metadata-mcp) so Claude and other LLMs can call it directly:

npx music-metadata-mcp --api-key=your_key
Enter fullscreen mode Exit fullscreen mode

Tools: lookup_track, find_tracks_by_bpm, find_tracks_by_key, bulk_lookup.

Pricing

  • Free: 500 req/mo (good for side projects)
  • Hobbyist: £9.99/mo — 3,000 req/mo
  • Starter: £39/mo — 20,000 req/mo
  • Professional: £129/mo — 150,000 req/mo

Free key: freqblog.com/music-api.html

OpenAPI docs: api.freqblog.com/docs


Built this because I needed it. If you're porting off Spotify's deprecated endpoints or building anything music-analysis related, happy to answer questions.

Tags: API, Python, Music, Audio, Spotify, Developer Tools

Top comments (0)