Solution

AudD for DJs

How DJs use AudD to build a timestamped tracklist from a recorded set, identify an unknown track in a recording, and credit tracks for a SoundCloud or Mixcloud upload.

view .md audddjtracklistmix

Posting a recorded set, hunting down one unknown ID, preparing credits for an upload: each starts with knowing which tracks are in the audio. AudD is a music-recognition HTTP API that fingerprints audio against a 160-million-song database. A continuous mix is the harder case (tracks are beat-matched and blended), and AudD’s enterprise endpoint is built for exactly that: it chunks a long file server-side and returns the songs it recognizes with each one’s position in the file.

What you can do

Build a tracklist or cue sheet from a recorded set

You have one long file — a recorded set or a continuous mix — and you want a timestamped list of what’s in it, the kind you’d post to a forum or a site like 1001Tracklists. The enterprise endpoint is the surface for this; the SDK’s recognize_enterprise is how you call it.

  • Hand the set to recognize_enterprise as a URL or a local file. It scans the file server-side and returns a flat list[EnterpriseMatch] — one entry per recognized fragment, in time order, each carrying a file-absolute start_seconds (its position in your set).
  • Place each track at its start_seconds, not at the match’s timecode — timecode is the position inside the matched recording, not where the track sits in your set.
  • Collapse the run of consecutive matches that name the same track into one entry, anchored at the first match’s start_seconds: the moment it comes in.
  • Surface blends. During a crossfade both the outgoing and incoming track fingerprint, so two consecutive matches can name different tracks at nearly the same position. Reading the run lets you mark a transition (w/ …) instead of dropping one side.

Always set limit while developing. The enterprise endpoint bills 1 request per 12 seconds of audio processed, so an hour-long set is hundreds of metered fragments. Run with a small limit until your formatting and overlap handling are right, then raise it for the full set.

Identify one unknown track in a recording

You have a short clip — a phone recording of something a DJ dropped, a few seconds you grabbed — and you just want to know what it is. This is the standard endpoint, not enterprise.

  • POST the clip to https://api.audd.io/. It’s for a short audio clip, responds in under 2 seconds, caps at 10 MB, and returns a single match.
  • A no-match returns result: null, distinct from an error. The track may not be in the database, or the clip may be too short or too noisy.
  • The public test token works here (and only here): api_token=test, 10 requests/day, standard endpoint only. Good for a first run; get your own token at the dashboard for real use.
  • Read artist, title, album, label, and the universal song_link (a lis.tn URL) off the result. Provider blocks (apple_music, spotify, deezer) come back when you ask for them with return.

Credit tracks for a SoundCloud or Mixcloud upload

You’re uploading a set and want an accurate credits list — every track, ideally with a time and an identifier — so listeners (and platforms) know what’s in it. This is the tracklist task above, read for crediting rather than for posting timestamps.

  • Run the set through recognize_enterprise once and reuse the same list[EnterpriseMatch] for both the timestamped tracklist and the flat credits list — you don’t pay twice to read it two ways.
  • Pull isrc and upc off each match for a precise credit; these come back on enterprise responses when your account is on a Startup plan or higher. Fields the SDK doesn’t surface as typed properties are available on each match’s model_extra map.
  • Keep your costs predictable: sample a multi-hour set with every and skip for a rough pass, or do a full pass when you need every track placed exactly. See enterprise cost control below.

Where to start

Code teaser

Send a mix to the enterprise endpoint and read each match’s file-absolute start_seconds. Always cap limit while you develop.

from audd import AudD

audd = AudD("your-api-token")  # token from dashboard.audd.io

# limit caps metered fragments while you get the tracklist right
matches = audd.recognize_enterprise("dj-set.wav", limit=25)  # list[EnterpriseMatch]

for m in matches:
    if m.start_seconds is None:
        continue  # no usable position for this fragment — skip it
    # start_seconds is the position in YOUR set, in seconds (e.g. 288.0)
    print(f"{m.start_seconds:.1f}s  {m.artist} — {m.title}  (score {m.score})")

recognize_enterprise returns a flat list[EnterpriseMatch], one per recognized fragment in time order. Each match carries where the track sits in your set directly:

  • start_seconds / end_seconds — where this track plays in your set, in file-absolute seconds. These are the values to place a track at; accurate offsets are on by default, so they’re precise. No offset math to do.
  • artist / title / album / label — the track, named.
  • isrc / upc — recording/release identifiers, back on Startup plan or higher.
  • song_link — the universal lis.tn URL for the track.
  • timecode — a position inside the matched recording, not your set; never use it to place a track in your mix.

A track held across a blend or a long stretch comes back as a run of consecutive matches naming the same (artist, title): collapse them into one tracklist entry anchored at the first match’s start_seconds, where it comes in. During a crossfade both the outgoing and incoming track can fingerprint, so two consecutive matches name different tracks at nearly the same position; surface that as a transition (w/ …) instead of dropping one side. Every field is Optional and parses leniently, so guard for None as above.

For a single unknown clip, the standard endpoint is one call and returns one match (or null):

from audd import AudD

audd = AudD()  # or AudD(api_token="test") for a quick first run
match = audd.recognize("https://audd.tech/example.mp3")
if match:
    print(f'{match.artist} — {match.title}')
else:
    print("no match")  # result: null — not an error

Related

Reading this as an AI agent? The raw Markdown is at for/djs.md, and the full index is /resources/llms.txt.