REST API

Add lyrics to anything. One endpoint.

Transcribe, transliterate, translate and align 52 languages in a single async call. Single jobs, batch up to 20, or hold a job for an artist to approve before the timings are made.

POST/v1/transcribe
# audio_url supports files up to 100 MB. Multipart file uploads cap at 4.5 MB.
curl https://lyrcs.ai/api/v1/transcribe \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "audio_url": "https://…/track.mp3",
    "language": "Punjabi",
    "word_align": true,
    "webhook_url": "https://your-app.com/hook"
  }'

→ 202 { job_id: "job_9f2a…", status: "queued" }
file upload or URLword-level timestampsasync + webhook52 languages
§ I · Integration

Three calls. Done.

i

POST a job

Send your audio file or URL, language code, and output preferences. The API returns a job ID immediately — processing happens asynchronously.

ii

Poll or receive a webhook

Pass a webhook_url at creation time and we'll POST the result when the job completes. Or poll GET /v1/jobs/{id} — most songs finish in under a minute. A job submitted with review=true instead waits for a human, so poll for review_approved_at rather than a deadline.

iii

Download the outputs

Download URLs are included in the completed job response. LRC, SRT, word-level JSON — both original script and transliterated — ready to ingest.

GET/v1/jobs/{id}
// status: "processing" | "complete" | "failed"
{
  "status": "complete",
  "transcript": "ਹਵਾ ਚੱਲੀ ਸ਼ਾਮ ਢਲੀ…",
  "download_urls": {
    "lrc_original": "https://…/download/lrc/original",
    "words_original": "https://…/download/words/original"
  }
}
§ II · Endpoints

A handful of endpoints cover every workflow.

Paths below are relative to https://lyrcs.ai/api — so /v1/transcribe is POST https://lyrcs.ai/api/v1/transcribe.

POST/v1/transcribe

Transcribe, transliterate, translate and align audio. Accepts a file upload (multipart, 4.5 MB ceiling) or an HTTPS audio URL for files up to 100 MB.

languagereq
ISO language name, e.g. Punjabi, Hindi, Tamil
file
Audio file (multipart). Required if audio_url is absent. Hard 4.5 MB ceiling — larger bodies are rejected with a plain 413 before reaching the API.
audio_url
HTTPS URL to an audio file. Required if file is absent, and the only option above 4.5 MB. Supported up to 100 MB — larger files are rejected with 413 (VAL_002). We only ever send GET requests, so presigned S3 and GCS links work. A link its host refuses at submission (401, 403, 404 or 410) is rejected with 422 (VAL_003) and nothing is charged. The link must stay valid until we fetch it: a minute or two for a single song, but songs wait their turn when you submit in bulk, so make bulk links valid for 24 hours. We keep our own converted copy after that.
align
Default true. Set false for transcript-only jobs.
word_align
Default true. Word-level timestamps in addition to line-level.
review
Default false. Holds the job for a human before delivery.
review_stage
Default "aligned". Set "transcript" to hold BEFORE alignment, so corrections reach the aligner. Requires review=true.
review_delivery
Default "both". "api" mints no review link, so approval can only come from your own system; "link" refuses API approval. Requires review=true.
end_user
Your own customer this song belongs to: { external_id, email?, name? }. Echoed back and filterable, so a job can be traced to the artist it came from.
isrc
The recording's ISRC. Hyphens accepted, stored canonically. The only identifier that means the same thing to us and to your catalogue.
external_id
Any string up to 255 chars, echoed everywhere, for mapping a job back to your own track. Accepted in JSON and multipart.
webhook_url
HTTPS URL to notify when the job completes.
Idempotency-Key
Request HEADER, not a body field. Makes a retried submission safe: the same key replays the original response instead of creating a second job and a second charge.
POST/v1/batch

Submit up to 20 jobs in a single call. Each job follows the same schema as /v1/transcribe.

jobsreq
Array of job objects (max 20). Each takes the same fields as /v1/transcribe — align, word_align, review, review_stage, review_delivery, isrc, external_id and end_user are all per job, not per batch.
webhook_url
Batch-level webhook — fires once when all jobs complete.
GET/v1/jobs/{id}

Poll a job for status and results. Returns download URLs for all output formats once the job is complete, and — while a job is held for review — the lyrics as an array of lines.

—
No body parameters. Cross-org enumeration is blocked; 404 for jobs not owned by your org.
GET/v1/jobs

List your jobs, newest changes last, with a resumable cursor. This is how a catalogue-sized integration syncs — poll this once rather than every job individually.

updated_since
ISO 8601. Only jobs that changed after this instant. The basis of an incremental sync.
status
processing | complete | failed.
external_id / isrc / end_user_id / batch_id
Exact-match filters. end_user_id accepts your own identifier or ours.
limit / cursor
Page size 1–100 (default 50), and the cursor returned by the previous page.
POST/v1/jobs/{id}/approve

Approve a job held for review, from your own server. Lets the artist review lyrics inside your product instead of being sent to a lyrcs.ai link — the outputs are identical either way.

lines
Corrected lines of the original script, text only. Omit to approve unchanged. No timestamps — approval re-derives them from the audio.
transliterated_lines
Corrected transliteration. Position-parallel to lines: send both when you add or remove a line.
POST/v1/jobs/{id}/align

Align, or re-align, a job that already exists — either a transcript-only job, or one whose lyrics have since been corrected. One job, one charge, audio we already hold.

—
No body. Draws on the submit rate limit, not the read limit, because it runs the aligner.
§ III · Outputs

Every format, both scripts.

LRCline-level

Standard .lrc format with per-line timestamps. Delivered for both original script and transliteration.

/v1/jobs/{id}/download/lrc/{type}
SRTsubtitle

.srt subtitle format. Drop into video editing software or a player that supports SRT.

/v1/jobs/{id}/download/srt/{type}
Word JSONword-level

Array of { word, timestamp } objects with millisecond precision. Powers karaoke and word-by-word highlighting.

/v1/jobs/{id}/download/words/{type}
Cultural notesin response body

Idioms, cultural references, and context notes generated during transcription. Returned in the job response, not a separate download.

LRC, SRT and word JSON are each delivered in two variants: original script (e.g. Gurmukhi, Devanagari) and transliterated. The {type} path segment is original or transliterated.

§ IV · Advanced

Human review gate. Batch. Webhooks.

Human review gate

Pass "review": true to pause the pipeline for human review. The completed transcription response includes a review_url — a shareable link where a human can approve or edit the transcript before alignment proceeds.

Useful for supervised workflows, editorial teams, or high-value tracks.

Webhooks

Pass webhook_url at job creation and we'll POST the completed job payload to your endpoint instead of making you poll. The webhook body carries the same job fields as the GET /v1/jobs/{id} response, wrapped with a top-level event field.

Use POST /v1/webhook-test to send a sample payload to your endpoint.

Batch jobs

Submit up to 20 jobs in a single call via POST /v1/batch. Rate limits are checked against the full batch size before any jobs are created. A single batch-level webhook fires when all jobs complete. Poll GET /v1/batch/{id} for per-job status.

Rate limits: 10 / minute · 100 / hour · 1,000 / day.

Ready to integrate?

Full reference docs, code samples, and language coverage at docs.lyrcs.ai. Request API access below.