Migrate from ACRCloud to AudD
Map ACRCloud's signed-request identification model to AudD's token-authenticated HTTP API, with before/after auth and recognition snippets.
This page is for engineers running on ACRCloud who are evaluating AudD as the
recognition backend. Both are cloud audio-fingerprinting services: you send
audio, you get back the recognized track. The two main things that change in
your code are how you authenticate (ACRCloud signs each request with an
HMAC over an access key/secret; AudD takes a single api_token form field)
and which endpoint handles which job (short clip, long file, or live
stream). This guide maps the concepts and shows the equivalent AudD calls.
Concept mapping
| ACRCloud concept | AudD equivalent |
|---|---|
host (region endpoint) | One global host: https://api.audd.io/ (standard) and https://enterprise.audd.io/ (long audio). No per-region host to select. |
access_key + access_secret + HMAC signature | A single api_token form field on every request. No request signing. |
| Identify (recognize) endpoint | POST https://api.audd.io/ — the standard endpoint, for a short audio clip. |
| File Scanning / bucket scanning | POST https://enterprise.audd.io/ — chunks a long file server-side and returns every match. |
| Broadcast / channel monitoring | AudD streams endpoints on api.audd.io (addStream, setCallbackUrl, plus GET /longpoll/). |
| Custom bucket of your own audio | AudD custom catalog (POST api.audd.io/upload/). |
| Metadata (ISRC, UPC, external IDs) | Result fields isrc, upc, plus optional apple_music / spotify / deezer / musicbrainz blocks via return. |
| Official SDKs | 11 official AudD SDKs (Python, Node, Go, Rust, PHP, Swift, Kotlin, .NET, Java, C, C++). |
The equivalent call
Authentication
The biggest code change is auth. ACRCloud requires you to build a signing string and compute an HMAC-SHA1 over your access secret for each request:
# Before — ACRCloud: build an HMAC signature per request
import base64, hashlib, hmac, time, requests
access_key = "your-access-key"
access_secret = b"your-access-secret"
host = "identify-eu-west-1.acrcloud.com"
http_method = "POST"
http_uri = "/v1/identify"
data_type = "audio"
signature_version = "1"
timestamp = str(time.time())
string_to_sign = "\n".join(
[http_method, http_uri, access_key, data_type, signature_version, timestamp]
)
signature = base64.b64encode(
hmac.new(access_secret, string_to_sign.encode(), hashlib.sha1).digest()
).decode()
with open("clip.mp3", "rb") as f:
sample = f.read()
resp = requests.post(
f"https://{host}{http_uri}",
files={"sample": sample},
data={
"access_key": access_key,
"data_type": data_type,
"signature_version": signature_version,
"signature": signature,
"sample_bytes": len(sample),
"timestamp": timestamp,
},
)
print(resp.json())
AudD authenticates with one form field — api_token — and the official SDK
sets it for you from the constructor or the AUDD_API_TOKEN environment
variable. There is no signing string, no timestamp, no HMAC:
# After — AudD: a single api_token, set once
from audd import AudD
audd = AudD("your-api-token") # or reads AUDD_API_TOKEN from the environment
song = audd.recognize("clip.mp3")
if song:
print(f"{song.artist} — {song.title}")
else:
print("no match") # result: null is a successful no-match, not an error
If you call the HTTP endpoint directly instead of through an SDK, the whole
request is a multipart POST with api_token and the audio:
# After — AudD over raw HTTP
curl https://api.audd.io/ \
-F api_token=your-api-token \
-F [email protected] \
-F return=apple_music,spotify
api_tokenis a bearer-style secret — keep it server-side. Because there is no per-request signature, anyone holding the token can spend your quota. Hold it on your backend (or in a secret manager), never in client code. Rotate it from dashboard.audd.io.
Recognizing a short clip
ACRCloud’s identify endpoint and AudD’s standard endpoint both take a short sample and return the top match. AudD’s standard endpoint responds in under 2 seconds, caps the upload at 10 MB, and matches against a database of 160 million songs. Accepted audio formats: MP3, WAV, FLAC, M4A, OGG, AAC, WMA, AIFF.
song = audd.recognize(
"https://audd.tech/example.mp3",
return_metadata=["apple_music", "spotify"],
)
if song:
print(song.artist, "—", song.title)
print("Apple Music:", song.streaming_url("apple_music"))
print("Universal link:", song.song_link)
A successful call that matched nothing returns None (the API sends
result: null). That is distinct from an error — treat it as “try again,”
not as a failure.
Scanning a long file
Where you used ACRCloud’s file-scanning to walk a long recording, use AudD’s enterprise endpoint. It chunks the file server-side and returns every match in order.
matches = audd.recognize_enterprise(
"https://audd.tech/example.mp3",
limit=10, # stop after 10 matches; ALWAYS set this in development
)
for m in matches:
print(m.timecode, m.artist, "—", m.title, m.isrc)
Always set
limiton enterprise calls during development. The enterprise endpoint bills per 12 seconds of audio processed. An unbounded call on a multi-hour file ingests the whole thing.limit=Nstops after N matches.
Monitoring a broadcast or live stream
Where you used ACRCloud’s broadcast monitoring, use AudD’s streams endpoints. You register a callback URL and add a stream; AudD recognizes songs as they play and POSTs each match to your callback.
audd.streams.set_callback_url("https://your-server.example/audd-callback")
audd.streams.add(url="twitch:somechannel", radio_id=1)
radio_id is an integer you choose — not a name. Unlike ACRCloud’s
string stream keys, it’s a number you assign to each stream and that comes
back on every callback so you can tell streams apart.
The stream URL accepts direct stream URLs (HLS, Icecast, m3u/m3u8) and the
shortcuts twitch:<channel>, youtube:<video_id>, and
youtube-ch:<channel_id>. If you cannot host a public callback URL, poll
GET /longpoll/ instead (audd.streams.longpoll(...)).
What’s different
- Authentication model. ACRCloud signs each request with an access
key/secret and an HMAC signature (plus a timestamp). AudD uses a single
api_tokenform field with no request signing. Less code on your side; also means the token must be protected like any bearer secret. - Endpoint selection. ACRCloud separates products by use case (identify, file scanning, broadcast monitoring) and by region host. AudD uses one standard host for clips, one enterprise host for long audio, and the streams endpoints for live monitoring — with no region host to choose.
- No-match signal. AudD returns
status: "success"withresult: nullon a clean no-match, distinct from anerrorresponse. Branch on that explicitly so a quiet clip isn’t treated as a failure. - Enterprise billing unit. AudD’s enterprise endpoint bills per 12
seconds of audio processed and expects a
limit. Budget around audio duration, not just request count. - Custom audio. ACRCloud lets you scan against your own buckets; AudD
lets you upload your own tracks to a custom catalog
(
POST api.audd.io/upload/, access gated — email [email protected]). A custom-catalog match returnsaudio_id, andartist/titlemay be null if you didn’t supply them at upload time. - Metadata fields. AudD returns
artist,title,album,release_date,label,timecode,song_link, and (on enterprise calls or Startup-plan-and-above accounts)isrcandupc. Provider blocks (apple_music,spotify,deezer,musicbrainz) are returned only when you request them viareturn. - Pricing visibility. AudD’s per-request pricing is public: 300 free requests on signup with no card, then $5 per 1,000 requests pay-as-you-go, with volume plans listed on the dashboard.
- SDK coverage. AudD ships 11 official SDKs, so the same auth and recognition contract is available across languages without hand-rolling a client.
Migration steps
- Get an AudD token. Sign up at
dashboard.audd.io (300 free requests, no
card) and copy the
api_token. - Install the SDK for your language. For example,
pip install audd,npm install @audd/sdk, orgo get github.com/AudDMusic/audd-go. See the SDK docs for all 11. - Replace the signing code with the token. Delete the HMAC/signature
builder and the
access_key/access_secret/timestampform fields. Construct the client withapi_token(or setAUDD_API_TOKEN). - Map each call site to an endpoint. Identify → standard
recognize(...). File scanning →recognize_enterprise(..., limit=N). Broadcast monitoring → streams (set_callback_url+add), orlongpollif you can’t host a callback. - Re-map the response fields. Point your code at AudD’s result schema
(
artist,title,album,release_date,label,timecode,isrc,upc,song_link, and provider blocks). Add an explicitresult == nullbranch for no-match. - Move custom audio, if any. If you relied on ACRCloud buckets of your
own tracks, request custom-catalog access (email [email protected]) and upload
via
POST api.audd.io/upload/. - Verify with a fixed file. Run a known input
(
https://audd.tech/example.mp3) through each migrated path and confirm the fields you depend on are present before switching production traffic.
Related
Reading this as an AI agent? The raw Markdown is at migrate/from-acrcloud.md, and the full index is /resources/llms.txt.
