---
title: "How to identify songs in audio files with the AudD API"
description: "Send an audio file or URL to AudD, parse the response, and handle no-match and error cases — a complete song-identification walkthrough with the Python SDK."
slug: "/resources/articles/identify-songs-in-audio-files"
section: "articles"
keywords: [audd, identify songs, audio file recognition, music recognition api, song identification python]
---

# How to identify songs in audio files with the AudD API

You've got an audio file sitting there — maybe a recorded radio segment,
something a user uploaded, or a stream capture from your app. You need to know
what's playing: artist, title, label, all of it. Building your own audio
fingerprinting engine isn't happening. You want to send a file and get an
answer.

The AudD API does exactly that. This guide covers the whole path: getting a
token, sending audio files, parsing responses, and handling the edge cases.
When you're done you'll have a working integration ready for any application.

## What you get back from AudD

Send an audio file or URL to AudD and it runs neural-network audio
fingerprinting against a database of 160 million songs. On a match you get
structured metadata:

- **Artist** and **title**
- **Album** name
- **Label**
- **Release date**
- A universal **song link** plus optional **Apple Music** and **Spotify** blocks

No match? The SDK returns `None` (the API sends `result: null`). That's a
successful response that simply found nothing — distinct from an error, and easy
to handle.

## Getting API access

