AI Music Detection API — Complete Developer Guide 2026
If you're building a DSP, distributor, A&R submission platform, or any tool that needs to flag AI-generated music programmatically, you need an API. This guide walks you through everything: authentication, endpoints, code samples in Python/Node/Java, rate limits, response formats, error handling, and production tips.
We'll use the AI Song Checker REST API for code examples — it's free to start (no credit card), supports all major AI music engines (Suno, Udio, Riffusion, ElevenLabs Music, MusicGen, Stable Audio), and returns rich JSON including confidence scores and platform attribution.
Why integrate via API instead of UI
- Scale: batch-analyze thousands of tracks per hour
- Automation: integrate into submission workflows, catalog audits, streaming uploads
- Customization: build your own dashboard, alerting, scoring thresholds
- Compliance: generate audit logs for EU AI Act watermarking requirements
- Cost-effective: pay-per-call beats hiring manual reviewers
Quick start — 60 seconds
- Sign up for free at aisongchecker.pro (just an email)
- Upgrade to Pro (4,99€/month) to unlock API access
- Go to Dashboard → API and copy your
ASC_API_KEY - Make your first call (see Python sample below)
Authentication
All API requests use HTTP Basic Auth or Bearer token in the Authorization header. Bearer is recommended:
Authorization: Bearer ASC_LIVE_xxxxxxxxxxxxxxxx
Your API key has full access to your account — keep it server-side, never in client JS or mobile app bundles.
Endpoints overview
| Endpoint | Method | What it does |
|---|---|---|
/api/v1/analyze/file | POST | Upload audio file, get AI detection result |
/api/v1/analyze/url | POST | Analyze a YouTube/Spotify/SoundCloud URL |
/api/v1/analyze/batch | POST | Submit up to 100 tracks in one call |
/api/v1/result/{id} | GET | Fetch result of an async batch job |
/api/v1/certificate/{id} | GET | Get authenticity certificate (PDF, signed) |
/api/v1/usage | GET | Current quota usage + rate limit status |
Analyze a single file — Python
import requests
API_KEY = "ASC_LIVE_your_key_here"
URL = "https://api.aisongchecker.pro/v1/analyze/file"
with open("track.mp3", "rb") as f:
response = requests.post(
URL,
headers={"Authorization": f"Bearer {API_KEY}"},
files={"audio": f},
data={"return_features": "true", "return_certificate": "true"},
)
result = response.json()
print(f"AI probability: {result['ai_probability']:.1%}")
print(f"Verdict: {result['verdict']}") # "ai" | "human" | "uncertain"
print(f"Most likely platform: {result['platform_attribution']['top']}")
print(f"Confidence: {result['confidence']:.2f}")
Example response
{
"id": "asc_anl_2k3jX9pQmR8t",
"ai_probability": 0.967,
"verdict": "ai",
"confidence": 0.94,
"platform_attribution": {
"top": "suno",
"scores": {
"suno": 0.91,
"udio": 0.04,
"riffusion": 0.02,
"elevenlabs_music": 0.01,
"musicgen": 0.01,
"stable_audio": 0.01
},
"version_hint": "v5"
},
"watermarks": {
"c2pa_detected": true,
"synthid_detected": false,
"c2pa_signer": "suno.ai"
},
"features": {
"spectral_flatness_mean": 0.0182,
"phase_coherence_entropy": 2.41,
"mfcc_distance_baseline": 8.93,
"frame_similarity": 0.78
},
"engine_version": "ASC-v8.3",
"analyzed_at": "2026-05-22T18:42:11Z",
"certificate_url": "https://aisongchecker.pro/cert/asc_anl_2k3jX9pQmR8t.pdf"
}
Analyze a URL — Node.js
const fetch = require('node-fetch');
const result = await fetch('https://api.aisongchecker.pro/v1/analyze/url', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.ASC_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
return_features: false
})
}).then(r => r.json());
console.log(`AI: ${(result.ai_probability * 100).toFixed(1)}%`);
if (result.verdict === 'ai') {
console.log(`Platform: ${result.platform_attribution.top}`);
}
Batch analysis — Java
import java.net.http.*;
import java.net.URI;
HttpClient client = HttpClient.newHttpClient();
String json = """
{
"tracks": [
{"id": "t1", "url": "https://soundcloud.com/artist/track-1"},
{"id": "t2", "url": "https://open.spotify.com/track/abc123"},
{"id": "t3", "url": "https://youtu.be/xyz789"}
],
"webhook_url": "https://your-app.com/asc-webhook"
}""";
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.aisongchecker.pro/v1/analyze/batch"))
.header("Authorization", "Bearer " + System.getenv("ASC_API_KEY"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(json))
.build();
HttpResponse<String> res = client.send(req, HttpResponse.BodyHandlers.ofString());
// Returns: {"job_id": "asc_job_xyz", "status": "queued", "estimated_completion": "..." }
Rate limits
| Tier | Requests/min | Requests/day | Batch size |
|---|---|---|---|
| Free | 10 | 50 | 1 |
| Pro | 60 | 5,000 | 100 |
| Business | 300 | 50,000 | 500 |
| Enterprise | Custom | Unlimited | Custom |
Rate limit headers in every response:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 47
X-RateLimit-Reset: 1716422400
Error handling
| HTTP code | Meaning | What to do |
|---|---|---|
| 400 | Bad request (invalid file format, URL unsupported) | Check input, retry with valid data |
| 401 | Invalid API key | Check key in dashboard, rotate if leaked |
| 402 | Quota exceeded (free tier) | Upgrade plan or wait until reset |
| 413 | File too large (max 50 MB) | Compress audio (still pass MP3 320 kbps) |
| 429 | Rate limit hit | Implement exponential backoff (see below) |
| 500/503 | Server error | Retry with backoff. We have 99.9% SLA. |
Exponential backoff pattern
import time, requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
session = requests.Session()
retries = Retry(
total=5, backoff_factor=2,
status_forcelist=[429, 500, 502, 503, 504],
allowed_methods=["POST"]
)
session.mount("https://", HTTPAdapter(max_retries=retries))
# Then use session.post(...) — auto retries with 2s, 4s, 8s, 16s, 32s
Webhooks for async batch jobs
For batches >10 tracks, results arrive via webhook (faster than polling). Configure webhook_url in the batch request. Webhook payload:
POST https://your-app.com/asc-webhook
Content-Type: application/json
X-ASC-Signature: t=1716422400,v1=abc123...
{
"event": "batch.completed",
"job_id": "asc_job_xyz",
"results": [
{ "id": "t1", "ai_probability": 0.97, "verdict": "ai", "platform": "suno" },
{ "id": "t2", "ai_probability": 0.04, "verdict": "human" },
{ "id": "t3", "ai_probability": 0.81, "verdict": "ai", "platform": "udio" }
],
"stats": { "processed": 3, "errors": 0, "duration_ms": 12450 }
}
Verify the X-ASC-Signature header server-side using HMAC-SHA256 with your webhook secret (same scheme as Stripe webhooks).
Use cases — real examples
1. Streaming platform — auto-flag uploads
On track upload, call /analyze/file async. If ai_probability > 0.85, add a "AI-Generated" label automatically (per EU AI Act requirements). Tag platform_attribution.top in metadata for transparency.
2. A&R submission filtering
SubmitHub-style platforms call the API on each demo upload. Tracks with ai_probability > 0.7 get human review priority. Saves curators hours.
3. Music supervisor — licensing due diligence
Before licensing a track for film/TV, run it through /analyze/file + request the signed certificate (HMAC-SHA256). Attach the certificate to the licensing contract as proof of human authorship.
4. Catalog audit for labels
Send your back catalog (10K-1M tracks) via /analyze/batch. Get a CSV report of suspicious tracks for human review. Pricing: ~$0.01 per track at Business tier.
SDKs available
- Python:
pip install aisongchecker· GitHub - Node.js:
npm install @aisongchecker/sdk· GitHub - Java: Maven dependency, GitHub
- Go:
go get github.com/aisongchecker/go-sdk - Postman collection: import from /api-docs
Production checklist
- ☑️ API key stored server-side only (env var or secret manager)
- ☑️ Exponential backoff on 429/5xx
- ☑️ Webhook signature verification (HMAC-SHA256)
- ☑️ Cache results by audio hash (avoid duplicate analyses)
- ☑️ Set
return_features=falsefor high-volume usage (smaller responses) - ☑️ Monitor
X-RateLimit-Remainingin dashboards - ☑️ Idempotency: pass your own
request_idto dedupe retries