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

# Render videos in Python

> Render a video template as an MP4 and follow its progress with the Python SDK.

A video template renders as an MP4. Each second of the video counts as one generation. [Generate videos](/docs/essentials/generate-videos) explains how to design one.

Both methods take a template id and keyword arguments.

<ParamField body="template_id" type="str" required>
  The id of a video template, for example `tpl_xxx`.
</ParamField>

<ParamField body="modifications" type="list[dict]">
  The values to put into the template's layers. A video layer takes a `src`, and the modification named `music` changes the music. [Modifications](/docs/essentials/modifications) lists the fields each layer accepts.
</ParamField>

## Render and wait for the URL

`render_and_wait_video` returns `{"result": url}` or `{"error": {...}}`.

```python theme={null}
result = client.render_and_wait_video(
    "tpl_xxx",
    modifications=[
        {"name": "headline", "text": "Summer sale"},
        {"name": "music", "src": "https://example.com/song.mp3"},
    ],
)

if "error" in result:
    raise RuntimeError(result["error"]["message"])

print(result["result"])
```

## Follow the progress

`render_video` yields event dicts. The last event is `done` or `error`.

```python theme={null}
for event in client.render_video("tpl_xxx", modifications=[{"name": "headline", "text": "Summer sale"}]):
    if event["type"] == "queued":
        print(f"{event['ahead']} videos before this one")
    elif event["type"] == "progress":
        print(f"{event['progress']:.0%}")
    elif event["type"] == "done":
        print(event["url"])
    elif event["type"] == "error":
        print(event["error"]["message"])
```

| Event | Fields |
| - | - |
| `queued` | `ahead`: the number of videos before this one |
| `progress` | `frame`, `totalFrames`, and `progress` from 0 to 1 |
| `done` | `url`: the URL of the MP4 |
| `error` | `error`: `code`, `message`, and `requestId` |

A refused request, such as an invalid API key or a used-up quota, gives one `error` event. The client timeout applies only to the connection, because a video can wait in line for minutes.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.