Agent note

Agent notes: the enterprise endpoint

Gotcha notes for AI agents writing AudD enterprise-endpoint code — billing, the chunked response shape, and how to compute file-absolute timestamps.

view .md auddenterprise endpointagentoffset

Terse gotchas for an agent about to write code against POST https://enterprise.audd.io/. These are the things that bite — read them before you generate the request, not after the bill arrives. For the full walkthrough see the enterprise recipes; this page is the short list.

1. Always set limit in development

The enterprise endpoint bills per 12 seconds of audio processed. The default is unbounded: an enterprise call on a one-hour file ingests the whole hour, in 12-second chunks, and charges for every chunk it scans.

Set limit=1 while you build. It caps the server at one recognized chunk so a test run against a long file can’t quietly process hours of audio. Raise it only once you understand the cost of the real file.

curl -s https://enterprise.audd.io/ \
  -F api_token=your-api-token \
  -F url=https://audd.tech/example.mp3 \
  -F limit=1

limit is the upper bound on the number of 12-second chunks the server will recognize. The public test token does not work here — enterprise needs a real token from dashboard.audd.io.

2. The response is an array of chunks, not a flat song list

Standard recognize returns one result object (or null). Enterprise returns result as an array of chunks. Each chunk is one 12-second window of the file and looks like:

{
  "offset": "00:48",
  "songs": [
    {
      "score": 100,
      "artist": "Barely Alive",
      "title": "Keyboard Killer",
      "timecode": "00:41",
      "start_offset": 1,
      "end_offset": 9660,
      "song_link": "https://lis.tn/KeyboardKiller"
    }
  ]
}
  • offset — MM:SS, the position in your submitted file of the start of this 12-second fragment.
  • songs[] — every match found inside that fragment. Usually one entry, but can be several when fragments overlap song boundaries or the audio is ambiguous. Each carries the usual score, artist, title, timecode, song_link, plus the offsets below.

The same song appears across many consecutive chunks while it plays. To get a per-song tracklist you collapse runs of adjacent chunks that share the same track — don’t treat each chunk as a distinct play.

3. The SDKs flatten chunks — file positions are start_seconds / end_seconds

The typed SDKs surface enterprise results as a flat list of matches (for example list[EnterpriseMatch] in Python) rather than the raw chunk array. Each match carries start_seconds and end_seconds — file-absolute positions, in seconds into the file you submitted. The SDKs request accurate_offsets=true by default and apply the chunk offset + start_offset / 1000 arithmetic for you, so those seconds are precise.

If you need where in the file a song played, read start_seconds on the match. Don’t recompute it from start_offset — that field is a within-fragment value (see below), not a file position.

The raw fragment-relative start_offset / end_offset milliseconds are also on each match when you need them.

4. start_offset / end_offset are milliseconds inside the fragment

Do not read start_offset as a file position. Both start_offset and end_offset are milliseconds within the 12-second fragment — they run roughly 0–12000. In the example above start_offset: 1, end_offset: 9660 means the match occupied ~0.0s to ~9.66s of that fragment, and the fragment itself starts at offset: "00:48" in the file.

File-absolute start time, in seconds, when you call the HTTP API directly (the SDKs precompute this as start_seconds):

def parse_offset(mmss: str) -> int:
    m, s = mmss.split(":")
    return int(m) * 60 + int(s)

# chunk["offset"] = "00:48", song["start_offset"] = 1
file_start_seconds = parse_offset(chunk["offset"]) + song["start_offset"] / 1000
# 48 + 0.001 = 48.001

Three different “time” fields live on an enterprise match — keep them straight:

FieldUnitMeans
offset (on the chunk)MM:SSstart of the 12s fragment in your file
start_offset / end_offset (on the song)millisecondsspan within that 12s fragment
timecode (on the song)MM:SSposition in the matched track where your audio lined up — not a file position

The per-fragment start_offset / end_offset are only populated when the request sets accurate_offsets=true; the SDKs set it by default.

5. accurate_offsets, every, skip, skip_first_seconds

  • accurate_offsets=true — populates the per-fragment start_offset / end_offset. Without it, don’t expect meaningful sub-fragment offsets. The SDKs send it by default.
  • every / skip — reduce metered audio by sampling. skip is how many 12-second chunks to skip after each scanned run; every is how many chunks to scan in a row. skip=4, every=1 scans 12s then skips 48s, repeating — one recognition per 60 seconds of audio, billed for one chunk per minute instead of five.
  • skip_first_seconds — skip the start of the file (e.g. a known intro) before recognition begins. Don’t combine with use_timecode.

These directly lower cost; reach for them before raising limit on big files.

6. ISRC / UPC need a plan

isrc and upc appear on enterprise matches only on the Startup plan or higher. On lower plans the fields are simply absent — don’t write code that assumes they’re always present, and don’t treat their absence as an error.

7. Use enterprise, not standard, when the file is long or multi-song

Reach for enterprise — not POST https://api.audd.io/ — whenever the input is longer than a short clip or may contain more than one song: a full-length track, a short-form video, a podcast, a broadcast, a DJ set. Standard recognize returns one match for one short clip and caps files at 10 MB; enterprise chunks the file server-side, returns every match, and has no practical size cap. Picking standard for a long file is an easy structural mistake — you’ll get one match for the whole file and miss everything else.


Related

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