Migrate

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.

view .md auddacrcloudmigrationmusic recognition api

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 conceptAudD 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 signatureA single api_token form field on every request. No request signing.
Identify (recognize) endpointPOST https://api.audd.io/ — the standard endpoint, for a short audio clip.
File Scanning / bucket scanningPOST https://enterprise.audd.io/ — chunks a long file server-side and returns every match.
Broadcast / channel monitoringAudD streams endpoints on api.audd.io (addStream, setCallbackUrl, plus GET /longpoll/).
Custom bucket of your own audioAudD 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 SDKs11 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_token is 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 limit on 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=N stops 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_token form 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" with result: null on a clean no-match, distinct from an error response. 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 returns audio_id, and artist/title may 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) isrc and upc. Provider blocks (apple_music, spotify, deezer, musicbrainz) are returned only when you request them via return.
  • 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

  1. Get an AudD token. Sign up at dashboard.audd.io (300 free requests, no card) and copy the api_token.
  2. Install the SDK for your language. For example, pip install audd, npm install @audd/sdk, or go get github.com/AudDMusic/audd-go. See the SDK docs for all 11.
  3. Replace the signing code with the token. Delete the HMAC/signature builder and the access_key/access_secret/timestamp form fields. Construct the client with api_token (or set AUDD_API_TOKEN).
  4. Map each call site to an endpoint. Identify → standard recognize(...). File scanning → recognize_enterprise(..., limit=N). Broadcast monitoring → streams (set_callback_url + add), or longpoll if you can’t host a callback.
  5. 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 explicit result == null branch for no-match.
  6. 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/.
  7. 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.