> ## 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.

# API

> Use the Renderjuice API to upload assets, create jobs, and query status directly from your studio tools and automation pipelines.

export const RequestAccessButton = () => {
  const handleClick = () => {
    if (typeof window !== 'undefined' && window.Intercom) {
      window.Intercom('showNewMessage', "Hello, I'm interested in requesting access to API & Webhooks for custom pipeline integration.");
    } else if (typeof window !== 'undefined') {
      setTimeout(() => {
        if (window.Intercom) {
          window.Intercom('show');
        }
      }, 100);
    }
  };
  return <div style={{
    margin: '8px 0'
  }}>
      <button onClick={handleClick} style={{
    backgroundColor: '#5B46D4',
    color: '#ffffff',
    padding: '6px 12px',
    border: 'none',
    borderRadius: '4px',
    cursor: 'pointer',
    fontSize: '14px',
    fontWeight: 500,
    fontFamily: 'inherit',
    transition: 'background-color 0.2s ease',
    display: 'inline-block'
  }} onMouseEnter={e => {
    e.currentTarget.style.backgroundColor = '#4A36C2';
  }} onMouseLeave={e => {
    e.currentTarget.style.backgroundColor = '#5B46D4';
  }}>
        Request Access
      </button>
    </div>;
};

<Callout icon="key" color="#FFC107" iconType="regular">
  **API & Webhooks** are available for studios requiring custom pipeline integration. To ensure we support your specific workflow, access is currently request-only.

  <RequestAccessButton />
</Callout>

The Renderjuice API gives you direct control over what happens on the platform. Where webhooks react to events Renderjuice fires, the API lets you initiate actions: upload source assets, create jobs, query job status, and coordinate multi-stage workflows from your own systems.

## How it works

The API gives you programmatic access to Renderjuice. You make authenticated requests to upload assets, create jobs, check status, and retrieve results on your schedule.

### API workflow

```mermaid theme={null}
sequenceDiagram
    participant Tool as Your Tool
    participant API as Renderjuice API

    Tool->>API: Authenticate with API key
    API-->>Tool: Access granted

    Tool->>API: Request upload URL
    API-->>Tool: uploadUrl + slug

    Tool->>API: Create job from slug
    API-->>Tool: Job created

    Note over Tool: Your system controls timing
```

## When to use the API

Reach for the API when you need to control what happens on Renderjuice:

### Job management

* **Submit renders from DCC tools** – Blender addons, Maya scripts, or custom exporters can upload source files and queue jobs without touching the dashboard.
* **Bulk operations** – submit hundreds of shots programmatically, retry failed jobs in batches, or adjust settings across a project.
* **Status monitoring** – build custom dashboards that poll job progress, aggregate metrics, or triage failures.

### Multi-stage workflows

* **Conditional rendering** – submit jobs only if upstream validation passes, or fork different render settings based on asset metadata.
* **Cross-system coordination** – tie Renderjuice jobs to farm nodes, compositing stages, or delivery pipelines that need precise timing control.

## Ingestion flow

The first external ingestion flow uses presigned single-request uploads for small source files.

### Step 1: Request a presigned upload URL

Your tool asks Renderjuice for an upload target with `POST /api/external/v1/uploads`. The response returns:

* `uploadUrl`: an opaque presigned `PUT` URL
* `slug`: the handle to pass into job creation later
* `expiresAt`: when the upload URL stops working

The upload endpoint is responsible for selecting the correct storage bucket and generating the `slug`. Clients should treat both `uploadUrl` and any storage-specific details as implementation details.

### Step 2: Upload the source asset directly

Upload the `.blend` or `.zip` bytes with a single `PUT` request to the returned URL. Renderjuice is not expected to proxy the file upload itself.

### Step 3: Create a job from the uploaded asset

After the upload completes, create a job with `POST /api/external/v1/jobs` using only the `slug` from step 1. You do not need to send the filename again.

### Step 4: Validate, render, and download

Once the job exists, the rest of the lifecycle follows the existing external endpoints:

* validate the job
* start render
* poll status and progress
* download results when complete

## First-release constraints

* Small `.blend` and `.zip` uploads only
* Single-request presigned uploads only
* Presigned single-request uploads are limited to files smaller than 5 GiB
* Multipart and resumable uploads are out of scope for the first public release
* Add-on uploads stay a separate workflow

## Example sequence

### 1. Request upload URL

```bash theme={null}
curl -X POST https://api.renderjuice.com/api/external/v1/uploads \
  -H "Authorization: Bearer RJ-ABC-XYZ..." \
  -H "Content-Type: application/json" \
  -d '{
    "fileName": "shot-010.zip",
    "fileType": "zip"
  }'
```

Example response:

```json theme={null}
{
  "uploadUrl": "https://storage.example.com/...",
  "slug": "amber-forest-1234",
  "expiresAt": "2026-03-26T18:30:00.000Z"
}
```

### 2. Upload file bytes

```bash theme={null}
curl -X PUT "$UPLOAD_URL" \
  -H "Content-Type: application/zip" \
  --data-binary "@shot-010.zip"
```

### 3. Create job

```bash theme={null}
curl -X POST https://api.renderjuice.com/api/external/v1/jobs \
  -H "Authorization: Bearer RJ-ABC-XYZ..." \
  -H "Content-Type: application/json" \
  -d '{
    "slug": "amber-forest-1234"
  }'
```

Example response:

```json theme={null}
{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "status": "created",
  "workspaceId": "123e4567-e89b-12d3-a456-426614174001",
  "createdAt": "2026-03-26T18:31:00.000Z",
  "updatedAt": "2026-03-26T18:31:00.000Z"
}
```

## Getting started

Ready to implement? See the [API Reference](/docs/api/introduction) for:

* Authentication and API key setup
* Upload and job lifecycle contracts
* Request/response schemas
* Interactive API playground

## Download filenames

When a job is ready, `GET /api/external/v1/jobs/:id/downloads` includes legacy URL arrays and structured output arrays. Use `frameOutputs[*].fileName` and `compositeNodeOutputs[*].fileName` for preserved original filenames; do not infer display names from the signed URL. For compositor outputs, use `compositeNodeOutputs[*].relativePath` when recreating output folders or ZIP entries.

## Best practices

* **Authenticate securely** – never hardcode API keys; use environment variables or secret managers.
* **Handle rate limits gracefully** – respect `429` responses and implement exponential backoff.
* **Combine with webhooks** – poll less frequently by relying on webhook notifications for completion events, then fetch details via the API only when needed.
* **Keep uploads opaque** – treat the presigned upload URL as a transport detail and keep using the returned `slug` as the Renderjuice-side identifier.
* **Validate inputs** – check file types, file sizes, and job payloads locally before submitting to catch errors early and reduce failed submissions.

## Next steps

<CardGroup cols={2}>
  <Card title="API Reference" icon="book" href="/docs/api/introduction">
    Authentication, uploads, endpoints, and payload schemas
  </Card>

  <Card title="Job lifecycle" icon="wand-magic-sparkles" href="/docs/api/job-lifecycle">
    Upload, create, validate, render, and download
  </Card>

  <Card title="Webhooks" icon="webhook" href="/docs/customizing-pipelines/webhooks">
    Pair the API with reactive event notifications
  </Card>
</CardGroup>
