Skip to main content
When a job is submitted with review=true, it stops for a human before delivery. A job.awaiting_review event carries a review_url; job.complete follows once someone approves. review_stage decides where it stops. See POST /transcribe for the parameter itself.

What “awaiting review” does and does not hold back

The job.complete webhook is held until approval. Nothing else is. GET /api/v1/jobs/{id} reports the job’s real pipeline state throughout, and once a stage has produced output that output is readable — so an aligned-stage job returns status: "complete" with download URLs before anyone has approved. Approval is recorded in review_approved_at.
If your workflow requires that nothing is consumed before sign-off, gate on review_approved_at yourself — do not treat status: "complete" as approval. For a hard gate, use review_stage: "transcript": alignment has not run, so there are no timed outputs to read early.

Review URL

It is delivered in the job.awaiting_review webhook, and is also returned by GET /api/v1/jobs/{id} and GET /api/v1/jobs under review_url. A webhook endpoint is not required — a polling consumer can run the whole flow. review_url is null until the job reaches its gate and a token is minted — after transcription for review_stage: "transcript", after alignment for "aligned". Poll until it is non-null rather than caching a null. A job submitted with review_delivery: "api" mints no token at all, so its review_url stays null permanently and our review page cannot be opened for it. That is deliberate: the link’s security is the token. The token is valid for 7 days and may be used more than once — a reviewer can open the link, leave, and come back. It cannot be used after review_expires_at; contact support@lyrcs.ai for a new one.

Two ways to approve

Both converge on the same approval and the same outputs; nothing downstream distinguishes them, and the first approval wins whichever door it came through. review_delivery at submission decides which doors a job opens — see Running Review In Your Own Product.

Approving

The reviewer approves in the browser at review_url. Corrections made there are saved with the approval. Corrections are re-aligned. On an aligned-stage job, editing a line invalidates the word-level timings that were derived from the old text, so approval re-runs alignment over the corrected lines. Where re-alignment is unavailable for your organisation, the word-level track is removed rather than returned describing text that is no longer there; the line-level LRC and SRT are unaffected. The approval response reports which happened:

Webhook payloads

job.awaiting_review — fires when the job reaches its gate:
review_stage tells you which gate fired — the same event name is used at both, and what the reviewer is being asked to check differs between them. job.complete — fires after approval, carrying the same fields as a non-review job:
Word-level download URLs appear only when the job was submitted with word_align=true and the timings survived review.

Review fields on the job response

review_approved_at is null until approval, then an ISO timestamp. It is the only field that tells you a human has signed off.

Known limitations

  • The job.complete webhook fired after approval is single-attempt — it does not retry, unlike the standard flow which retries at +1 min, +5 min and +30 min. If you miss it, poll GET /jobs/{id}; review_approved_at will be set and the results are available.
  • A review_stage: "transcript" job waits up to 8 days. If nobody approves, it is marked failed with stage review rather than remaining processing indefinitely.
  • Adding or removing lines requires that the timings can be re-derived. At the aligned gate for an organisation without re-alignment, only the wording of existing lines can change; an attempt to alter the line count is refused with 409 REV_001.
See the Review Flow guide for a full end-to-end walkthrough.