Six download endpoints are available for each completed job where align=true (the default). All require authentication.
LRC and SRT endpoints
| Endpoint | Description |
|---|
GET /api/v1/jobs/{id}/download/lrc/original | LRC file in the source language script |
GET /api/v1/jobs/{id}/download/lrc/transliterated | LRC file with romanised (transliterated) lyrics |
GET /api/v1/jobs/{id}/download/srt/original | SRT file in the source language script |
GET /api/v1/jobs/{id}/download/srt/transliterated | SRT file with romanised lyrics |
Word-level JSON endpoints
| Endpoint | Description |
|---|
GET /api/v1/jobs/{id}/download/words/original | Per-word timestamps in the source language script |
GET /api/v1/jobs/{id}/download/words/transliterated | Per-word timestamps in romanised form |
These endpoints are only available when the job was submitted with word_align=true (the default). They return a JSON array where each entry contains a single word and its start timestamp.
Response — 200 OK:
[
{ "word": "நான்", "timestamp": "[00:12.34]" },
{ "word": "உன்னை", "timestamp": "[00:12.71]" },
{ "word": "நேசிக்கிறேன்", "timestamp": "[00:13.10]" }
]
Content-Type: application/json; charset=utf-8
Content-Disposition: attachment; filename="<original_filename>[_transliterated]_words.json"
Not ready yet — 202:
If word-level alignment has not completed, the endpoint returns 202:
{ "status": "processing" }
Only fetch word-level downloads once GET /api/v1/jobs/{id} returns status: "complete" and words_original appears in results.downloads.
Response — 200 OK
Returns a plain-text file with:
Content-Type: text/plain; charset=utf-8
Content-Disposition: attachment; filename="<original_filename>[_transliterated].<ext>"
Not ready yet — 202
If the job exists but alignment has not completed, the endpoint returns 202 instead of 404:
{ "status": "processing" }
Poll GET /api/v1/jobs/{id} and only fetch downloads once status is "complete".
Not available for align=false jobs
If the job was submitted with align=false, no LRC or SRT files are generated. Calling the download endpoints will return 202 { "status": "processing" } indefinitely since alignment never runs.
Download URLs are returned directly in results.downloads on the job response and in the job.complete webhook payload. You do not need to construct them manually.
Examples
# Original script LRC
curl https://lyrcs.ai/api/v1/jobs/a1b2c3d4-.../download/lrc/original \
-H "Authorization: Bearer $LYRCS_API_KEY" \
-o song.lrc
# Transliterated LRC
curl https://lyrcs.ai/api/v1/jobs/a1b2c3d4-.../download/lrc/transliterated \
-H "Authorization: Bearer $LYRCS_API_KEY" \
-o song_transliterated.lrc
# Original script SRT
curl https://lyrcs.ai/api/v1/jobs/a1b2c3d4-.../download/srt/original \
-H "Authorization: Bearer $LYRCS_API_KEY" \
-o song.srt
Download from webhook payload
If you’re using webhooks, the download URLs arrive in the job.complete payload:
{
"event": "job.complete",
"job_id": "a1b2c3d4-...",
"results": {
"downloads": {
"lrc_original": "https://lyrcs.ai/api/v1/jobs/a1b2c3d4-.../download/lrc/original",
"lrc_transliterated": "https://lyrcs.ai/api/v1/jobs/a1b2c3d4-.../download/lrc/transliterated",
"srt_original": "https://lyrcs.ai/api/v1/jobs/a1b2c3d4-.../download/srt/original",
"srt_transliterated": "https://lyrcs.ai/api/v1/jobs/a1b2c3d4-.../download/srt/transliterated",
"words_original": "https://lyrcs.ai/api/v1/jobs/a1b2c3d4-.../download/words/original",
"words_transliterated": "https://lyrcs.ai/api/v1/jobs/a1b2c3d4-.../download/words/transliterated"
}
}
}
All four URLs require your API key in the Authorization header to fetch.
See LRC & SRT Formats for a description of the file formats and when to use each.