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.

Quote accepts the same request envelope as create, including mode, language, outputs, maxCredits, and config, although only source and budget fields affect the current estimate.


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.audioUrlURI stringyesPublic 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.
languagestring2-16 chars. Omit or use "auto" for automatic language handling.
outputsarray1-4 entries from srt, json, vtt, lrc; default is srt + json.
budget.maxCostUsdPerMinnumberPublic price ceiling from 0.001 to 1 USD/min. Use 0.05 to enforce a five-cent/minute cap.
maxCreditsnumberOptional create-time credit spend guard, minimum 1.
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": [
{ "text": "First lyric line", "startSec": 0.12, "endSec": 3.4, "section": "Verse 1" }
],
"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_FILE_INVALID400A supplied subtitle file could not be parsed into usable cues.
SUBTITLE_GENERATION_FAILED400 / 502Audio download, transcription, or subtitle artifact generation failed.
SUBTITLE_NO_SPEECH_DETECTED422The audio did not produce usable lyric or speech content.