If you've ever built anything music-related, you know the pain: you have a
track on one platform — a Spotify ID, an ISRC, whatever — and you need the
same track everywhere else. The Apple Music link. The Tidal ID. The
Beatport release. Plus clean metadata: label, release date, genre.
There's no single, affordable place to get that. And it just got worse:
Spotify has been locking down its API — the thing half of us reached for by
default. Audio features, related artists, recommendations, 30-second previews:
gone or gated. If you're a startup, a hobbyist, or an indie hacker, "apply for
extended access and maybe we'll get back to you" is a non-starter.
So I built SonoVault — a music metadata API that
aggregates open catalog data (Discogs, MusicBrainz, Wikidata, and the MLC)
and enriches it with cross-platform IDs. ~90M tracks. Search them, browse
them, pull artist info, and — the part I actually needed — resolve any ID or
ISRC to links on every supported platform.
The core problem: one track, many IDs
Say you've got Daft Punk's One More Time. Searching is just artist + title:
curl -G "https://api.sonovault.now/v1/tracks/search" \
--data-urlencode "artist=Daft Punk" \
--data-urlencode "title=One More Time" \
-H "x-api-key: YOUR_KEY"
{
"id": "282378616",
"title": "One More Time",
"isrc": "DEND21200535",
"duration": 320,
"genre": ["House"],
"subgenre": ["Electronica"]
}
Now the useful bit. Hand that track ID (or the ISRC, or a Spotify ID) to the
links resolver and you get every platform back in one call:
curl -G "https://api.sonovault.now/v1/tracks/links" \
--data-urlencode "id=282378616" \
-H "x-api-key: YOUR_KEY"
{
"track_id": 282378616,
"title": "One More Time",
"isrc": "DEND21200535",
"links": [
{ "source": "spotify", "external_id": "0DiWol3AO6WpXZgp0goxAV", "url": "https://open.spotify.com/track/0DiWol3AO6WpXZgp0goxAV" },
{ "source": "beatport", "external_id": "6014288", "url": "https://www.beatport.com/track/-/6014288" },
{ "source": "discogs", "external_id": "2844-A", "url": "https://www.discogs.com/release/2844" },
{ "source": "musicbrainz", "external_id": "41829821-316a-46b7-9ba3-82a50296d3bc", "url": "https://musicbrainz.org/recording/41829821-316a-46b7-9ba3-82a50296d3bc" },
{ "source": "applemusic", "external_id": "5468282", "url": "https://music.apple.com/song/5468282" },
{ "source": "tidal", "external_id": "124215", "url": "https://tidal.com/browse/track/124215" },
{ "source": "youtube", "external_id": "0XTLs9IsmCg", "url": "https://www.youtube.com/watch?v=0XTLs9IsmCg" }
]
}
You can start from an ISRC instead — same result, because every ISRC for the
recording resolves to the same track:
curl -G "https://api.sonovault.now/v1/tracks/links" \
--data-urlencode "isrc=DEND21200535" \
-H "x-api-key: YOUR_KEY"
"Listen on / Buy on" buttons in ~10 lines
The thing most people want this for — universal links — is now trivial:
async function getLinks(isrc) {
const res = await fetch(
`https://api.sonovault.now/v1/tracks/links?isrc=${isrc}`,
{ headers: { "x-api-key": process.env.SONOVAULT_KEY } }
);
const { links } = await res.json();
return Object.fromEntries(links.map((l) => [l.source, l.url]));
}
const links = await getLinks("DEND21200535");
// { spotify: "...", applemusic: "...", tidal: "...", beatport: "...", youtube: "..." }
It's not just links — there's metadata too
Artist info: origin, formation, socials
Every artist comes with country, formation year, social handles, and a
Wikidata ID for further linking:
curl "https://api.sonovault.now/v1/artists/1925615" -H "x-api-key: YOUR_KEY"
{
"id": 1925615,
"name": "Daft Punk",
"country": "France",
"formation_year": 1993,
"social_links": {
"website": "https://daftpunk.com",
"twitter": "daftpunk_music",
"instagram": "daftpunk",
"facebook": "daftpunk"
},
"wikidata_id": "Q185828",
"release_count": 888
}
(/v1/artists/search?name=... returns the same shape, so you can go from a
name straight to socials + origin.)
Browse: discover by genre, year, and label
Need "give me some House from 2001" — optionally random — instead of an exact
search? That's the browse endpoint (Starter tier and up):
curl -G "https://api.sonovault.now/v1/tracks/browse" \
--data-urlencode "genre=House" \
--data-urlencode "year=2001" \
--data-urlencode "randomize=true" \
-H "x-api-key: YOUR_KEY"
{
"results": [
{ "title": "Work (Masters At Work Remix)", "artists": [{ "name": "Masters At Work" }], "genre": ["House"] },
{ "title": "Moments in Time (VW20 Mix)", "artists": [{ "name": "Vince Watson" }], "genre": ["House"], "subgenre": ["Deep House"] }
]
}
Filter by any combination of genre (or genreId), year, labelId, and
artistId. Great for radio-style "more like this" features and seeded playlists.
New releases, scoped to a label
Want to follow a label's latest drops? Resolve the label, then page its
releases newest-first:
1. find the label id
curl -G "https://api.sonovault.now/v1/labels/search" \
--data-urlencode "name=Ed Banger" -H "x-api-key: YOUR_KEY"
{ "id": 604, "name": "Ed Banger Records", "release_count": 634 }
2. its newest releases
curl "https://api.sonovault.now/v1/labels/604/releases?limit=5" \
-H "x-api-key: YOUR_KEY"
{
"results": [
{
"id": 130298552,
"title": "SAINT LAURENT WOMEN'S WINTER 26",
"artist": { "id": 1236632, "name": "SebastiAn" },
"label": { "id": 604, "name": "Ed Banger Records" },
"release_date": "2026-05-07",
"track_count": 1
}
],
"next_cursor": "2026-05-07:130298552"
}
The same paginated, newest-first pattern exists for artists
(/v1/artists/:id/releases) — handy for "new from artists you follow" feeds.
The hard part: what counts as "one track"?
This was the real engineering challenge. A single recording exists as a dozen
near-identical rows across sources — radio edit, extended mix, remaster,
compilation reissue — each with its own ID and often its own freshly-minted
ISRC. If I returned all of them, every search would be a wall of duplicates.
So SonoVault collapses similar variants into one canonical track. Search
One More Time and you get one result, not fifteen. Every variant's ISRC
still resolves back to that canonical track, so a lookup from any source lands
in the same place. (Getting the normalization right — without merging genuinely
different recordings — took a lot of iterations.)
What it deliberately doesn't do
Being honest about the boundaries:
- No album art. The cover images are copyrighted by the labels/DSPs.
- No audio previews. Those belong to the streaming services.
It's metadata and cross-platform resolution — not a media CDN.
It's in open beta — kick the tyres
- Free tier: 1,000 requests/month, no credit card.
- Search, ISRC lookup, artist info, label/artist release feeds, and the cross-platform links resolver are all on the free tier. (Browse, charts, and the global new-releases feed unlock on Starter and up.)
- Full docs here.
I'd genuinely love feedback — especially from anyone who's fought with the
Spotify or MusicBrainz APIs. And if you want to stress-test it, reply or
get in touch and I'll bump your limits for free while we're in beta.
Top comments (0)