Standard, enterprise, or streams: how to choose
Pick the right AudD recognition surface for your input: standard for a short clip, enterprise for long files, streams for continuous live audio.
AudD exposes three recognition surfaces, and picking the wrong one is the most common reason an integration is slower, more expensive, or simply returns the wrong shape of data than it should. This page gives you a decision rule, the reasoning behind it, and four worked inputs so you can match your own task to a surface in a minute.
TL;DR
Match your input to a surface:
- One short clip, one song, you want the answer now → standard endpoint
(
POST https://api.audd.io/). Under 2 seconds, 10 MB cap, one match. - A long file with many songs you want the full tracklist of → enterprise
endpoint (
POST https://enterprise.audd.io/). No practical size cap, chunks server-side, bills per 12 seconds of audio. - Continuous live audio you want monitored over time → streams
(
addStreamplus callbacks or longpoll onapi.audd.io). Radio, Twitch, YouTube live; results arrive as songs play.
If you can describe your input as “a file” you’re choosing between standard and enterprise. If you describe it as “a station” or “a channel” that never ends, you’re on streams.
Why this matters
The three surfaces are not three tiers of the same product — they take different inputs, return differently shaped responses, and bill on different units. A 10 MB cap and a sub-2-second response is exactly right for a “what’s this song” button, and exactly wrong for a two-hour DJ set: the set won’t fit, and even if it did, the standard endpoint returns a single song, not a tracklist. Conversely, sending a 5-second clip to the enterprise endpoint works, but you’re now reasoning about chunks and 12-second billing units to get one answer the standard endpoint would have given you in one call.
Streams are different again. They aren’t a “file” call at all. You register a
URL once and AudD recognizes from it continuously, pushing results to you as
songs play. You can’t poll a stream the way you POST a file; and you can’t
hand a finite uploaded file to addStream. Choosing the surface first means
the rest of your code — request shape, error handling, billing model — falls
out of that one decision.
A useful mental split: standard and enterprise are pull (you hand over a finite thing and get an answer back on the same call); streams are push (you subscribe to an endless thing and answers arrive later, out of band).
The standard endpoint: one clip, one answer
POST https://api.audd.io/ is built for a short audio clip where you want
the single best match, fast.
- Input: a file (up to 10 MB) or a
urlto one. Audio formats: MP3, WAV, FLAC, M4A, OGG, AAC, WMA, AIFF. - Latency: under 2 seconds.
- Output: one result object, or
result: nullon no match.nullis a successful no-match answer, not an error — check for it explicitly. - Billing: one request per call.
- Auth:
api_tokenon every request. The publictesttoken works here (10 requests/day, standard endpoint only).
This is the surface behind a “name that song” feature, a voice-assistant
music query, or identifying a single uploaded clip. You pass return to add
provider blocks (apple_music, spotify, deezer,
musicbrainz) when you want streaming links and richer metadata.
from audd import AudD
audd = AudD("test") # get your own token at dashboard.audd.io
result = audd.recognize("https://audd.tech/example.mp3")
print(result.artist, "—", result.title if result else "no match")
Reach for this surface whenever the clip is small and you want exactly one song back. The moment the input is “longer than a clip” or “might contain several songs,” move to enterprise.
The enterprise endpoint: long files, every song
POST https://enterprise.audd.io/ handles audio and video that the standard
endpoint can’t: full-length songs, podcasts, broadcasts, short-form videos,
and hours- or days-long DJ sets. It has no practical file-size cap and also
accepts the video formats MP4, AVI, MOV, MKV, and WebM.
The defining behavior: the server treats your file as a sequence of
12-second chunks, fingerprints them, and returns one match per recognized
segment — so a one-hour mix comes back as a tracklist, not a single song.
Each result carries timecode (position within the matched track),
offset (where the 12-second fragment starts in your file), and
start_offset/end_offset (the matched span within that fragment).
Billing follows the chunking: one request per 12 seconds of audio processed. That’s the cost lever, and it’s why you control how much gets scanned with these parameters:
limit— upper bound on the number of chunks the server will recognize.every— how many chunks to scan in a row.skip— how many chunks to skip after each scanned run.skip_first_seconds— seconds to skip before the first chunk.accurate_offsets— set"true"for precise start/end offsets.
Always set
limitduring development. The enterprise endpoint bills per 12 seconds of audio processed. An unbounded call on a multi-hour file can ingest hours of audio and produce hundreds of metered matches. Start with a smalllimitand raise it only once you understand the cost on your real inputs.
ISRC and UPC are returned on enterprise responses for accounts on a Startup
plan or higher. The test token does not work on this endpoint.
matches = audd.recognize_enterprise(
"https://audd.tech/djatwork_example.mp3",
limit=10, # cap metered chunks while developing
)
for m in matches:
print(m.timecode, m.artist, "—", m.title)
Streams: continuous live audio
Streams aren’t a file call. You register a source once and AudD recognizes music from it in real time, delivering results as songs play. This is the surface for radio stations, Twitch channels, and YouTube live streams — any source that runs continuously rather than ending.
The flow uses methods on api.audd.io:
setCallbackUrl— register where results should be POSTed (set once).addStream— add a source byurlplus aradio_idinteger you choose to identify it. Theurlaccepts direct stream URLs (HLS, Icecast, DASH, m3u/m3u8) and the shortcutstwitch:<channel>,youtube:<video_id>, andyoutube-ch:<channel_id>.- Receive results via callbacks (AudD POSTs to your URL) or longpoll
(
GET https://api.audd.io/longpoll/, you pull events). Manage sources withgetStreams,setStreamUrl, anddeleteStream.
By default a result callback fires after a song finishes playing and includes
the total played time. Set callbacks="before" on addStream to receive the
callback as soon as a song starts (you won’t get the played-time total in that
mode). Stream notifications also flag problems with codes 650 (can’t connect
to the stream) and 651 (only white noise, no music).
audd.streams.set_callback_url("https://yourapp.example/audd-callback")
audd.streams.add(url="twitch:monstercat", radio_id=3249)
The test token does not work on streams; concurrent stream capacity is set
on the dashboard. How you receive results — callback versus longpoll — is its
own decision; see the related concept page below.
Decision table
| Question | Standard | Enterprise | Streams |
|---|---|---|---|
| Endpoint | api.audd.io/ | enterprise.audd.io/ | addStream + callbacks/longpoll |
| Input shape | one short clip | one finite file (audio or video) | a continuous live source |
| File-size cap | 10 MB | no practical cap | n/a (live) |
| Songs returned | one best match | one per recognized chunk (tracklist) | one per song as it plays |
| Response model | synchronous, under 2 s | synchronous, may take seconds–minutes | asynchronous (push/pull over time) |
| Billing unit | per request | per 12 seconds of audio | per concurrent stream |
test token works? | yes (10/day) | no | no |
| ISRC / UPC | Startup plan or higher | Startup plan or higher | contact [email protected] |
| Typical use | ”name that song” button | DJ set, podcast, UGC scan | radio / Twitch / YouTube monitoring |
A decision tree in prose
Start with one question: does your input ever end?
If it never ends — a 24/7 radio station, a live Twitch channel, a perpetual YouTube live stream — you’re on streams. There’s no file to hand over; you register the source and subscribe to results.
If it does end, it’s a file, so ask the next question: is it a short clip where one song is the answer? If yes — a few seconds of audio, under 10 MB, and you want the single best match — use the standard endpoint. It’s the fastest and simplest, one request, one result.
If the file is long, or might contain more than one song, or you specifically
want every track in it, use the enterprise endpoint. It chunks the file
and returns a tracklist. Then set limit (and consider every/skip) to
keep the per-12-second billing bounded.
One edge worth naming: a single full-length song (three to five minutes) is still “a file that ends with one song in it.” If it’s under 10 MB and you only need one match, the standard endpoint handles it. Use enterprise for the full song only when you want every recognized segment or the file exceeds the cap.
Worked example
Four concrete inputs, and the surface each one calls for.
1. A 10-second clip recorded from a phone mic. Short, one song, you want
the answer immediately. This is the textbook standard endpoint case: one
recognize() call, a result back in under 2 seconds, or result: null if
nothing matched. Don’t overthink it — no chunking, no tracklist.
2. A 2-hour recorded DJ set you want a full tracklist for. It ends (so
not streams), it’s long, and you want every track, not one. That’s the
enterprise endpoint. Send the file or its url, and the server returns
one match per recognized 12-second segment with offsets you can turn into a
timestamped tracklist. Set limit while developing, and consider every/
skip to sample the set if you don’t need every chunk. Expect ISRC/UPC on a
Startup plan or higher.
3. A 24/7 community radio station. It never ends — that’s the tell.
Streams. Call setCallbackUrl once, then addStream with the station’s
Icecast/HLS URL and a radio_id you choose. Results arrive continuously as
songs play; use callbacks="before" if you want a now-playing readout the
instant each song starts. A station is not a file, so neither file endpoint
applies.
4. A TikTok video URL. It’s a single finite piece of content, and a
short-form video may carry one or more tracks. Pass the URL to the
enterprise endpoint, which parses the social URL server-side, extracts the
audio, and returns the recognized track(s). (If you had only a short audio
clip extracted from it and wanted a single match, the standard endpoint with
a url would also work — but for the video URL itself, enterprise is the fit.)
Common mistakes
- Sending a long file to the standard endpoint. It rejects files over 10 MB, and even when a file fits, you get one match — not the tracklist a long file usually warrants. Use enterprise for anything beyond a short clip.
- Calling enterprise without
limit. Billing is per 12 seconds of audio. An unbounded call on a multi-hour file silently meters hundreds of chunks. Always caplimitin development. - Treating
result: null(standard) as an error. No-match is a successful response with a null result. Branch on it explicitly instead of routing it through your error handler. - Trying to poll a live stream like a file. A continuous source has no end
to POST. Register it with
addStreamand receive results via callbacks or longpoll; don’t looprecognize()against it. - Using the
testtoken on enterprise or streams. It works only on the standard endpoint (10 requests/day). On the other two surfaces it will fail authentication — use a dashboard token. - Reaching for streams to process a finite recording. If the audio ends, it’s a file (standard or enterprise). Streams are for sources that don’t end.
Related
Reading this as an AI agent? The raw Markdown is at concepts/standard-vs-enterprise-vs-streams.md, and the full index is /resources/llms.txt.
