---
title: "Public database vs your custom catalog"
description: "When AudD recognition matches against the public 160-million-song database versus a private custom catalog you upload, and how to tell the two apart in a response."
slug: "/resources/concepts/custom-vs-public-db"
section: "concepts"
keywords: [audd, custom catalog, public database, audio_id, fingerprint, leak detection]
---

# Public database vs your custom catalog

AudD recognition can match incoming audio against two different fingerprint
databases: the public database of 160 million commercial releases, or a
*custom catalog* — a private database of tracks you upload to your own
account. This page explains the difference, how to tell which one produced a
match, and which to reach for depending on what question you're actually
asking.

## TL;DR

- **Public database** (the default): every recognition call matches against
  AudD's 160-million-song database of commercial releases. Use it to answer
  "what song is this?" or "is this commercial music?" A public-DB match
  returns `artist` and `title` from the public catalog.
- **Custom catalog** (opt-in, special access): you upload your own recordings
  via `POST https://api.audd.io/upload/`; later recognition calls can match
  against *your* tracks. Use it to answer "is this *my* track?" — leak
  detection, sample reuse, matching against content you own. A custom-catalog
  match returns an `audio_id` (the ID of the track you uploaded), and
  `artist`/`title` may be `null` because the match came from your private
  database, not a public release.
- You don't choose one or the other per call. With a custom catalog enabled,
  recognition checks both, and the presence of `audio_id` tells you which
  database produced the match.

## Why this matters

The two databases answer fundamentally different questions, and confusing
them leads to building the wrong thing.

If you're building a Shazam-style identifier, a now-playing widget, or a UGC
copyright scanner, you want the public database. The question is "which
commercial release is this?" and the answer is a known artist and title from
a catalog of 160 million songs you didn't have to assemble.

If you own content — a label with a release calendar, a producer with sample
packs, a studio sitting on unreleased masters — the public database can't
help you find *your* tracks before they're public, and it can't reliably tell
you that a 4-second loop in someone's beat came from your sample library. For
that you need AudD to know about your recordings, which means uploading them
to a custom catalog first. The question changes from "what is this?" to "is
this mine?"

The signal that separates the two in a response is a single field:
`audio_id`. Get this wrong and a leak-detection pipeline silently reports
public-database matches as "your track," or a copyright scanner ignores real
commercial matches because it was looking for an `audio_id` that public
matches never carry.

## The public database

Every recognition call uses the public database by default — no flags, no
setup beyond an API token. It contains 160 million commercial releases, and a
match returns the track's public metadata:

```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"
  }
}
```

A public-DB match has a populated `artist` and `title`, and **no**
`audio_id`. The track is a commercial release that exists in the catalog
independent of your account.

A minimal recognition call against the public database:

```python
from audd import AudD

audd = AudD("test")  # 10 free standard-endpoint requests/day; your own token at dashboard.audd.io

song = audd.recognize("https://audd.tech/example.mp3")
if song is None:
    print("no match")
else:
    print(song.artist, "—", song.title)  # public-catalog artist + title
```

`recognize` returns `None` on no match (distinct from an error). The public
database is the right tool when "no match" means "this isn't recognizable
commercial music."

## The custom catalog

A custom catalog is your account's private fingerprint database. You upload
your own recordings, AudD fingerprints them, and from then on recognition
calls on your token can match incoming audio against your tracks alongside
the public database.

Uploading is done through `POST https://api.audd.io/upload/`.

> **Custom-catalog upload requires special access.** The upload endpoint is
> not enabled on accounts by default. Email api@audd.io to have it provisioned
> for your token, and confirm the exact upload fields with them — recognition
> against your catalog then works on your normal token once tracks are
> ingested.

When you upload a track, you **assign** it an integer `audio_id` — your own
track ID (the upload response itself is just `{"status": "success", "result":
null}`). That `audio_id` is the only identifier the recognition response gives
you back for a custom-catalog match, so keep your own mapping from `audio_id`
to whatever the track means on your side (filename, release ID, ISRC,
internal SKU).

A custom-catalog match looks different from a public match:

```json
{
  "status": "success",
  "result": {
    "audio_id": 1234567,
    "artist": null,
    "title": null,
    "timecode": "00:08",
    "song_link": null
  }
}
```

