> ## Documentation Index
> Fetch the complete documentation index at: https://heygen-1fa696a7.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Transparent Background Videos

> Generate avatar videos with a transparent background (alpha channel) using the HeyGen API. Set output_format to webm to get a compositing-ready video with no background.

To get an avatar video with a transparent background, request the **WebM** output format on [`POST /v3/videos`](/reference/create-video). WebM carries an alpha channel; MP4 does not. This is the single most-missed setting — the default output is a standard MP4 with an opaque background, so if you don't ask for WebM you will never get transparency.

<Warning>
  **Your avatar must support matting.** Transparent output only works when the avatar was trained with matting (background separation) enabled. Matting is enabled by default for recently-created avatars, so most video avatars (Digital Twins and Studio Avatars) support transparent output. If an avatar wasn't trained with matting, the WebM request is rejected with a clear error — *"This video avatar does not support webm output. The avatar must be trained with matting enabled."* — so you can request WebM and handle that error rather than guessing up front. If you hit it, use a more recently-created avatar (or confirm with the avatar's owner).
</Warning>

## Prerequisites

<Check>
  An `avatar_id` for a matting-trained avatar — matting is the default for recently-created avatars. Use `GET /v3/avatars/looks` to browse your looks and copy an `id`.
</Check>

<Check>
  A `voice_id` for the voice you want. Use `GET /v3/voices` to browse available voices. (You can omit `voice_id` when using an `avatar_id` — the avatar's default voice is used.)
</Check>

## The one required switch: `output_format`

`output_format` accepts two values:

| Value  | Result                                                                             |
| ------ | ---------------------------------------------------------------------------------- |
| `mp4`  | **Default.** Standard video, opaque background. No alpha channel.                  |
| `webm` | Transparent background — a WebM file with an alpha channel, ready for compositing. |

Selecting `output_format: "webm"` does three things automatically:

1. Returns a WebM file with a real alpha channel.
2. Applies background removal for you — you do **not** need to set `remove_background`.
3. Rejects any `background` value in the same request (you can't both remove and set a background).

So the minimum change to turn a normal avatar video into a transparent one is adding a single field: `"output_format": "webm"`.

## Step 1 — Create the video

Send a `POST` to `/v3/videos` with `type: "avatar"`, your avatar and voice, and `output_format: "webm"`:

```bash theme={null}
curl -X POST "https://api.heygen.com/v3/videos" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "avatar",
    "avatar_id": "YOUR_AVATAR_LOOK_ID",
    "script": "Hi! This video has a transparent background, ready to drop onto any scene.",
    "voice_id": "YOUR_VOICE_ID",
    "title": "Transparent Background Demo",
    "resolution": "1080p",
    "aspect_ratio": "16:9",
    "output_format": "webm"
  }'
```

<Note>
  `output_format: "webm"` already removes the background. Passing `"remove_background": true` alongside it is redundant but harmless. Do **not** also pass a `background` object — with WebM it is rejected.
</Note>

The response confirms the resolved format so you can verify WebM was accepted:

```json theme={null}
{
  "data": {
    "video_id": "v_abc123def456",
    "status": "waiting",
    "output_format": "webm"
  }
}
```

Copy `data.video_id` for the next step. If `data.output_format` comes back as `mp4`, your request did not select WebM — recheck the field name and value.

## Step 2 — Poll for completion

Video generation is asynchronous. Poll `GET /v3/videos/{video_id}` until `status` is `completed`:

```bash theme={null}
curl -X GET "https://api.heygen.com/v3/videos/YOUR_VIDEO_ID" \
  -H "x-api-key: YOUR_API_KEY"
```

| Status       | Meaning                                        |
| ------------ | ---------------------------------------------- |
| `pending`    | Queued for processing                          |
| `processing` | Video is being generated                       |
| `completed`  | Ready — `video_url` points to the `.webm` file |
| `failed`     | Something went wrong — check `failure_message` |

When `status` is `completed`, `data.video_url` is a presigned download link to your transparent WebM.

## Full example

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

API_KEY = "YOUR_API_KEY"
BASE = "https://api.heygen.com"
HEADERS = {"x-api-key": API_KEY, "Content-Type": "application/json"}

# 1. Create a transparent-background video.
#    output_format="webm" is the ONLY switch you need — it also removes the background.
resp = requests.post(f"{BASE}/v3/videos", headers=HEADERS, json={
    "type": "avatar",
    "avatar_id": "YOUR_AVATAR_LOOK_ID",
    "script": "Hi! This video has a transparent background.",
    "voice_id": "YOUR_VOICE_ID",
    "resolution": "1080p",
    "aspect_ratio": "16:9",
    "output_format": "webm",
})
data = resp.json()["data"]
video_id = data["video_id"]
assert data["output_format"] == "webm", "WebM was not selected — check your request"
print(f"Video created: {video_id}")

# 2. Poll until done.
while True:
    detail = requests.get(f"{BASE}/v3/videos/{video_id}", headers=HEADERS).json()["data"]
    print(f"Status: {detail['status']}")
    if detail["status"] == "completed":
        print(f"Transparent WebM: {detail['video_url']}")
        break
    if detail["status"] == "failed":
        print(f"Error: {detail.get('failure_message')}")
        break
    time.sleep(10)
```

## Why MP4 can't be transparent

MP4 (H.264/H.265) has no alpha channel — the container and codecs simply can't store per-pixel transparency. Any request that leaves `output_format` at its `mp4` default produces an opaque video, no matter what else you set. Transparency requires a format that supports alpha, which on this API is **WebM**. If you need a different alpha-capable container (for example MOV/ProRes 4444 for a video editor), render the WebM and transcode it locally.

## Common pitfalls

* **Left `output_format` at the default.** Omitting it gives you an opaque MP4. Add `"output_format": "webm"`.
* **Set `remove_background: true` but kept MP4.** Background removal without WebM does not give you a usable transparent file — MP4 can't carry the alpha channel. Use `output_format: "webm"` (which removes the background for you).
* **Used an avatar that wasn't trained with matting.** WebM requires a matting-enabled avatar; otherwise the request is rejected with a clear error. Matting is on by default for recently-created avatars — if you hit this, try a more recent avatar. See the warning at the top.
* **Passed a `background` object together with `webm`.** WebM removes the background and rejects any `background` value — send one or the other, not both.
* **Expected the file extension to change on its own.** The transparency comes from the WebM container returned in `video_url`, not from renaming an MP4.

## Avatar IV, Avatar V, Avatar III, and photo avatars

`output_format` is a top-level field on the create request, independent of the rendering engine, so transparent background works the same across all avatar engines:

* **Avatar IV** (the default engine when `engine` is omitted) — no change needed; just add `output_format: "webm"`.
* **Avatar V** — pass `"engine": {"type": "avatar_v"}` and `"output_format": "webm"` together. Transparency is set the same way.
* **[Avatar III](/avatar-iii)** — pass `"engine": {"type": "avatar_iii"}` and `"output_format": "webm"` together. Works with digital twin, studio avatar, and photo avatar looks alike.
* **Photo avatars** — use `type: "avatar"` with the photo-avatar look `id` and `output_format: "webm"`, same as a Digital Twin.

The transparent-background switch also applies to [image-driven videos](/image-to-video) (`type: "image"`) — set `output_format: "webm"` there too.

<Note>
  Transparent output is **not** available for Cinematic Avatar (`type: "cinematic_avatar"`). That mode has no `output_format` field.
</Note>

## Next steps

* [Digital Twin videos](/generate-avatar-video) — the full avatar-video flow and all optional parameters
* [Image to Video](/image-to-video) — animate a photo, also supports transparent WebM
* [Create Video API reference](/reference/create-video) — the complete `POST /v3/videos` schema
