---
title: "Submit, track and retrieve a render"
canonical_url: https://docs.zvid.io/docs/operations/render-lifecycle/
source: docs/operations/render-lifecycle.md
content_revision: 6338386a1dd87e4a
---

# Submit, track and retrieve a render

A render submission creates an asynchronous job. Acceptance means the job was submitted, not that a video or image is ready.

## The complete flow

1. Build a project or select a stored template and variable values.
2. [Validate the exact request and inspect its cost](https://docs.zvid.io/docs/validate-and-estimate/).
3. Submit to the video or image endpoint. Credits are reserved during submission.
4. Store the returned `jobId` with your own business record before doing other work.
5. Poll `GET /api/jobs/{jobId}` or receive a [webhook](https://docs.zvid.io/docs/automation/webhooks/).
6. On completion, read the output URL and store it where your application needs it. On failure, record `failedReason` and decide whether the cause can be corrected.

The [downloadable Node.js example](https://docs.zvid.io/examples/render-once.mjs) implements validation, a single submission and bounded polling. It validates only unless you explicitly pass `--render`.

## Job state and progress

The queue may report intermediate states such as `waiting`, `delayed`, `prioritized`, `active` or `waiting-children`. Keep waiting within your deadline unless `state` is `completed` or `failed`. An unexpected state is useful diagnostic information; do not invent a successful result from it.

`progress` can be a number or an object with `percentage` and other stage information. It is a progress hint, not a completion test. A value of 100 does not replace checking `state` and `result`.

Job data can come from the live queue or stored history. Queue timestamps use epoch milliseconds; stored timestamp fields can be date strings. Normalize them before doing arithmetic. Do not assume the response has one timestamp representation forever.

## Extract the output URL

For a completed job, `result` can be an object with `url` or a URL string from stored history:

```js
const url = typeof job.result === "string" ? job.result : job.result?.url;
if (job.state === "completed" && !url) {
  throw new Error("Completed job has no output URL; retain the job ID for investigation.");
}
```

Only use the final media when the job reports completion and a usable URL. A thumbnail or preview is not the finished output. Keep your job ID alongside the output URL for support and reconciliation.

## Polling and webhooks

For polling, use a delay, an overall deadline and a timeout on each network request. Retry safe status reads after temporary failures; honor `Retry-After` when present. A polling timeout means the client stopped waiting, not that rendering failed. Resume tracking the **same** job.

For production automation, signed account webhooks avoid constant polling. Verify the original request bytes and timestamp, acknowledge promptly, and handle repeated deliveries idempotently. A per-request `webhookUrl` is unsigned; see [webhook security and payloads](https://docs.zvid.io/docs/automation/webhooks/).

## Failures, cancellation and retention

Submission failures and render failures are different. A rejected submission may have no job ID. An accepted job can later fail while fetching media or rendering. See [errors and retries](https://docs.zvid.io/docs/operations/errors-and-retries/) before resubmitting.

Job deletion requires a dashboard session/JWT; an API key can read job status but cannot call the delete endpoint. Deleting a queued job can cancel work and trigger the applicable refund behavior. An active job cannot simply be deleted; the API returns a conflict. Deleting a completed render can also remove its stored output. Treat deletion as a lifecycle action, not as a way to hide a dashboard row.

Do not assume CDN output is a permanent archive. If your product requires long-term retention, copy completed media to storage you control under your own retention policy. See [media and URLs](https://docs.zvid.io/docs/concepts/media-assets/).
