karalyr.

API

Free, open, LRCLIB-compatible

Public JSON API, CORS enabled for all origins, no keys. The request and response shapes are LRCLIB-compatible: an LRCLIB client works by swapping the base URL. Karaoke-specific data lives in the extra karalyr object.

GET/api/get

Best lyrics for an exact track match. Params: artist_name, track_name (required), album_name, duration (seconds, matched ±2s). On a miss it returns 404 and triggers a background import from LRCLIB — retry once after a couple of seconds.

curl "https://karalyr.com/api/get?artist_name=Neon%20Practice&track_name=Refactor%20My%20Heart&duration=212"

Response: LRCLIB fields (plainLyrics, syncedLyrics — Enhanced LRC when word timing exists) plus karalyr: { payload, tier, source, revision_id, has_word_timing }.

GET/api/get/:track_id

Same response by internal track id.

curl "https://karalyr.com/api/get/2"

GET/api/search

Fuzzy full-text search over artist / title / album. Params: q, or artist_name / track_name / album_name.

curl "https://karalyr.com/api/search?q=refactor"

POST/api/request-challenge

Proof-of-work challenge for publishing. Find a nonce such that sha256(prefix + nonce) (hex) is ≤ target. Challenges expire after 10 minutes and are single-use.

curl -X POST "https://karalyr.com/api/request-challenge"
# → { "prefix": "…", "target": "00001fff…" }

POST/api/publish

Submit lyrics as a new revision (nothing is overwritten). Body: track metadata + either a structured payload or raw text with format (lrc, enhanced_lrc, ultrastar), plus the solved challenge. If the track's current best revision is verified, the submission enters pending_review.

curl -X POST "https://karalyr.com/api/publish" -H "Content-Type: application/json" -d '{
  "challenge": { "prefix": "<prefix>", "nonce": "<nonce>" },
  "artist_name": "Artist",
  "track_name": "Song",
  "duration": 201,
  "raw": "[00:12.00]First line\n[00:15.30]Second line",
  "format": "lrc"
}'

POST/api/signal

Quality feedback for a revision. Types: explicit_up, explicit_down, clean_playthrough, offset_correction (with value = offset in ms, positive = lyrics should appear later). Three agreeing offset reports auto-create a corrected revision; three positive signals promote a revision one tier.

curl -X POST "https://karalyr.com/api/signal" -H "Content-Type: application/json" \
  -d '{ "revision_id": 2, "type": "explicit_up" }'

POST/api/observe

Listen-along alignment: karaoke clients (the Karafilt extension) submit per-line word-timing observations measured during normal playback. Body: track metadata + line_start_ms, line_text, words and a confidence (0–1). Once enough lines of a track are covered, observations are median-merged and published automatically as an auto_aligned revision. Unknown tracks return 202 and trigger a LRCLIB import.

curl -X POST "https://karalyr.com/api/observe" -H "Content-Type: application/json" -d '{
  "artist_name": "Artist", "track_name": "Song", "duration": 195,
  "line_start_ms": 4000, "line_text": "First line here",
  "words": [ { "text": "First", "start_ms": 4000, "end_ms": 4400 },
             { "text": "line", "start_ms": 4400, "end_ms": 4800 },
             { "text": "here", "start_ms": 4800, "end_ms": 5400 } ],
  "confidence": 0.7
}'

GET/api/track/:id/revisions

Full revision history for a track (public transparency).

curl "https://karalyr.com/api/track/2/revisions"

Tiers

Every revision has a tier: imported < auto_aligned < community < verified. The API always serves the active revision with the highest tier; ties break by community signals, then recency.