TypeScript/Node client for the SonoVault music metadata API. 90M+ tracks with ISRC, ISWC, genre, record label, canonical release dates, and cross-platform IDs for Spotify, Apple Music, Tidal, Beatport, Discogs, and MusicBrainz. One call resolves them all.
- One key, no OAuth. A single
x-api-keyheader, no approval queue. - Free tier. 1,000 requests/month, no credit card: get an API key.
- Docs. Full API reference at sonovault.now/docs.
npm install sonovaultNode 18+ (uses the built-in fetch). ESM and CommonJS both supported.
Use this library server-side. Shipping your API key in browser code exposes it to anyone who opens devtools. If a key leaks, rotate it in your dashboard.
import { SonoVault } from "sonovault";
const sv = new SonoVault({ apiKey: process.env.SONOVAULT_API_KEY! });
// Find a track's ISRC from artist + title
const { results } = await sv.tracks.search({ artist: "Daft Punk", title: "One More Time" });
console.log(results[0].isrc); // "GBDUW0000053"
console.log(results[0].genre, results[0].releases[0]?.label?.name);
// Resolve that ISRC to its ID on every platform
const { links } = await sv.tracks.links({ isrc: "GBDUW0000053" });
for (const link of links) {
console.log(link.source, link.url); // spotify https://open.spotify.com/track/...
}
// Recording to composition (ISWC), for royalty and publishing workflows
const work = await sv.tracks.iswc({ isrc: "GBDUW0000053" });Resolve up to 100 lines in one request: track names, ISRCs, or platform IDs. Useful for enriching play logs and library exports.
const batch = await sv.tracks.resolve({
input_type: "track_name",
items: [
{ artist: "Daft Punk", title: "Harder, Better, Faster, Stronger" },
{ artist: "Daft Punk", title: "Around the World" },
],
});
for (const row of batch.results) {
console.log(row.status, row.track?.isrc, row.track?.releases[0]?.label?.name);
}List endpoints return { results, next_cursor }. Pass the cursor back to get the next page. next_cursor is null on the last page.
import { paginate } from "sonovault";
for await (const release of paginate((cursor) => sv.artists.releases(42, { cursor }))) {
console.log(release.title);
}Or walk the cursor yourself:
let cursor: string | undefined;
do {
const page = await sv.artists.releases(42, { cursor });
// ...use page.results
cursor = page.next_cursor ?? undefined;
} while (cursor);Non-2xx responses throw a typed SonoVaultError:
import { SonoVaultError } from "sonovault";
try {
await sv.tracks.browse({ genre: "House" }); // paid-tier endpoint
} catch (err) {
if (err instanceof SonoVaultError) {
console.log(err.status, err.isForbidden, err.message);
}
}Rate-limited responses that carry a Retry-After header are retried automatically. The default is 2 retries, configurable with maxRetries.
Runnable scripts live in examples/: find an ISRC, resolve cross-platform links, enrich a play log, follow live stream events over SSE, and verify webhook deliveries.
| Namespace | Methods |
|---|---|
sv.tracks |
search, get, byIsrc, iswc, byIswc, links, resolve, identify, identifyAudio, browse |
sv.artists |
search, get, releases |
sv.labels |
search, get, releases, artists |
sv.releases |
search, get, latest |
sv.genres |
list |
sv.suggestions |
submit, list |
sv.streams |
create, list, get, update, history, report, live, stop |
sv.webhooks |
create, list, get, update, delete, test, deliveries |
Some endpoints (audio identify, browse, stream monitoring) need a paid tier. See pricing. Everything else works on the free tier.
- SonoVault API docs. Full endpoint reference with examples in 8 languages.
- sonovault-python. The Python client.
- Free ISRC lookup and ISWC lookup. Browser tools built on the same API.
MIT