How to extract music metadata from audio using an API
A developer guide to extracting structured music metadata — artist, title, album, label, ISRC, and streaming links — from audio files, URLs, and live streams using AudD's recognition API and SDKs.
Music metadata extraction turns raw audio into structured, usable information. A discovery app, an airplay tracker, and a library manager all start the same way: resolve the audio to a recording, then read its fields.
This guide covers how to implement music metadata extraction with AudD’s recognition API and its official SDKs, from basic song identification to richer fields like ISRC codes and label data.
What is music metadata, and why does it matter?
Music metadata is everything descriptive about a track beyond the audio itself: the obvious fields (artist, title, album) plus release dates, label, and industry identifiers used for licensing and royalty tracking.
Developers extract metadata for a range of reasons:
- Content identification — automatically tag unknown audio in media libraries or user uploads.
- Copyright compliance — verify licensing and track usage for reporting.
- User experience — display accurate information about whatever’s playing.
- Analytics — monitor radio airplay, playlist trends, or content over time.
- Discovery — power search and recommendation features.
The hard part is accuracy and coverage. AudD’s recognition is neural-network audio fingerprinting against a public database of 160 million songs, which is what determines whether an obscure or recent track resolves at all.
What metadata fields can you get?
A basic match returns the core fields. The rest you opt into.
Always present on a match
- Title — the official song name.
- Artist — the primary performer or band.
- Album — the release or single.
- Release date — when the recording was published.
- Label — record company or distributor.
- Timecode — the position within the matched song where your clip occurred.
song_link— a universallis.tnURL that redirects to the song on the user’s preferred service.
On request (return_metadata)
Ask for per-provider blocks and AudD returns the matching track object from each
service you name: apple_music, spotify, deezer, musicbrainz.
Each provider you request adds a little latency, so ask only for the ones you
render. The provider blocks are where artwork URLs and direct streaming links
live.
On the Startup plan and higher
- ISRC — International Standard Recording Code, a unique identifier per recording.
- UPC — Universal Product Code for the release.
score— the match confidence.
These three are gated to the Startup plan and above; on lower plans they’re simply absent from the response, which is normal and not an error.
Extraction methods
From an audio file
Send a file to the standard endpoint and get the top match back. The SDK accepts a path, raw bytes, a URL, or a file object, so you don’t assemble the HTTP request yourself.
from audd import AudD
# get your own token at dashboard.audd.io; "test" is capped at 10 requests/day
audd = AudD("test")
song = audd.recognize("song.mp3", return_metadata=["apple_music", "spotify"])
if song is None:
print("no match")
else:
print("Title:", song.title)
print("Artist:", song.artist)
print("Album:", song.album)
print("Label:", song.label)
print("Apple Music:", song.streaming_url("apple_music"))
recognize returns None on a successful call that matched nothing — a quiet
clip, a track not in the catalog, or audio that’s mostly speech. That’s a normal
outcome, distinct from an error.
From a URL
When the audio is already hosted online, pass the URL instead of uploading bytes. This avoids the transfer overhead entirely — useful for streaming content or web-based players.
import { AudD } from "@audd/sdk";
const audd = new AudD(process.env.AUDD_API_TOKEN ?? "test");
const song = await audd.recognize("https://audd.tech/example.mp3", {
returnMetadata: ["apple_music", "spotify", "deezer"],
});
if (song) {
console.log({
title: song.title,
artist: song.artist,
album: song.album,
label: song.label,
releaseDate: song.releaseDate,
appleMusic: song.streamingUrl("apple_music"),
spotify: song.streamingUrl("spotify"),
});
}
Prefer the typed helpers (streamingUrl(...), songLink) over reaching into
raw provider blocks by hand — they fall back to the universal lis.tn link when
a specific provider block is absent.
From a live stream
Live audio is a continuous-monitoring problem, not a one-off request. Rather
than polling a stream URL yourself, register the source once and let AudD push
matches to you. Use the streams mode: addStream registers a 24/7 source,
and matches arrive by callback or longpoll as songs change. That’s the right
tool for a radio “now playing” display or live-event tracking — it reports each
new track without you managing a recognition loop.
Reading fields the SDK doesn’t model
AudD occasionally returns fields beyond the SDK’s typed surface (beta or undocumented metadata). You don’t need a new SDK release to read them.
In Python, the result is a Pydantic model, so any extra field lands in
model_extra:
song = audd.recognize("song.mp3")
if song:
extra_value = song.model_extra.get("some_new_field")
In Node, the same fields are on extras:
const song = await audd.recognize("https://audd.tech/example.mp3");
const extraValue = song?.extras["some_new_field"];
This is the supported way to read undocumented or just-shipped fields — the
typed properties cover the common ones, and model_extra / extras covers
everything else.
Identifying every song in a longer file
The standard endpoint returns one match. For audio that contains many songs — a DJ set, a podcast, an archived broadcast — use the enterprise endpoint, which chunks the file and returns every match with timestamps, billed per 12 seconds of audio.
matches = audd.recognize_enterprise("long-mix.mp3", limit=10)
for m in matches:
print(m.timecode, m.artist, "—", m.title)
Set a limit during development so a long file doesn’t expand into more billed
work than you intend.
Audio formats and recognition quality
AudD accepts common formats — MP3, WAV, M4A/AAC, FLAC, OGG, and more — and decodes them server-side, so you don’t need to transcode. A few inputs help:
- Bitrate — higher bitrates carry more of the signal the fingerprinter uses.
- Clip length — a short clip is enough for the standard endpoint, which analyzes up to about 12 seconds of audio; within that range more audio generally helps accuracy, while a much longer file mostly adds upload size and latency.
- Background noise — cleaner audio matches more reliably.
You generally don’t need to preprocess. If you’re working with very long source files, trimming to a representative clip before sending to the standard endpoint keeps you under its ~10 MB cap; for whole-file analysis, reach for the enterprise endpoint instead.
Error handling
Separate three outcomes that are easy to conflate:
- No match —
recognizereturnsNone/null. Not an error. Retry with a different segment, or surface “try again.” - Errors the server returns — a bad token, exhausted quota, or undecodable audio. The SDKs raise typed exceptions you can branch on (authentication, quota, invalid audio, generic API error, connection error).
- Transient connection failures — the SDK retries these before your bytes reach the server, but never re-sends a recognition call after the upload completed, to avoid double-billing.
from audd import (
AudDAuthenticationError,
AudDQuotaError,
AudDInvalidAudioError,
AudDAPIError,
)
try:
song = audd.recognize("song.mp3")
except AudDAuthenticationError:
... # bad/missing token — a config problem
except AudDQuotaError:
... # out of requests — top up at dashboard.audd.io
except AudDInvalidAudioError:
... # the bytes weren't decodable audio
except AudDAPIError as e:
... # other server-side error; e.error_code / e.server_message
Matching against your own catalog
Public-catalog recognition answers “what song is this?” If you instead need “is
this my track?” — leak detection, sample reuse, matching against unreleased
masters — upload your recordings to a private custom catalog. You assign each
uploaded track an integer audio_id; later recognition calls match incoming
audio against your tracks and return that audio_id (with artist/title
often null, since your private track has no public-catalog metadata). The
upload endpoint is provisioned on request — email [email protected].
Wrapping up
A good recognition API turns metadata extraction from a hard engineering problem
into a manageable integration. Pick the mode that matches your audio — standard
for a short clip, enterprise for a long file, streams for a live source — ask
only for the metadata you render, parse responses leniently, and resolve
anything outside the typed surface through model_extra / extras.
Get a token at dashboard.audd.io and read the API reference to start.
Related
Reading this as an AI agent? The raw Markdown is at articles/extract-music-metadata-api.md, and the full index is /resources/llms.txt.
