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

# Create Render Job

> Start a video render job

Kick off a video render. Send the request as `multipart/form-data`.

<Note>
  **Two workflows available:**

  * **On-Demand:** Upload `ref_image` and `driving_video` directly -- no preprocessing, no stored assets. Costs 1 credit/second of video.
  * **Reusable Assets:** Pre-create characters and scenes for reuse across renders. Each render costs 1 credit/second.
</Note>

<Warning>
  **Video limits:** `driving_video` uploads are limited to **10 minutes** duration and **100 MB** file size.
</Warning>

## Parameters

Send as `multipart/form-data`. Supply the character as **either** `ref_image`/`ref_image_url` **or** a pre-created `character_id`, and the motion as **either** `driving_video`/`driving_video_url` **or** a pre-created `scene_id`.

| Parameter           | Type   | Description                                                                                  |
| ------------------- | ------ | -------------------------------------------------------------------------------------------- |
| `ref_image`         | file   | Character reference image (PNG, JPG). Use this or `ref_image_url` or `character_id`.         |
| `ref_image_url`     | string | URL to a character image; the server fetches it.                                             |
| `character_id`      | string | ID of a `ready` [character](/api-reference/characters/create) (reusable-asset workflow).     |
| `driving_video`     | file   | Driving video (MP4). Use this or `driving_video_url` or `scene_id`. Max 10 min / 100 MB.     |
| `driving_video_url` | string | URL to a driving video; the server fetches it.                                               |
| `scene_id`          | string | ID of a `ready` [scene](/api-reference/scenes/create) (reusable-asset workflow).             |
| `model`             | string | `V3_Preview` (default) or `V4_Preview`. Must match how the character/scene was preprocessed. |
| `background_mode`   | string | `original` (default), `solid`, or `transparent`. See [Compositing](/guides/compositing).     |
| `bg_color`          | string | RGB for a solid background, e.g. `"0,255,0"`. Only used when `background_mode` is `solid`.   |

## Response

```json theme={null}
{
  "job_id": "job_abc123xyz",
  "status": "queued",
  "mode": "full_pipeline",
  "enqueued_at": "2026-06-12T08:00:00Z",
  "poll_url": "/api/render/job_abc123xyz",
  "status_url": "/api/render/job_abc123xyz"
}
```

| Field                     | Description                                                                             |
| ------------------------- | --------------------------------------------------------------------------------------- |
| `job_id`                  | Identifier for the render. Poll [Get Job Status](/api-reference/render/status) with it. |
| `status`                  | Starts at `queued`.                                                                     |
| `poll_url` / `status_url` | Convenience path to poll for status.                                                    |

## Error Handling

If the request fails, the response includes a structured error with an `error_code`:

```json theme={null}
{
  "detail": {
    "error_code": "CS-ORIV-001",
    "message": "Reference image is required",
    "action": "Upload a ref_image (PNG/JPG)"
  }
}
```

Common error codes for this endpoint:

| Code          | Cause                   | Fix                                          |
| ------------- | ----------------------- | -------------------------------------------- |
| `CS-ORAU-001` | Missing API key         | Add `Authorization: Bearer sk-...` header    |
| `CS-ORAU-002` | Invalid API key         | Check your key is correct                    |
| `CS-ORIV-001` | Missing reference image | Upload `ref_image`                           |
| `CS-ORIV-002` | Missing driving video   | Upload `driving_video` or provide `scene_id` |
| `CS-ORIV-004` | Video too long          | Keep under 10 minutes                        |
| `CS-ORCR-001` | Insufficient credits    | Top up credits                               |

See [Error Codes](/error-codes) for the full list. When contacting **[support@viggle.ai](mailto:support@viggle.ai)**, include the `error_code` and your job ID.

## Examples

### On-Demand Render (upload files directly)

<CodeGroup>
  ```python Python theme={null}
  import requests

  url = "https://apis.viggle.ai/api/render"
  headers = {"Authorization": "Bearer YOUR_API_KEY"}

  with open("character.png", "rb") as img, open("driving.mp4", "rb") as vid:
      resp = requests.post(
          url,
          headers=headers,
          files={
              "ref_image": ("character.png", img, "image/png"),
              "driving_video": ("driving.mp4", vid, "video/mp4"),
          },
          data={"background_mode": "original"},
      )

  data = resp.json()
  if "detail" in data:
      print(f"Error {data['detail']['error_code']}: {data['detail']['message']}")
  else:
      print(f"Job created: {data['job_id']}")
      print(f"Poll: GET /api/render/{data['job_id']}")
  ```

  ```javascript JavaScript theme={null}
  const form = new FormData();
  form.append("ref_image", await fetch("character.png").then(r => r.blob()), "character.png");
  form.append("driving_video", await fetch("driving.mp4").then(r => r.blob()), "driving.mp4");
  form.append("background_mode", "original");

  const resp = await fetch("https://apis.viggle.ai/api/render", {
    method: "POST",
    headers: { "Authorization": "Bearer YOUR_API_KEY" },
    body: form,
  });

  const data = await resp.json();
  if (data.detail) {
    console.error(`Error ${data.detail.error_code}: ${data.detail.message}`);
  } else {
    console.log(`Job created: ${data.job_id}`);
    console.log(`Poll: GET /api/render/${data.job_id}`);
  }
  ```

  ```bash cURL theme={null}
  curl -X POST "https://apis.viggle.ai/api/render" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -F "ref_image=@character.png" \
    -F "driving_video=@driving.mp4" \
    -F "background_mode=original"
  ```
</CodeGroup>

### Reusable Assets Render (pre-created character + scene)

