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
- Each accepted analysis uses one request from the key's allowance (a fixed total, or a monthly allowance). Failed analyses are not
charged (refunded automatically), and neither are rejected files.
GET /api/v1/usageshows what is left; every response carriesX-Quota-Limit/X-Quota-Remaining. - Per key: a number of requests per minute and of analyses in progress at the same time (see
/api/v1/usage). - Files up to 40 MB; the first 6 minutes of a track are analysed. Formats: MP3, WAV, FLAC, M4A/AAC, OGG/Opus, WebM, WMA, AIFF, MP4.
- Results are kept for 60 minutes and are visible only to the key that requested them. Audio is deleted right after analysis.
Errors
| HTTP | code | meaning |
|---|---|---|
| 401 | invalid_api_key | missing or wrong key |
| 403 | key_revoked / key_expired / links_not_enabled | the key may not be used (for this) |
| 413 / 415 / 400 | too_large / not_audio / bad_request | the input was rejected; nothing is charged |
| 422 | analysis_failed | the file could not be analysed; the request is refunded |
| 429 | quota_exceeded / rate_limited / too_many_concurrent | allowance used up, or slow down (see Retry-After) |
| 503 | busy | the 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.