Checking render job status over the API is what turns one-off video generation into a dependable production pipeline. CoreReflex exposes the entire lifecycle of a render, from the moment a worker claims the job to the instant a finished asset lands in your storage, so your code always knows exactly where a job stands. This guide walks through kicking off a render, polling its status cleanly, and handling the failures that any real system has to expect.
The render job lifecycle, end to end
CoreReflex runs a deterministic render path on a real Remotion render-worker. A render is not a black box that eventually emits a file, it moves through discrete, observable stages, and each one is reflected in the job's status. Once you understand the lifecycle, polling becomes obvious rather than guesswork.
- Queued, the job is accepted and waiting for a worker to pick it up.
- Claimed, a render-worker has claimed the job. Claiming is what prevents two workers from rendering the same manifest twice.
- Rendering, frames are being composed from your manifest. On the right encoder tier this stage can run on GPU.
- Uploading, the finished file is being written to your storage and a faststart MP4 is produced so it streams immediately.
- Complete, an asset row exists and the job carries a durable URL to the finished cut.
- Failed, the job exhausted its retries and was moved to the dead-letter queue for inspection.
Because the worker renders from a manifest rather than from live editor state, the same input always produces the same cut, that determinism is the property that makes polling trustworthy: a job in complete will not silently change underneath you.
Kick off a render
You start a render by submitting the project (or composition) you want rendered along with output settings. In practice you POST to the render endpoint with a composition id, a resolution, a frame rate, and an encoder tier, and you receive back a job id. That id is the handle you will poll against for the rest of the job's life.
A minimal request carries the essentials: which composition to render, the dimensions, the fps, and an output profile. The encoder tier you choose controls the speed-versus-quality trade-off, a fast tier for previews, a higher tier for final delivery. If you are assembling the manifest programmatically rather than from a saved project, our guide on how to edit video as data with the JSON engine covers the shape of that payload. For the exact field names and defaults, keep the API reference open in another tab.
Worth noting for budgeting: planning, scoring, and editing your project are free. Only generation and rendering consume credits, which is why most teams iterate on the manifest cheaply and only submit a paid render once the plan is locked. The pricing page breaks down how credits are counted.
Poll for render job status
Once you hold a job id, you read its state with a GET against the job endpoint. The response returns the current status, a progress signal where available, and, once the job reaches complete, the asset URL and metadata. The pattern is simple: request the job, branch on its status, and stop when it reaches a terminal state.
There are two terminal states, complete and failed, and everything else is transient. Your loop should keep requesting render job status on an interval until it sees one of those two, then act accordingly.
Status values you will see
| Status | Terminal? | What your code should do |
|---|---|---|
queued | No | Keep polling; the job is waiting for a worker. |
claimed | No | Keep polling; a worker owns the job now. |
rendering | No | Keep polling; surface progress to the user if shown. |
uploading | No | Keep polling; the file is nearly ready. |
complete | Yes | Read the asset URL and hand off the finished cut. |
failed | Yes | Read the failure reason; the job is in the dead-letter queue. |
When a render fails: retries and the dead-letter queue
Failure is a first-class part of the pipeline, not an afterthought. When a render hits a transient problem, a momentary resource hiccup, a slow upstream dependency, the worker retries automatically, you will not see the job flip to failed on the first stumble. It only lands in the terminal failed state after its retries are exhausted, at which point the job is moved to a dead-letter queue.
The dead-letter queue matters because it means failures are captured rather than lost. A job that cannot complete is preserved with its context so it can be inspected and, if appropriate, replayed, instead of vanishing into a log somewhere. When your polling loop sees failed, read the attached reason: a manifest that references a missing asset is a different problem from a transient infrastructure error, and only one of those is worth resubmitting unchanged.
A polling loop that behaves in production
A naive loop that hammers the status endpoint every 200 milliseconds wastes requests and tells you nothing extra. A well-behaved loop follows a few rules:
- Use a sensible interval with backoff. Start with a short interval while the job is likely
queuedorclaimed, then ease off as a long render proceeds. Renders take real wall-clock time; you do not need sub-second resolution. - Add jitter. If you submit many jobs at once, randomize your poll timing slightly so your requests do not arrive in a synchronized burst.
- Set a ceiling. Give every job a maximum wait. If a job has not reached a terminal state within your ceiling, alert rather than loop forever.
- Be idempotent. Re-reading render job status is always safe. Treat the read as the source of truth and avoid caching a stale status in your own state machine.
- Prefer events where you can. Polling is the universal fallback, but if your integration can receive a callback on completion, lean on that and poll only as a backstop.
If you are wiring this into application code rather than scripts, the SDK quickstart shows the same loop with the client library handling retries for you, and the broader developer guides cover authentication and error handling end to end.
From a job id to a file you can ship
When the status reaches complete, the job hands you a durable asset URL backed by an asset row in your storage. Because the render path produces a faststart MP4, that file begins playing before it has fully downloaded, useful when you are previewing in a browser or embedding in a client review. If you need a higher-resolution master, the same finished render can flow through the native upscaler seam to 4K or 8K without re-running the whole pipeline.
The end-to-end shape, submit, poll, retrieve, is identical whether you generated the film from a single sentence via the AI video API or hand-assembled every shot. The render-worker does not care how the manifest was authored; it only cares that the manifest is deterministic, which is exactly what lets you trust the status you poll.
Frequently asked questions
How do I check if a render finished via the API?
Poll the job endpoint with the job id you received when you submitted the render, and watch the status field. When it returns complete, the response includes the asset URL for the finished cut. Until then it will report a transient state such as queued, rendering, or uploading, so your loop should keep polling on a backoff interval until it sees a terminal status.
What happens when a render job fails?
The worker retries transient failures automatically, so a single hiccup will not surface as a failure. Only after the retries are exhausted does the job move to the terminal failed state and into the dead-letter queue, where it is preserved with its context so you can inspect the reason and decide whether to replay it. Read the attached failure reason before resubmitting, a bad manifest will fail again unchanged.
How often should I poll for render job status?
Use a short interval at first, while the job is likely queued, then back off as the render proceeds, and add a little jitter if you are running many jobs in parallel. Renders take real time, so sub-second polling buys you nothing and just burns requests. Always set a maximum wait so a stuck job triggers an alert instead of an infinite loop.
Is a render reproducible if I submit the same project twice?
Yes. The render-worker renders from a manifest, and the same manifest produces the same cut every time. That determinism is what makes the status you poll meaningful, a completed job's output will not drift, so you can cache the result against the manifest with confidence.
Ship renders you can rely on
A render pipeline you can poll with confidence is one you can build on: deterministic output, automatic retries, a dead-letter queue that catches the rest, and a clean status contract from queued to complete. That is the whole point of the deterministic render path, to make video generation behave like infrastructure instead of a slot machine. Start free with no credit card and submit your first render against the API today.