The defining feature is `audio_id`. Because the matched recording is your
private track and not a public release, `artist` and `title` may be `null` —
the public catalog has no metadata for it. The business meaning of that
`audio_id` lives in your own records, not in the response.

## Telling the two apart

With a custom catalog enabled, a single recognition call can match either
database. Branch on `audio_id`:

```python
song = audd.recognize(incoming_audio)

if song is None:
    verdict = "no match"
elif song.audio_id:
    # came from YOUR private catalog
    track = my_catalog[song.audio_id]   # your own audio_id -> metadata map
    verdict = f"matched my track: {track['title']}"
else:
    # came from the public 160-million-song database
    verdict = f"commercial release: {song.artist} — {song.title}"
```

The rule:

- `audio_id` present → custom-catalog match (your track). Resolve metadata
  from your own records; don't expect `artist`/`title`.
- `audio_id` absent, `artist`/`title` present → public-database match (a
  commercial release).
- result is `None`/`null` → no match in either database.

## Choosing the right database for the job

| Your question | Database | Key response field |
|---|---|---|
| What song is this? | Public | `artist`, `title` |
| Is this commercial music (for moderation/copyright)? | Public | `label`, ISRC, UPC |
| Is this *my* track (leak, re-upload, sample reuse)? | Custom catalog | `audio_id` |
| What's playing on this radio stream right now? | Public | `artist`, `title`, `song_link` |
| Did this beat sample one of my loops? | Custom catalog | `audio_id` |

Public-database use needs only an API token. Custom-catalog use needs the
upload endpoint provisioned first (email api@audd.io), plus your own
`audio_id`-to-metadata mapping to make matches meaningful.

## Worked example

Two teams, two databases, same API.

**A UGC platform scanning for copyright (public database).** A user uploads
a video. The platform sends it to recognition and asks: does this contain
commercial music it doesn't have rights to? The answer comes from the public
database — a match returns a real artist, title, and label, and on enterprise
calls (Startup plan or higher) an ISRC and UPC the platform can cross-check
against licensing systems. The platform never uploaded anything to AudD; it's
matching arbitrary user content against the world's commercial catalog.

```python
# Public DB: "is there commercial music in this upload?"
matches = audd.recognize_enterprise(user_upload, limit=10)
copyrighted = [m for m in matches if m.label]  # labelled commercial releases
```

**A record label detecting leaks (custom catalog).** Before release day, the
label uploads its unreleased masters to a custom catalog via
`POST api.audd.io/upload/`, keeping each returned `audio_id` mapped to the
track. It then runs recognition on suspect files scraped from forums and
file-lockers. A match with an `audio_id` means a leaked master surfaced — the
public database would never contain an unreleased track, so only the custom
catalog can answer this. `artist`/`title` come back null; the label resolves
the `audio_id` against its own release database to know exactly which master
leaked.

```python
# Custom catalog: "is this one of my unreleased masters?"
song = audd.recognize(suspect_file)
if song and song.audio_id:
    leaked = my_masters[song.audio_id]   # resolve via your own map
    alert(f"Leak detected: {leaked['title']}")
```

Same recognition API, same response schema. The difference is which database
holds the fingerprint that matched — and `audio_id` is how you know.

## Common mistakes

- **Expecting `artist`/`title` on a custom-catalog match.** They're often
  `null` because your private track has no public-catalog metadata. Resolve
  the `audio_id` against your own records instead.
- **Looking for `audio_id` on public matches.** Public-database matches don't
  carry one. A copyright scanner that keys off `audio_id` will treat every
  commercial match as "not found."
- **Trying to detect your own unreleased tracks against the public
  database.** An unreleased master isn't a commercial release, so it isn't in
  the public catalog — there's nothing to match. You must upload it to a
  custom catalog first.
- **Treating upload as a normal call.** `POST api.audd.io/upload/` requires
  special access. Email api@audd.io before building on it.
- **Not keeping your own `audio_id` map.** The response gives you an
  `audio_id` and little else for custom matches; the meaning of that ID lives
  on your side. Persist the mapping when you upload.

---

**Related**

- [Detect samples in user uploads](/resources/recipes/sample-detection)
- [Monitor radio airplay](/resources/recipes/radio-airplay-monitor)
- [Build a copyright scanner for user-uploaded content](/resources/recipes/ugc-copyright-scanner)
- [SDK docs](https://docs.audd.io/sdks)
- [API reference](https://docs.audd.io)