Identify any track
from audio
Send a clip — or a fingerprint — and get the matching track back with ISRC, artist, release, genre, and cross-platform IDs. One REST call, across 90M+ tracks.
Send audio or a fingerprint
POST a short audio clip as raw bytes and we fingerprint it for you — or generate a Chromaprint fingerprint locally and send the integer array as JSON.
We match the acoustic fingerprint
Your clip is matched against an acoustic index spanning 90M+ tracks — robust to bitrate, format, and encoding differences.
Get the track + full metadata
You get back the matching catalog track — same shape as a search result, with ISRC, release, label, genre, and platform IDs ready to use.
Server-side
The simplest call: send the raw audio file and we do the fingerprinting. Keep your API key on the server.
# Send the raw audio file — we fingerprint it for youcurl -X POST https://api.sonovault.now/v1/tracks/identify \-H "x-api-key: YOUR_API_KEY" \-H "Content-Type: application/octet-stream" \--data-binary @song.mp3
import { readFile } from "node:fs/promises";const audio = await readFile("song.mp3");const res = await fetch("https://api.sonovault.now/v1/tracks/identify", {method: "POST",headers: {"x-api-key": process.env.SONOVAULT_API_KEY, // keep your key server-side"Content-Type": "application/octet-stream",},body: audio,});const { matched, results } = await res.json();if (matched) {const track = results[0]; // results are plain tracksconsole.log(`${track.artists[0].name} — ${track.title} (${track.isrc})`);}
Prefer not to upload audio? Fingerprint locally with Chromaprint's fpcalc and send the integer array — ~1 KB instead of a file.
# Or fingerprint locally with Chromaprint's fpcalc and send the raw int arrayfpcalc -raw -length 30 song.mp3 # -> FINGERPRINT=1,2,3,...curl -X POST https://api.sonovault.now/v1/tracks/identify \-H "x-api-key: YOUR_API_KEY" \-H "Content-Type: application/json" \-d '{"fingerprint":[1,2,3,4,5]}'
In the browser
From a web app, let the user pick a file and send the bytes to your own backend, which adds the API key and forwards them to SonoVault. The browser never sees your key.
<input type="file" accept="audio/*" id="audio" /><script type="module">document.getElementById("audio").addEventListener("change", async (e) => {const file = e.target.files[0];if (!file) return;// POST the raw bytes to YOUR backend — never put your API key in the// browser. Your backend forwards it to SonoVault (see the proxy below).const res = await fetch("/api/identify", {method: "POST",headers: { "Content-Type": "application/octet-stream" },body: file,});const { matched, results } = await res.json();document.title = matched? `${results[0].artists[0].name} — ${results[0].title}`: "No match";});</script>
// Your backend route — adds the secret key and forwards the audio.export async function POST(req) {const audio = await req.arrayBuffer();const res = await fetch("https://api.sonovault.now/v1/tracks/identify", {method: "POST",headers: {"x-api-key": process.env.SONOVAULT_API_KEY,"Content-Type": "application/octet-stream",},body: audio,});return new Response(res.body, { headers: { "Content-Type": "application/json" } });}
The response
results is a ranked array of plain track objects — the same shape returned by track search — best match first. matched is false with an empty array when nothing matches.
{"matched": true,"results": [{"id": 121217599,"title": "Harder, Better, Faster, Stronger","artists": [{ "id": 9001, "name": "Daft Punk", "is_primary": true }],"releases": [{ "id": 4242, "title": "Discovery", "release_date": "2001-03-12" }],"isrc": "GBDUW0000059","duration": 224,"genre": ["Electronic"],"subgenre": ["French House"]}],"credits_charged": 10}
Identify tracks right in your dashboard
Logged-in users get an Identify tool in the dashboard — drop in an audio file and get the matching track back instantly. It runs the same recognition as the API, billed against your account's default key.