Skip to content

Lyrics / Subtitle Sync API

The Lyrics / Subtitle Sync API turns a public audio URL into lyrics plus line-level subtitle artifacts through OmnAPI’s managed transcription and timing pipeline. It is designed for MV captions, lyric preview, and any workflow that needs SRT/VTT/LRC/JSON timing from ordinary audio.

Use this flow:

  1. POST /api/v1/subtitles/quote to estimate credits and public price.
  2. POST /api/v1/subtitles with an Idempotency-Key.
  3. Poll GET /api/v1/subtitles/{taskId}.
  4. Read artifacts.srtUrl, artifacts.vttUrl, artifacts.lrcUrl, or artifacts.jsonUrl from the completed task.

source.durationSec is optional. If omitted, OmnAPI safely probes the public audio URL before quote/create and uses the server-detected duration for pricing, budget checks, and queue sizing. Send it only as a client hint when you already know the duration.


Terminal window
curl -X POST https://api.omnapi.com/api/v1/subtitles/quote \
-H "x-api-key: $OMNAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": {
"type": "audio",
"audioUrl": "https://example.com/song.mp3"
},
"budget": {
"maxCostUsdPerMin": 0.05
}
}'

Response:

{
"credits": 1,
"durationSec": 60,
"estimatedUsd": 0.02,
"maxCostUsdPerMin": 0.05,
"publicUsdPerMin": 0.02
}

budget.maxCostUsdPerMin is a public price guard. Quote returns both the active price and submitted ceiling so clients can decide before creating a task. Create fails with SUBTITLE_BUDGET_EXCEEDED before credits are deducted when the active subtitle price is above the submitted ceiling.


Terminal window
curl -X POST https://api.omnapi.com/api/v1/subtitles \
-H "x-api-key: $OMNAPI_KEY" \
-H "Idempotency-Key: subtitle-demo-001" \
-H "Content-Type: application/json" \
-d '{
"mode": "extract",
"source": {
"type": "audio",
"audioUrl": "https://example.com/song.mp3"
},
"language": "auto",
"outputs": ["srt", "json", "vtt", "lrc"],
"budget": {
"maxCostUsdPerMin": 0.05
},
"config": {
"metadata": {
"purpose": "mv-caption"
}
}
}'

Response:

{
"taskId": "task_01J...",
"status": "PENDING",
"creditsRequired": 1,
"pollUrl": "/api/v1/subtitles/task_01J..."
}
FieldTypeRequiredNotes
mode"extract"Default extract.
source.type"audio"yesPublic audio URL input.
source.audioUrlstringyesPublic http(s) URL. Private/local network URLs are rejected.
source.durationSecnumberOptional 1-600 second hint. If omitted, OmnAPI probes the audio before quoting or creating.
languagestringOmit or use "auto" for automatic language handling.
outputsarrayAny of srt, json, vtt, lrc; default is srt + json.
budget.maxCostUsdPerMinnumberPer-minute public price ceiling. Use 0.05 to enforce a five-cent/minute cap.
maxCreditsnumberOptional create-time credit spend guard.
configobjectStandard task config: priority, tags, metadata, webhookUrl.

Terminal window
curl https://api.omnapi.com/api/v1/subtitles/task_01J... \
-H "x-api-key: $OMNAPI_KEY"

Completed response:

{
"taskId": "task_01J...",
"status": "COMPLETED",
"progress": 100,
"lyrics": "First lyric line\nSecond lyric line",
"timeline": {
"lines": [
{ "index": 1, "startSec": 0.12, "endSec": 3.4, "text": "First lyric line" }
],
"words": []
},
"artifacts": {
"srt": {
"url": "https://cdn.omnapi.com/...",
"expiresAt": "2026-07-12T00:00:00.000Z",
"retentionDays": 7
},
"json": {
"url": "https://cdn.omnapi.com/...",
"expiresAt": "2026-07-12T00:00:00.000Z",
"retentionDays": 7
},
"srtUrl": "https://cdn.omnapi.com/...",
"jsonUrl": "https://cdn.omnapi.com/..."
},
"warnings": []
}

Current extraction returns line-level timing. timeline.words is included for a stable response shape and may be empty.


MV Fast and Studio use the same Subtitle Sync capability when a request enables subtitles but does not provide srtUrl.

{
"mode": "fast",
"source": {
"type": "audio",
"audioUrl": "https://example.com/song.mp3"
},
"subtitles": true,
"subtitle": {
"mode": "auto",
"language": "auto",
"maxCostUsdPerMin": 0.05,
"fallback": "continue_without_subtitles"
}
}

Use subtitle.mode="provided" when your product requires caller-supplied timing only. Use subtitle.mode="off" to disable subtitles even if a legacy subtitles toggle is present.


CodeHTTPMeaning
SUBTITLE_BUDGET_EXCEEDED400Active public subtitle price is above budget.maxCostUsdPerMin.
AUDIO_DURATION_INVALID400source.durationSec is outside the subtitle extraction range or does not match the probed duration.
AUDIO_DURATION_PROBE_FAILED400OmnAPI could not determine duration from the submitted audio.
AUDIO_FILE_TOO_LARGE413Submitted audio exceeds the Subtitle Sync audio size limit.
AUDIO_URL_INVALID400The audio URL is invalid, private/local, or otherwise not allowed.
AUDIO_URL_UNREACHABLE400 / 408 / 502OmnAPI could not fetch or inspect the audio URL.
SERVICE_UNAVAILABLE503Subtitle Sync is disabled, temporarily unavailable, or all extraction slots are busy.
SUBTITLE_GENERATION_FAILED400 / 502Audio download, transcription, or subtitle artifact generation failed.
SUBTITLE_NO_SPEECH_DETECTED422The audio did not produce usable lyric or speech content.