Get an API token at [dashboard.audd.io](https://dashboard.audd.io). The free
tier is plenty for testing — get your integration running before committing to a
paid plan. Keep the token server-side; every request needs it.

Install the Python SDK:

```bash
pip install audd
```

## Three ways to send audio

AudD accepts audio in three forms:

1. **Local file** — a filesystem path or raw bytes
2. **URL** — pointing to publicly accessible audio
3. **Live stream** — for continuous real-time monitoring (see
   [streams](https://docs.audd.io/streams))

Most file-based projects use the first two.

## Identifying songs from local files

The SDK's `recognize` takes a path, a URL, raw bytes, or a file object and
returns the top match — or `None` on a successful call that matched nothing.

```python
from audd import AudD

audd = AudD("test")  # get your own token at dashboard.audd.io

song = audd.recognize("sample_clip.mp3", return_metadata=["apple_music", "spotify"])

if song:
    print(f"{song.artist} — {song.title}")
else:
    print("no match")
```

The `return_metadata` argument is optional but useful — requesting
`apple_music` and `spotify` populates those provider blocks in the response.
Perfect if you're building a UI that links to tracks. Each provider you request
adds a little latency, so ask only for the ones you render.

### What the response looks like

Under the hood, a successful match looks like this:

```json
{
  "status": "success",
  "result": {
    "artist": "Imagine Dragons",
    "title": "Warriors",
    "album": "Smoke + Mirrors (Deluxe)",
    "release_date": "2015-02-17",
    "label": "KIDinaKORNER/Interscope Records",
    "timecode": "00:31",
    "song_link": "https://lis.tn/Warriors",
    "apple_music": { "url": "https://music.apple.com/…", "…": "…" },
    "spotify": { "external_urls": { "spotify": "https://open.spotify.com/…" }, "…": "…" }
  }
}
```

A no-match returns `status: "success"` with `result: null`. That `status:
success` only means the request processed without errors — not that a song was
found. The SDK collapses this for you: `recognize` returns the result object on
a match and `None` otherwise, so you branch on the return value rather than
poking at `status` by hand.

## Identifying songs from URLs

Got audio hosted somewhere public? Skip the upload and pass the URL — same
method, same return value.

```python
song = audd.recognize(
    "https://audd.tech/example.mp3",
    return_metadata=["apple_music", "spotify"],
)

if song:
    print(f"{song.artist} — {song.title}")
```

## Reading the fields

Prefer the SDK's typed properties and helpers over reaching into provider blocks
by hand:

```python
if song:
    artist = song.artist
    title = song.title
    album = song.album
    label = song.label
    spotify_url = song.streaming_url("spotify")
    apple_music_url = song.streaming_url("apple_music")
    universal_link = song.song_link  # always present on a match
```

`song.song_link` is always present on a match — a universal `lis.tn` URL that
redirects to the song on whatever service the user has. Use it as the fallback
when a specific provider link is missing. Every field is nullable: a
custom-catalog match, for instance, may have a `None` artist and title. Guard
accordingly. For any field outside the typed surface, read it from
`song.model_extra`.

## Handling errors

The SDK raises typed exceptions when the server returns an error, so you can
branch on the cause instead of parsing error codes:

```python
from audd import AudD
from audd.exceptions import (
    AudDAuthenticationError,
    AudDQuotaError,
    AudDInvalidAudioError,
    AudDAPIError,
    AudDConnectionError,
)

audd = AudD("test")

try:
    song = audd.recognize("clip.mp3", return_metadata=["apple_music", "spotify"])
    if song is None:
        print("no match — try a different clip")
    else:
        print(f"{song.artist} — {song.title}")
except AudDAuthenticationError:
    print("bad or missing token — check the dashboard")
except AudDQuotaError:
    print("out of requests — top up at dashboard.audd.io")
except AudDInvalidAudioError:
    print("the audio couldn't be decoded (too short or corrupted)")
except AudDConnectionError:
    print("transient network issue — the SDK already retried")
except AudDAPIError as err:
    print(f"AudD #{err.error_code}: {err.server_message}")
```

Keep the three outcomes separate:

- **No match** — `recognize` returns `None`. Not an error. Render "try again."
- **Server-returned errors** — bad token, exhausted quota, undecodable audio.
  These raise typed exceptions, as above.
- **Quota during testing** — the `test` token is capped at 10 requests/day on
  the standard endpoint. If recognition suddenly starts failing with a quota
  error in development, you've hit that cap; switch to a real dashboard token.

The SDK retries transient connection failures before your bytes reach the
server, but never repeats a recognition call after the upload completes —
re-sending would risk double-billing.

## Audio length and quality tips

The standard endpoint is tuned for a short audio clip — a handful of seconds
of reasonably clean audio matches reliably. The fingerprinting handles
real-world conditions: background noise, low bitrates, slight distortion.
Heavily clipped or distorted audio will hurt accuracy.

Working with a longer recording? You don't need the whole file for the standard
endpoint — a short clip from where the music plays is plenty, and it keeps you
well under the 10 MB upload cap. To get *every* song across a long file, use the
enterprise endpoint instead (next section).

## Supported audio formats

AudD handles the formats you'll actually encounter: MP3, WAV, FLAC, M4A, OGG,
AAC, WMA, and AIFF. Working with an uncommon format? Convert to MP3 or WAV first
— `ffmpeg` is the standard tool and drops into any pipeline.

## Beyond single files

Once basic file identification works, the same SDK covers more:

- **Long files and full tracklists.** The standard endpoint returns one match.
  To identify every song across a long recording — a DJ set, a podcast, a
  broadcast — use the **enterprise endpoint** (`recognize_enterprise`). It
  chunks the file server-side, bills per 12 seconds of audio, and returns one
  match per recognized segment with timestamps. Always set `limit` during
  development to cap metered chunks.

  ```python
  matches = audd.recognize_enterprise("long_recording.mp3", limit=10)
  for m in matches:
      print(m.timecode, m.artist, "—", m.title)
  ```

- **Radio and stream monitoring.** AudD's **streams** surface runs continuous,
  real-time recognition against live stream URLs, returning timestamped song
  data as tracks change — the basis for airplay monitoring and broadcast
  compliance.

- **Content moderation.** Song identification in an upload pipeline can flag
  user content containing copyrighted music; the label and artist data is enough
  for basic rights awareness.

- **Match your own tracks.** Upload private recordings to a custom catalog and
  later `recognize` calls match against them too, returning the integer
  `audio_id` you assigned. Custom-catalog access is gated — email
  [api@audd.io](mailto:api@audd.io).

## Wrapping up

AudD gives you a clean interface: send audio, get metadata — the
fingerprinting, catalog, and matching are AudD's problem. The same `recognize`
call you wrote here is the one you'll use for uploads, broadcasts, and
backlogs.

---

**Related**

- [Build a Shazam-style music identification app](/resources/recipes/shazam-clone)
- [Standard, enterprise, or streams: how to choose](/resources/concepts/standard-vs-enterprise-vs-streams)
- [Recognition result fields](/resources/reference/result-fields)
- [API reference](https://docs.audd.io)