AI music detector API

Send a song, get a score from 0 (no AI fingerprint found) to 100 (AI), the verdict, a per-section breakdown and, optionally, a verifiable PDF report. Access is by personal API key; each key has its own request allowance.

Getting access

API keys are issued individually by the operator of this service, each with its own request allowance. Ask the operator for a key.

Authentication

Send your key as Authorization: Bearer aim_... (or X-API-Key). Keep it secret; it is shown once when it is created.

Analyse a file

curl -X POST https://api.youmadeit.org/api/v1/analyze \
  -H "Authorization: Bearer aim_YOUR_KEY" \
  -F "file=@song.mp3"

# or the raw bytes:
curl -X POST https://api.youmadeit.org/api/v1/analyze -H "Authorization: Bearer aim_YOUR_KEY" \
  -H "X-Filename: song.mp3" --data-binary @song.mp3

# or a YouTube link:
curl -X POST https://api.youmadeit.org/api/v1/analyze -H "Authorization: Bearer aim_YOUR_KEY" \
  -H "Content-Type: application/json" -d '{"url": "https://www.youtube.com/watch?v=..."}'

By default the request waits for the result (usually 10-40 s, at most about 80 s). Add ?wait=0 to get a job id immediately and poll GET /api/v1/jobs/<id>. If a waiting request times out you get 202 with the job id as well.

{
  "id": "5b1f...", "state": "done",
  "result": {
    "file": "song.mp3", "score": 0.9731, "score100": 97,
    "verdict": "AI",                       // "AI" | "unsure" | "real" (= no AI fingerprint found)
    "verdict_label": "Likely AI-generated",
    "band": {"low": 0.5, "high": 0.77},    // AI >= high, unsure between, no AI found <= low
    "duration_s": 173.8, "n_clips": 8,
    "clips": [{"start_s": 0.0, "end_s": 20.1, "p": 0.98}, ...],   // AI probability of each ~20 s section
    "per_model": {"cnn_chain_v2": 0.97, ...}, "notes": ["..."], "analysed_at": "2026-10-12T16:39:56Z",
    "model_version": "v2"
  },
  "report_pdf": "/api/v1/jobs/5b1f.../report.pdf",
  "quota": {"limit": 100, "used": 3, "remaining": 97, "period": "total", "resets_at": null}
}

PDF report

GET /api/v1/jobs/<id>/report.pdf (same key) returns the report as PDF. It carries a report ID and a link; anyone can check it on the site's "Verify a report" form. Generating it stores a small record of the result (file name, verdict, score, section scores, time) for 365 days, like the web page's PDF export.

Allowance and limits

Errors

HTTPcodemeaning
401invalid_api_keymissing or wrong key
403key_revoked / key_expired / links_not_enabledthe key may not be used (for this)
413 / 415 / 400too_large / not_audio / bad_requestthe input was rejected; nothing is charged
422analysis_failedthe file could not be analysed; the request is refunded
429quota_exceeded / rate_limited / too_many_concurrentallowance used up, or slow down (see Retry-After)
503busythe service is at capacity; retry shortly

Python

import requests
KEY = "aim_YOUR_KEY"
with open("song.mp3", "rb") as f:
    r = requests.post("https://api.youmadeit.org/api/v1/analyze", headers={"Authorization": f"Bearer {KEY}"},
                      files={"file": f}, timeout=120)
r.raise_for_status()
res = r.json()["result"]
print(res["score100"], res["verdict_label"])
pdf = requests.get("https://api.youmadeit.org" + r.json()["report_pdf"], headers={"Authorization": f"Bearer {KEY}"})
open("report.pdf", "wb").write(pdf.content)

What the score means

The detector recognises songs from two AI generators (Suno and Treblo) against real music. A low score means no known AI fingerprint was found, which is not proof that a human made the track; other generators are not recognised. Treat a result as evidence, not proof.