Karaoke Sync API
Submit an MP3 audio file with pre-segmented lyrics and receive word-level timestamps for karaoke synchronization. Results are delivered asynchronously and stored for 90 days.
https://karaoke.cohesium.ai
Authentication
All API requests require an API key sent via the X-API-Key header.
X-API-Key: kk_your_api_key_here
API keys are provided by the platform administrator. Keys prefixed with kk_ are Tonael keys.
POST /api/v1/sync
Submit an alignment job. Returns immediately with a job ID. Results are delivered asynchronously.
Request
Content-Type: multipart/form-data
| Field | Type | Required | Description |
|---|---|---|---|
audio |
file | Yes | MP3 audio file (max 50 MB, max 15 minutes) |
lyrics |
string | Yes | Lyrics text (max 20,000 chars). Auto-segmented if no line breaks provided. |
language |
string | Yes | ISO 639-1 language code: fr, en, es, de, it, pt, ja, ko |
Example
curl -X POST https://karaoke.cohesium.ai/api/v1/sync \
-H "X-API-Key: kk_your_api_key_here" \
-F "audio=@song.mp3" \
-F "lyrics=Joyeux anniversaire
Cher Antoine
On te souhaite
Plein de bonheur" \
-F "language=fr"
Response 202 Accepted
{
"job_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "processing",
"created_at": "2026-04-04T10:30:00Z"
}
GET /api/v1/sync/{job_id}
Retrieve the status and result of an alignment job. Results are available for 90 days after completion.
Query Parameters
| Param | Default | Description |
|---|---|---|
format |
json |
Output format. Options: json, lrc, srt, vtt, ass, ttml, sbv, txt |
Export Examples
# Get as Enhanced LRC (karaoke)
curl "https://karaoke.cohesium.ai/api/v1/sync/{job_id}?format=lrc" -H "X-API-Key: ..."
# Get as SRT (subtitles)
curl "https://karaoke.cohesium.ai/api/v1/sync/{job_id}?format=srt" -H "X-API-Key: ..."
# Get as WebVTT (web video)
curl "https://karaoke.cohesium.ai/api/v1/sync/{job_id}?format=vtt" -H "X-API-Key: ..."
# Get as ASS (video karaoke with word highlighting)
curl "https://karaoke.cohesium.ai/api/v1/sync/{job_id}?format=ass" -H "X-API-Key: ..."
Example
curl https://karaoke.cohesium.ai/api/v1/sync/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
-H "X-API-Key: kk_your_api_key_here"
Response 200 OK (completed)
{
"job_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "completed",
"created_at": "2026-04-04T10:30:00Z",
"completed_at": "2026-04-04T10:30:12Z",
"expires_at": "2026-07-03T10:30:12Z",
"result": {
"segments": [
{
"index": 0,
"text": "Joyeux anniversaire",
"start": 5.240,
"end": 7.810,
"words": [
{ "word": "Joyeux", "start": 5.240, "end": 5.880, "confidence": 0.94 },
{ "word": "anniversaire", "start": 5.920, "end": 7.810, "confidence": 0.89 }
]
}
],
"statistics": {
"total_segments": 4,
"total_words": 12,
"avg_confidence": 0.87,
"low_confidence_words": 1,
"duration_s": 30.5
}
}
}
Response 202 Accepted (still processing)
{
"job_id": "a1b2c3d4-...",
"status": "processing",
"created_at": "2026-04-04T10:30:00Z"
}
Response 410 Gone (expired)
{
"error": {
"code": "RESULT_EXPIRED",
"message": "Result expired after 90 days"
}
}
DELETE /api/v1/sync/{job_id}
Cancel a job that is still in the queue. Only jobs with status queued can be cancelled. Jobs that are already processing, completed, or failed cannot be cancelled.
Example
curl -X DELETE https://karaoke.cohesium.ai/api/v1/sync/{job_id} \
-H "X-API-Key: kk_your_api_key_here"
Response 200 OK
{ "job_id": "...", "status": "cancelled" }
Response 409 Conflict (not cancellable)
{ "error": { "code": "NOT_CANCELLABLE", "message": "Job is 'processing' — only 'queued' jobs can be cancelled" } }
GET /api/v1/health
Health check endpoint. No authentication required. Returns the status of all system components.
Response 200 OK (all systems operational)
{
"status": "healthy",
"service": "tonael-sync",
"version": "1.0.0",
"checks": {
"api": "ok",
"database": "ok",
"processing": "ok"
}
}
Response 503 Service Unavailable (degraded)
{
"status": "degraded",
"service": "tonael-sync",
"version": "1.0.0",
"checks": {
"api": "ok",
"database": "ok",
"processing": "down"
}
}
Use this endpoint for uptime monitoring. Status healthy = all systems go. degraded = partial outage. unhealthy = critical failure.
Error Codes
| HTTP | Code | Description |
|---|---|---|
| 400 | INVALID_AUDIO_FORMAT | File is not a valid MP3 |
| 400 | AUDIO_TOO_LARGE | File exceeds 50 MB |
| 400 | AUDIO_TOO_LONG | Audio exceeds 15 minutes |
| 400 | INVALID_LYRICS | Lyrics empty or exceeds 20,000 chars |
| 400 | UNSUPPORTED_LANGUAGE | Language code not supported |
| 401 | UNAUTHORIZED | Missing or invalid API key |
| 403 | KEY_PAUSED | API key is paused by administrator |
| 403 | KEY_REVOKED | API key has been revoked |
| 404 | JOB_NOT_FOUND | Job ID does not exist or belongs to another key |
| 410 | RESULT_EXPIRED | Result deleted after 90-day retention |
| 500 | INTERNAL_ERROR | Unexpected server error |
All errors follow the format: {"error": {"code": "...", "message": "..."}}
Lyrics Guidelines
What you should do
Send the lyrics as-is: Just paste the raw lyrics text. The API handles everything else — formatting, cleaning, and segmentation are fully automatic.
Tip: For best results, include only what is actually sung or spoken. But even if you include metadata or headers, the API will do its best.
What the API handles automatically
AUTO Line segmentation: Long lines are automatically split at natural points (punctuation, pauses) for optimal karaoke display. You can send a single block of text — the API will segment it intelligently.
AUTO
Bracket tags: Section markers like [Verse 1], [Chorus], [SFX], [Female] are automatically stripped.
AUTO
Numbers: Digits are converted to words (10 → dix, 5 → cinq) based on the language parameter.
AUTO
Accented characters: Characters like é, à, ç, ö, ü are normalized internally. Original text is preserved in the output.
AUTO
Punctuation: Standalone punctuation (!, ?, :) is handled gracefully.
Limits
| Max audio duration | 15 minutes |
| Max file size | 50 MB |
| Max lyrics length | 20,000 characters |
| Result retention | 90 days |
| Processing time | ~10-15 seconds (typical 3-4 min song) |