> For the complete documentation index, see [llms.txt](https://docs.castmagic.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.castmagic.io/endpoints/renders.md).

# Renders

Render a captioned clip or audiogram from a recording.

Render a captioned clip (for video recordings) or an audiogram (for audio recordings) from a segment of a recording. Rendering is asynchronous — poll `GET /v1/renders/:id` for progress and the finished asset URL.

The recording must have a **completed transcript**. Clips are capped at **3 minutes**.

{% hint style="info" %}
**Tier:** `platform`. Base URL `https://app.castmagic.io`.
{% endhint %}

## Create a render

<mark style="color:green;">`POST`</mark> `https://app.castmagic.io/v1/renders`

Give a window with `start_ms`/`end_ms`, **or** pass a `suggestion_id` from [`GET /v1/recordings/:id/clip-suggestions`](/endpoints/clip-suggestions.md) to use that suggestion's window and title.

#### Request Body

| Name                                             | Type    | Description                                                                       |
| ------------------------------------------------ | ------- | --------------------------------------------------------------------------------- |
| recording\_id<mark style="color:red;">\*</mark>  | String  | The recording to render from                                                      |
| start\_ms<mark style="color:red;">\*</mark>      | Integer | Clip start in ms (required unless `suggestion_id` is given), window max 3 minutes |
| end\_ms<mark style="color:red;">\*</mark>        | Integer | Clip end in ms (required unless `suggestion_id` is given)                         |
| suggestion\_id<mark style="color:red;">\*</mark> | String  | Use a clip suggestion's window and title (alternative to `start_ms`/`end_ms`)     |
| aspect\_ratio                                    | String  | `9:16` (default) · `1:1` · `16:9` · `4:5` · `original`                            |
| title                                            | String  | Overlay title                                                                     |

{% hint style="info" %}
The window snaps to spoken words. A window with no speech is rejected.
{% endhint %}

{% tabs %}
{% tab title="202: Accepted" %}

```json
{
    "render": {
        "id": "r1...",
        "status": "rendering",
        "style": "captions",
        "aspect_ratio": "9:16",
        "start_ms": 154000,
        "end_ms": 178000,
        "progress": 0.02,
        "message": "Queued for export...",
        "asset_url": null,
        "created_at": "2026-08-21T22:15:00Z"
    }
}
```

{% endtab %}

{% tab title="400: Bad Request Silent window" %}

```json
{ "error": "no speech in that window; pick a range with spoken words" }
```

{% endtab %}
{% endtabs %}

## Fetch a render

<mark style="color:blue;">`GET`</mark> `https://app.castmagic.io/v1/renders/:id`

Poll for progress. Statuses are `rendering`, `completed`, and `failed`. When `completed`, `asset_url` is a signed URL.

{% tabs %}
{% tab title="200: OK completed" %}

```json
{
    "render": {
        "id": "r1...",
        "status": "completed",
        "style": "captions",
        "aspect_ratio": "9:16",
        "start_ms": 154000,
        "end_ms": 178000,
        "progress": 1.0,
        "message": "Done",
        "asset_url": "https://storage.googleapis.com/...",
        "created_at": "2026-08-21T22:15:00Z"
    }
}
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
`asset_url` is a signed URL valid for about an hour. Re-fetch the render for a fresh URL if it expires.
{% endhint %}
