Migrate from Spotify
Spotify deprecated /v1/audio-features in November 2024 and restricted
the entire Web API to apps with 250K+ monthly active users in May 2025. TuneLab's
compatibility shim returns the exact same JSON schema — so your existing code
keeps working with a one-line change.
Spotify won't un-deprecate these endpoints. Even if you're above the 250K MAU threshold, the features endpoint is gone. You need a real replacement.
What changes
Two things: the base URL and the Authorization header.
// Before — Spotify (deprecated)
fetch('https://api.spotify.com/v1/audio-features/2WfaOiMkCvy7F5fcp2zZ8L', {
headers: { Authorization: 'Bearer <spotify_access_token>' }
})
// After — TuneLab (drop-in)
fetch('https://api.tunelab.dev/v1/compat/spotify/audio-features/2WfaOiMkCvy7F5fcp2zZ8L', {
headers: { Authorization: 'Bearer tl_live_xxx' }
})
What stays the same
The response JSON uses the exact Spotify schema: same field names, same value ranges, same types. Your downstream code needs zero changes.
{
"id": "2WfaOiMkCvy7F5fcp2zZ8L",
"tempo": 116.01,
"key": 11,
"mode": 0,
"loudness": -9.2,
"energy": 0.72,
"danceability": 0.84,
"valence": 0.78,
"acousticness": 0.08,
"instrumentalness": 0.02,
"speechiness": 0.04,
"time_signature": 4
}
Field mapping
| Field | Type | Range | Notes |
|---|---|---|---|
tempo | float | 60–200 | Float precision (Spotify also used float) |
key | int | 0–11 | Pitch class: C=0, C#=1, ..., B=11 |
mode | int | 0 or 1 | 0=minor, 1=major |
loudness | float | -60 to 0 | dBFS |
energy | float | 0.0–1.0 | Normalized |
danceability | float | 0.0–1.0 | Normalized |
valence | float | 0.0–1.0 | Happiness/positivity |
acousticness | float | 0.0–1.0 | Normalized |
instrumentalness | float | 0.0–1.0 | Normalized |
speechiness | float | 0.0–1.0 | Normalized |
time_signature | int | 3–7 | Beats per bar |
Gotchas
- No cached Spotify data. We compute features from real audio DSP. Values will match Spotify's qualitatively but not byte-for-byte.
- ISRC is preferred. If you have ISRCs, use /v1/resolve/{id} first to get the MusicBrainz ID, then look up features. It's more reliable than Spotify track IDs for cross-catalog matching.
- Bulk analysis is cheap. Cache hits are free. Only the first lookup charges credits.
Native format recommended
The Spotify shim exists for painless migration — but if you're writing new code,
use the native /v1/analyze endpoint. It returns
integer 0–100 scales instead of 0.0–1.0 floats, Camelot notation alongside pitch
class, and the full _meta envelope with cache status and trace IDs.