Magic Chords Public API

A versioned REST API for chord recognition, lyrics transcription and sheet exports. All endpoints live under /api/v1/, accept and return JSON (except uploads and generated files), and are open to anonymous developers within fair-use quotas.

Every endpoint is documented interactively in the embedded reference below, generated directly from the implementation and always up to date.

How it works

Analysis and transcription run asynchronously: you submit a job, receive a job_id, poll for status, then fetch the full result once processing completes.

Quick start

Submit chord analysis for a song URL:

curl -X POST https://magic-chords.dev/api/v1/analyze/url \
  -H "Content-Type: application/json" \
  -d '{"url": "https://www.youtube.com/watch?v=VIDEO_ID"}'

The response contains your job handle:

{"job_id": "bBm3Zx8kQ7...", "status": "processing"}

Poll until the status is complete:

curl https://magic-chords.dev/api/v1/jobs/bBm3Zx8kQ7...

Fetch chords, tempo, key and structure:

curl https://magic-chords.dev/api/v1/jobs/bBm3Zx8kQ7.../result

Or download an export artifact directly (pdf, midi, musicxml, txt, csv, json):

curl -o chords.pdf \
  "https://magic-chords.dev/api/v1/jobs/bBm3Zx8kQ7.../export?format=pdf"

To analyze a local audio file instead of a URL:

curl -X POST https://magic-chords.dev/api/v1/analyze \
  -F "file=@song.mp3"

Endpoints

Method & PathPurpose
POST /api/v1/analyzeSubmit uploaded audio for chord analysis (multipart form)
POST /api/v1/analyze/urlSubmit a media URL for chord analysis
POST /api/v1/transcribeSubmit uploaded audio for lyrics transcription
POST /api/v1/transcribe/urlSubmit a media URL for lyrics transcription
GET /api/v1/jobs/{job_id}Compact status envelope for polling
GET /api/v1/jobs/{job_id}/resultFull result payload (chords, words, tempo, key…)
GET /api/v1/jobs/{job_id}/export?format=…Export completed analysis as pdf/midi/musicxml/txt/csv/json
GET /api/v1/limitsCurrent quota policy (unmetered)

Rate limits

Anonymous clients are limited per IP address. Current defaults (also available live from /api/v1/limits):

BucketLimit
Job submissions (heavy)20 per hour per client
Status/result/export reads (light)60 per minute per client
Concurrent running jobs2 per client

Every metered response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset headers. When a limit is hit you receive 429 with a Retry-After header — please respect it.

Errors

StatusMeaning
400Invalid request (bad URL, unknown format)
404Unknown job_id
409Job exists but is not finished or not exportable
413Upload exceeds the maximum size
415File is not recognized as audio
429Rate limit or concurrency cap exceeded
503Temporarily unavailable (quota backend down)

Notes & good citizenship

Interactive API reference

The complete reference loads below — browse every endpoint and try requests directly from this page.

Loading the interactive reference…