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

# Renders

> Create, inspect, and download asynchronous V1 video renders.

A Render combines one Character source, one Motion source, and optional background settings into a video. All Render endpoints require `Authorization: Bearer YOUR_API_KEY`.

## Create a Render

`POST /v1/renders`

Send `multipart/form-data`. For both Character and Motion, choose either a reusable ID or a direct input.

### Character input

| Field          | Type   |  Required  | Description                                                                       |
| -------------- | ------ | :--------: | --------------------------------------------------------------------------------- |
| `character_id` | string | One source | Ready full Character ID, for example `char_550e8400-e29b-41d4-a716-446655440000`. |
| `image`        | file   | One source | Character image uploaded directly.                                                |
| `image_url`    | string | One source | Public URL for a character image.                                                 |

### Motion input

| Field              | Type   |  Required  | Description                                                                   |
| ------------------ | ------ | :--------: | ----------------------------------------------------------------------------- |
| `motion_id`        | string | One source | Ready full Motion ID, for example `mot_550e8400-e29b-41d4-a716-446655440000`. |
| `motion_video`     | file   | One source | Driving video uploaded directly.                                              |
| `motion_video_url` | string | One source | Public URL for a driving video.                                               |

### Render settings

| Field             | Type   |   Required   | Default    | Description                                  |
| ----------------- | ------ | :----------: | ---------- | -------------------------------------------- |
| `background_mode` | string |      No      | `original` | `original`, `solid`, or `transparent`.       |
| `bg_color`        | string | With `solid` | —          | RGB color as `R,G,B`, for example `0,255,0`. |

For each input family, send one source. For example, use `character_id` with a newly uploaded `motion_video`, or upload both inputs for a one-time Render.

### Valid source combinations

| Character source      | Motion source                       | Typical use                            |
| --------------------- | ----------------------------------- | -------------------------------------- |
| `image` / `image_url` | `motion_video` / `motion_video_url` | One-time Render.                       |
| `character_id`        | `motion_video` / `motion_video_url` | Reuse one Character with a new Motion. |
| `image` / `image_url` | `motion_id`                         | Reuse one Motion with a new Character. |
| `character_id`        | `motion_id`                         | Reuse both assets.                     |

`bg_color` is rejected unless `background_mode=solid`. `transparent` returns an additional `alpha_url` when ready.

### Example: one-time Render

```bash theme={null}
curl -X POST "https://apis.viggle.ai/v1/renders" \
  -H "Authorization: Bearer $VIGGLE_API_KEY" \
  -F "image=@character.png" \
  -F "motion_video=@dance.mp4" \
  -F "background_mode=original"
```

### Example: reuse assets with transparent output

```bash theme={null}
curl -X POST "https://apis.viggle.ai/v1/renders" \
  -H "Authorization: Bearer $VIGGLE_API_KEY" \
  -F "character_id=char_123abc" \
  -F "motion_id=mot_456def" \
  -F "background_mode=transparent"
```

```json theme={null}
{
  "id": "render_789ghi",
  "status": "queued",
  "progress": 0,
  "stage": null,
  "video_url": null,
  "alpha_url": null,
  "created_at": "2026-07-17T10:00:00Z",
  "completed_at": null,
  "error": null
}
```

### Python example: create and poll

```python theme={null}
import os
import time
import requests

headers = {"Authorization": f"Bearer {os.environ['VIGGLE_API_KEY']}"}
with open("character.png", "rb") as image, open("dance.mp4", "rb") as motion:
    response = requests.post(
        "https://apis.viggle.ai/v1/renders",
        headers=headers,
        files={"image": image, "motion_video": motion},
        data={"background_mode": "original"},
    )
response.raise_for_status()
render = response.json()

while render["status"] in {"queued", "processing"}:
    time.sleep(3)
    response = requests.get(
        f"https://apis.viggle.ai/v1/renders/{render['id']}", headers=headers
    )
    response.raise_for_status()
    render = response.json()

if render["status"] == "ready":
    print(render["video_url"])
else:
    print(render["error"])
```

## Get a Render

`GET /v1/renders/{render_id}`

