> ## Documentation Index
> Fetch the complete documentation index at: https://www.renderjuice.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Job lifecycle

> A visual guide to every job status transition in the Renderjuice API, from upload and validation through rendering to completion.

Visual overview:

### Upload and ingest

```mermaid theme={null}
flowchart LR
    U([request upload URL]) --> V([upload source file])
    V --> N([create job from slug]) --> A((created))

    classDef primary fill:#7B61FF,stroke:#4f33d1,color:#fff;
    class U,V,N,A primary;
```

### Validation

```mermaid theme={null}
flowchart LR
    A((created)) -- "POST /jobs/:id/validate" --> B((validating)) -- auto --> C((validated))

    classDef primary fill:#7B61FF,stroke:#4f33d1,color:#fff;
    class A,B,C primary;
```

### Render and completion

```mermaid theme={null}
flowchart LR
    C((validated)) -- "POST /jobs/:id/render" --> D((booting)) -- auto --> E((rendering)) -- auto --> H((completed))

    classDef primary fill:#7B61FF,stroke:#4f33d1,color:#fff;
    class C,D,E,H primary;
```

Auto transitions from `booting` → `rendering` → `completed` are handled by Renderjuice once render starts.

## Ingest flow

Creating a job is not the first API call.

1. Call `POST /api/external/v1/uploads` to request a presigned upload URL.
2. Upload a small `.blend` or `.zip` file directly to object storage.
3. Call `POST /api/external/v1/jobs` with the `slug` returned by the upload endpoint.
4. Renderjuice creates a job in `created` status.

This keeps uploads and job creation as separate steps, which makes retries and debugging easier for API clients.

## Status flow

* Upload step before job creation: request upload URL → upload file → create job
* `created` → `validating` → `validated` → `booting` → `rendering` → `finalizing` → `completed`
* Failure branch: any stage can move to `failed`.
* Cancel branch: cancel is accepted until work finishes; canceled jobs remain `canceled`.

## Allowed actions by status

* **Create job** (`POST /api/external/v1/jobs`): accepts a previously returned upload `slug` and creates a job in `created` status. You do not need to send the filename again.
* **Validate** (`POST /api/external/v1/jobs/:id/validate`): only from `created`; returns 400 if already validating/validated.
* **Render** (`POST /api/external/v1/jobs/:id/render`): call after `validated`. A missing or empty `requestedRenderConfig` yields 400.
* **Cancel** (`POST /api/external/v1/jobs/:id/cancel`): allowed while the job is in progress; expect failure once `completed`/`failed`/`canceled`.
* **Progress** (`GET /api/external/v1/jobs/:id/progress`, `GET /api/external/v1/jobs/progress`): available anytime; returns current counters or an empty array when nothing is running.
* **Downloads** (`GET /api/external/v1/jobs/:id/downloads`): returns download URLs once output is ready; earlier states respond with empty arrays. `frames` and `compositeNodes` are legacy URL arrays. Prefer `frameOutputs` and `compositeNodeOutputs` for new integrations because each entry includes the signed `url`, preserved original `fileName`, stereo/multiview `view` suffix when available, and `relativePath` for compositor outputs that should keep folders.

## Status reference

* `created`: upload already completed and job record exists; no validation/render started.
* `validating` → `validated`: validation in progress/finished.
* `booting`: workers are provisioning.
* `rendering`: frames are processing.
* `finalizing`: outputs are being packaged.
* `completed`: outputs are ready for download.
* `failed`: validation or render failed; check `failedReason`.
* `canceled`: user/system canceled the job.

## Webhooks

* Currently documented: `onRenderComplete` fires when a render finishes successfully.