<CodeGroup>
  ```python Python theme={null}
  import requests

  url = "https://apis.viggle.ai/api/render"
  headers = {"Authorization": "Bearer YOUR_API_KEY"}

  resp = requests.post(
      url,
      headers=headers,
      data={
          "character_id": "char_550e8400e29b41d4",
          "scene_id": "scene_660e8400e29b41d4",
          "background_mode": "original",
      },
  )

  data = resp.json()
  if "detail" in data:
      print(f"Error {data['detail']['error_code']}: {data['detail']['message']}")
  else:
      print(f"Job created: {data['job_id']}")
  ```

  ```javascript JavaScript theme={null}
  const form = new FormData();
  form.append("character_id", "char_550e8400e29b41d4");
  form.append("scene_id", "scene_660e8400e29b41d4");
  form.append("background_mode", "original");

  const resp = await fetch("https://apis.viggle.ai/api/render", {
    method: "POST",
    headers: { "Authorization": "Bearer YOUR_API_KEY" },
    body: form,
  });

  const data = await resp.json();
  if (data.detail) {
    console.error(`Error ${data.detail.error_code}: ${data.detail.message}`);
  } else {
    console.log(`Job created: ${data.job_id}`);
  }
  ```

  ```bash cURL theme={null}
  curl -X POST "https://apis.viggle.ai/api/render" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -F "character_id=char_550e8400e29b41d4" \
    -F "scene_id=scene_660e8400e29b41d4" \
    -F "background_mode=original"
  ```
</CodeGroup>

## Next Steps

After creating a render job, poll [Get Job Status](/api-reference/render/status) every 3-5 seconds (no auth required). When `status` is `complete`, use the `cdn_url` field to download the final video.


## OpenAPI

````yaml POST /api/render
openapi: 3.0.3
info:
  title: Viggle API
  description: Generate AI-powered character animation videos
  version: 2.0.0
  contact:
    name: Viggle Support
    url: https://viggle.ai
servers:
  - url: https://apis.viggle.ai
    description: Production server
security: []
paths:
  /api/render:
    post:
      tags:
        - Render
      summary: Create Render Job
      description: >-
        Start a video render job. Accepts multipart/form-data with file uploads
        and render options as form fields.
      operationId: createRenderJob
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                ref_image:
                  type: string
                  format: binary
                  description: >-
                    Character reference image file (PNG, JPG). Use this or
                    ref_image_url.
                ref_image_url:
                  type: string
                  format: uri
                  description: >-
                    URL to a character image. The server fetches it. Use instead
                    of ref_image file upload.
                  example: https://example.com/character.png
                driving_video:
                  type: string
                  format: binary
                  description: >-
                    Driving video file (MP4). Use this or driving_video_url.
                    Maximum 10 minutes duration and 100 MB file size.
                driving_video_url:
                  type: string
                  format: uri
                  description: >-
                    URL to a driving video. The server fetches it. Use instead
                    of driving_video file upload.
                  example: https://example.com/dance.mp4
                character_id:
                  type: string
                  description: ID of a ready character (for preprocessed renders)
                  example: char_550e8400e29b41d4
                scene_id:
                  type: string
                  description: ID of a ready scene (for preprocessed renders)
                  example: scene_660e8400e29b41d4
                model:
                  type: string
                  enum:
                    - V4_Preview
                    - V3_Preview
                  default: V3_Preview
                  description: >-
                    Avatar model. Defaults to V3_Preview. Scenes preprocessed on
                    one model cannot be rendered on the other.
                background_mode:
                  type: string
                  enum:
                    - original
                    - solid
                    - transparent
                  default: original
                  description: >-
                    Background handling: original (default, person removed via
                    AI inpainting), solid (single color), transparent (alpha
                    mask for compositing)
                bg_color:
                  type: string
                  description: >-
                    RGB string for solid background color, e.g., "0,255,0". Only
                    used when background_mode is solid.
                  example: 0,255,0
      responses:
        '200':
          description: Render job created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RenderCreated'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          description: Asset not ready or invalid parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorStructured'
              example:
                detail:
                  error_code: CS-ORIV-002
                  message: >-
                    Character or scene is not ready yet, or a required parameter
                    is missing. Wait until the asset status is ready.
      security:
        - bearerAuth: []
components:
  schemas:
    RenderCreated:
      type: object
      properties:
        job_id:
          type: string
          example: job_abc123xyz
        status:
          type: string
          example: queued
        mode:
          type: string
          description: The render mode (e.g. full_pipeline, preprocessed)
          example: full_pipeline
        enqueued_at:
          type: string
          format: date-time
        poll_url:
          type: string
          description: URL to poll for job status
          example: /api/render/job_abc123xyz
        status_url:
          type: string
          description: URL to get job status
          example: /api/render/job_abc123xyz
    ErrorStructured:
      type: object
      description: >-
        Structured error. `detail` carries a machine-readable `error_code` plus
        a human-readable `message`.
      properties:
        detail:
          type: object
          properties:
            error_code:
              type: string
              example: CS-UORC01-008
            message:
              type: string
              example: Insufficient credits. Top up your balance to continue.
    Error:
      type: object
      description: >-
        Simple error. `detail` is a human-readable message (used for auth
        errors).
      properties:
        detail:
          type: string
          example: 'API key required. Use Authorization: Bearer sk-xxx'
  responses:
    Unauthorized:
      description: Missing or invalid API key
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            detail: >-
              Invalid or missing API key. Pass it as Authorization: Bearer
              sk-...
    InsufficientCredits:
      description: Insufficient credits
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorStructured'
          example:
            detail:
              error_code: CS-UORC01-008
              message: Insufficient credits. Top up your balance to continue.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: API key passed as Bearer token

````