Skip to main content
Webhooks deliver event payloads to your server as jobs complete. Pass a webhook_url when submitting a job or batch — lyrcs.ai will POST the event payload to that URL.
Webhooks are the recommended way to consume the API. They fire only on terminal outcomes, so there is no in-flight state to interpret and no need to decide how long is too long. Polling works, but it puts the burden of judging “is this job stuck?” on your client — and that judgement is the single most common source of integration bugs.If you do poll, see job status for how long jobs legitimately take, and don’t impose a shorter timeout of your own.

Events

Retry schedule

lyrcs.ai retries failed webhook deliveries (non-2xx or timeout) on this schedule: Your endpoint must return a 2xx response within 10 seconds or the delivery is counted as failed.
The job.complete webhook fired after artist approval in the review flow uses single-attempt delivery — it does not retry. Ensure your review webhook endpoint is reliable.

Signature verification

Every webhook delivery includes an X-Lyrcs-Signature header containing an HMAC-SHA256 signature of the request body, keyed with your webhook_secret. Verify the signature before processing the payload to confirm the request came from lyrcs.ai.
Node.js — signature verification

Event payloads

job.complete

Fires when a job completes successfully. downloads is omitted when align=false was set. cultural_notes may be null.
Download URLs in the payload still require your API key in the Authorization header to fetch.
words_original and words_transliterated are present when word_align_requested: true (the default). Jobs submitted with word_align=false include only lrc_* and srt_* in downloads.
second_opinion and alignment are always present and may be null, which means the check did not run. An empty suggestions array is the opposite signal — it ran and agreed with every line. See Quality Signals.

job.awaiting_review

Fires instead of job.complete when review=true and alignment succeeded. No results block — lyrics are held until the artist approves.
Forward review_url to the artist. When they approve, job.complete fires with the full payload.

job.degraded

Fires on the first Gemini 503 retry only. The job is still processing — this is informational. Do not assume the job has failed.

job.failed

Fires when a job fails permanently after all retries are exhausted.

batch.complete

Fires when all jobs in a batch have finished — whether complete or failed. status is "complete" if all jobs succeeded, "partial" if any failed or timed out. downloads is included per job only when status === "complete" AND align_requested === true for that job.