| Path parameter | Type   | Required | Description                                                                           |
| -------------- | ------ | :------: | ------------------------------------------------------------------------------------- |
| `render_id`    | string |    Yes   | Full Render ID returned by `POST /v1/renders`, for example `render_8f50b2c2c2b84ae0`. |

```bash theme={null}
curl "https://apis.viggle.ai/v1/renders/render_789ghi" \
  -H "Authorization: Bearer $VIGGLE_API_KEY"
```

Poll every 3–5 seconds until the Render is terminal: `ready`, `failed`, or `cancelled`.

### Ready and failed responses

```json theme={null}
{
  "id": "render_789ghi",
  "status": "ready",
  "progress": 100,
  "stage": null,
  "video_url": "https://assets.viggle.ai/results/output.mp4",
  "alpha_url": null,
  "created_at": "2026-07-17T10:00:00Z",
  "completed_at": "2026-07-17T10:01:10Z",
  "error": null
}
```

```json theme={null}
{
  "id": "render_789ghi",
  "status": "failed",
  "progress": null,
  "stage": null,
  "video_url": null,
  "alpha_url": null,
  "error": {
    "code": "task_failed",
    "message": "The render could not be completed.",
    "request_id": "req_123abc"
  }
}
```

## Download a Render

`GET /v1/renders/{render_id}/download`

| Path parameter | Type   | Required | Description                                                  |
| -------------- | ------ | :------: | ------------------------------------------------------------ |
| `render_id`    | string |    Yes   | Full ready Render ID, for example `render_8f50b2c2c2b84ae0`. |

```bash theme={null}
curl -L "https://apis.viggle.ai/v1/renders/render_789ghi/download" \
  -H "Authorization: Bearer $VIGGLE_API_KEY" \
  -o output.mp4
```

The endpoint redirects to the finished video. You can also download `video_url` from a ready Render response.

## Cancel a Render

`DELETE /v1/renders/{render_id}`

Cancel a queued or processing Render owned by the current account. If the Render is already terminal, the response reports its current terminal status.

```bash theme={null}
curl -X DELETE "https://apis.viggle.ai/v1/renders/render_8f50b2c2c2b84ae0" \
  -H "Authorization: Bearer $VIGGLE_API_KEY"
```

```json theme={null}
{
  "id": "render_8f50b2c2c2b84ae0",
  "status": "cancelled",
  "progress": null,
  "stage": null,
  "video_url": null,
  "alpha_url": null,
  "created_at": null,
  "completed_at": null,
  "error": null
}
```

## Response and status rules

| Endpoint                               | Success status | Response      | Notes                                                              |
| -------------------------------------- | -------------- | ------------- | ------------------------------------------------------------------ |
| `POST /v1/renders`                     | `200`          | Render object | Starts as `queued`.                                                |
| `GET /v1/renders/{render_id}`          | `200`          | Render object | A failed Render still returns `200`; inspect `status` and `error`. |
| `DELETE /v1/renders/{render_id}`       | `200`          | Render object | Returns `cancelled` or the Render's existing terminal status.      |
| `GET /v1/renders/{render_id}/download` | `302`          | Redirect      | Available only when the Render is ready.                           |

## Render response fields

| Field                         | Type                    | Description                                                                                                    |
| ----------------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------- |
| `id`                          | string                  | Public Render ID, for example `render_8f50b2c2c2b84ae0`. Preserve it exactly for status and download requests. |
| `status`                      | string                  | `queued`, `processing`, `ready`, `failed`, or `cancelled`.                                                     |
| `progress`                    | integer or null         | Progress from 0 to 100 when available.                                                                         |
| `stage`                       | string or null          | `analyzing`, `rendering`, or `finishing` while processing.                                                     |
| `video_url`                   | string or null          | Final video URL when status is `ready`.                                                                        |
| `alpha_url`                   | string or null          | Alpha-mask video URL for transparent output.                                                                   |
| `created_at` / `completed_at` | ISO 8601 string or null | Render timestamps.                                                                                             |
| `error`                       | object or null          | Present when status is `failed`.                                                                               |
