Skip to main content
For developers

Developer API

Automate LrcSong with HTTP — interactive docs, code samples, and webhooks.

Sign in to create API keys. API access is included with the Premium and Elite plans.

Sign in

Authentication

Send your API key in the X-API-Key header on every request:

curl -H "X-API-Key: lrc_xxxxxxxxxxxx" \
  https://lrcsong.com/api/v1/me

Stable API — /api/v1 (recommended)

The versioned v1 surface has frozen response contracts — fields are only ever added, never removed or renamed. Build integrations against these. Machine-readable schema: openapi.json · interactive docs.

  • POST /api/v1/lrc — submit an AI-LRC job (audio file or youtube_url).
  • POST /api/v1/transcribe — speech-to-subtitles job (SRT/VTT/TXT).
  • GET /api/v1/jobs/{id} — job status + progress.
  • GET /api/v1/jobs/{id}/result — finished lyrics: LRC text, plain lyrics, timed lines & words.
  • GET /api/v1/lyrics/search — LRCLIB synced-lyrics search (free).
  • GET /api/v1/me — key + credit-balance introspection.

Internal endpoints (unversioned — may change)

The endpoints below power the web app. They work with Bearer-token auth but their shapes can change without notice — prefer /api/v1 for anything you don't want to babysit.

  • POST /api/converters/convert — convert between LRC/SRT/VTT/ASS/TTML.
  • POST /api/tags/mp3/read / /tags/flac/read — read metadata.
  • POST /api/audio/convert-format — MP3 ↔ FLAC ↔ WAV ↔ OGG.
  • POST /api/translate/lyrics — translate lyrics with timing preserved.
  • POST /api/romanize/cjk — romanize CJK text (pinyin/romaji/RR).
  • POST /api/audio/separate-stems — vocal/instrumental separation (2/4/6 stems).
  • GET /api/api-keys/usage — your API usage statistics.
  • POST /api/api-keys/webhooks/test — test webhook delivery.

Rate limits

Limits are per API key, not per plan — every plan gets the same ceilings:

  • 10 / minute — job submissions (POST /v1/lrc, /v1/transcribe)
  • 120 / minute — job polling (GET /v1/jobs/…)
  • 30 / minute — lyrics search (GET /v1/lyrics/search)
  • 10 / minute — Studio project calls

Exceeding a limit returns 429. Credits are consumed the same way as the web UI. Need more throughput for a production integration? Get in touch — we raise limits per key.

Webhook events

Configure webhook endpoints to receive real-time notifications when jobs complete or fail. Use the to test your endpoint.

  • job.completed — job finished successfully
  • job.failed — job encountered an error (credits are refunded automatically)

Verifying the signature

Every delivery carries X-LrcSong-Signature: t=<unix>,v1=<hex>, where hex is HMAC-SHA256 of "<t>.<raw body>" keyed with your signing secret. The timestamp is inside the signed material, so a captured delivery cannot be replayed later — reject a t that is far from your own clock.

Sign the raw request bytes. Parsing the JSON and re-serialising it changes key order and whitespace, which changes the digest and fails every check.

import hashlib, hmac, time

def verify(secret: str, raw_body: bytes, header: str, tolerance_s: int = 300) -> bool:
    parts = dict(p.split("=", 1) for p in header.split(","))
    ts, sent = int(parts["t"]), parts["v1"]
    if abs(int(time.time()) - ts) > tolerance_s:
        return False                      # too old — replay
    expected = hmac.new(
        secret.encode(), f"{ts}.".encode() + raw_body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, sent)   # constant-time

Also sent: X-LrcSong-Event (the event name) and X-LrcSong-Delivery, which carries the job id and is stable across retries — use it as your idempotency key so a redelivered event is not processed twice. Reply 2xx to acknowledge. Anything else is retried up to 4 times with backoff (30s, doubling to a 10-minute cap), and an endpoint that fails 20 deliveries in a row is disabled automatically — saving the URL again re-enables it.