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

# Video Translations

> Submit up to 100 video translation requests in a single call. Fan one source video out to many languages, then poll one batch id for per-item progress.

<img className="w-full h-44 object-cover rounded-xl" src="https://mintcdn.com/heygen-1fa696a7/hfMXXwJzjE7vBSYZ/images/theme/research-4.webp?fit=max&auto=format&n=hfMXXwJzjE7vBSYZ&q=85&s=ed7eea7e860c769f9b1b12804a27315a" alt="" noZoom width="1400" height="788" data-path="images/theme/research-4.webp" />

## Overview

Translation batches let you submit many translations in one request instead of calling [`POST /v3/video-translations`](/reference/create-video-translation) once per job. You send an array of translation payloads, get back a single `batch_id` right away, and poll that one id for the status and id of every item.

Each item in a batch is a standard translation payload — the exact shape [`POST /v3/video-translations`](/reference/create-video-translation) accepts — so anything you can translate on its own can be batched, in either [Speed](/docs/video-translate) or [Precision](/docs/video-translation-precision) mode.

<Note>
  A batch holds up to **100** items. A single payload targeting multiple `output_languages` expands to **one batch item per language**, and the expanded count is what the 100-item cap applies to. Each item is created and processed independently, so one bad source does not fail the rest.
</Note>

## Create a Batch

* Endpoint: `POST /v3/video-translations/batches`
* Purpose: Queue up to 100 translation payloads and return a `batch_id` immediately.

### Quick Example

One source video fanned out to three languages — this creates three batch items:

```bash theme={null}
curl -X POST "https://api.heygen.com/v3/video-translations/batches" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Q3 keynote — localized cuts",
    "callback_url": "https://example.com/hooks/heygen",
    "video_translations": [
      {
        "video": { "type": "url", "url": "https://example.com/keynote.mp4" },
        "title": "Q3 keynote",
        "output_languages": ["Spanish (Spain)", "French", "Japanese"],
        "mode": "speed"
      }
    ]
  }'
```

```json Response theme={null}
{
  "data": {
    "batch_id": "batch_tr_abc123"
  }
}
```

The call returns `202 Accepted` — the batch is queued, not finished. Use the returned `batch_id` to [poll for progress](#get-a-batch).

### Request Body

| Parameter            | Type   | Required | Default | Description                                                                                                                                                      |
| -------------------- | ------ | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `video_translations` | array  | Yes      | —       | Translation payloads, each identical in shape to [`POST /v3/video-translations`](/reference/create-video-translation). Up to 100 items after language expansion. |
| `title`              | string | No       | `null`  | Display name for the batch, shown in the HeyGen app.                                                                                                             |
| `callback_url`       | string | No       | `null`  | [Webhook](/docs/webhooks) URL invoked once when every item in the batch reaches a terminal state.                                                                |

Each entry in `video_translations` takes the full set of translation options — `video` (as a `url` or `asset_id`), `output_languages` (use [`GET /v3/video-translations/languages`](/reference/list-supported-translation-languages) for valid values), `mode` (`speed` or `precision`), plus captions, brand glossary, stock voice, partial-range, and format controls. See [`POST /v3/video-translations`](/reference/create-video-translation) for every field.

### Idempotency

Pass an `Idempotency-Key` header to make retries safe — replaying the same key returns the original batch instead of creating a duplicate.

## Get a Batch

* Endpoint: `GET /v3/video-translations/batches/{batch_id}`
* Purpose: Return the batch's aggregate status plus one page of items with their id and per-item status.

### Quick Example

```bash theme={null}
curl -X GET "https://api.heygen.com/v3/video-translations/batches/batch_tr_abc123?limit=100" \
  -H "x-api-key: YOUR_API_KEY"
```

```json Response theme={null}
{
  "data": {
    "batch_id": "batch_tr_abc123",
    "title": "Q3 keynote — localized cuts",
    "status": "processing",
    "total_items": 3,
    "counts_by_status": {
      "completed": 2,
      "processing": 1
    },
    "created_at": 1783891200,
    "items": [
      {
        "item_index": 0,
        "status": "completed",
        "video_id": "vt_9f2c...",
        "error": null
      },
      {
        "item_index": 1,
        "status": "completed",
        "video_id": "vt_81aa...",
        "error": null
      },
      {
        "item_index": 2,
        "status": "processing",
        "video_id": null,
        "error": null
      }
    ],
    "has_more": false,
    "next_token": null
  }
}
```

<Info>
  The batch read model is shared across the batch APIs, so the per-item id field is named `video_id` — for translation batches it holds the **video translation id**. Use it with [`GET /v3/video-translations/{video_translation_id}`](/reference/get-video-translation) for the full record and download URL.
</Info>

### Query Parameters

| Parameter | Type    | Required | Default | Description                                                       |
| --------- | ------- | -------- | ------- | ----------------------------------------------------------------- |
| `limit`   | integer | No       | `100`   | Items per page, `1`–`100`.                                        |
| `token`   | string  | No       | —       | Opaque pagination cursor from a previous response's `next_token`. |

The response shape matches the [video batch](/batch-videos#response-fields): aggregate `status` (`processing`, `completed`, or `failed`), `total_items`, `counts_by_status`, and a paged `items` array where each item carries `item_index`, `status` (`queued`, `processing`, `completed`, or `failed`), its id, and `error` details when failed.

## Bulk Statuses

* Endpoint: `GET /v3/video-translations/statuses`
* Purpose: Check up to 100 translations in one request — across batches, or for jobs created individually.

```bash theme={null}
curl -X GET "https://api.heygen.com/v3/video-translations/statuses?batch_ids=batch_tr_abc123" \
  -H "x-api-key: YOUR_API_KEY"
```

| Parameter               | Type   | Required | Description                                                         |
| ----------------------- | ------ | -------- | ------------------------------------------------------------------- |
| `video_translation_ids` | string | No       | Comma-separated translation ids to look up.                         |
| `batch_ids`             | string | No       | Comma-separated batch ids; each expands to its member translations. |

Statuses are `queued`, `processing`, `completed`, or `failed`, plus `not_found` for unknown or unowned ids.

## Tracking completion

* **Webhook (push).** Set `callback_url` on the batch to be notified once, when the last item reaches a terminal state, or subscribe to `video_translate.success` / `video_translate.fail` [webhook events](/docs/webhook-events) for per-item notifications.
* **Polling (pull).** Call `GET /v3/video-translations/batches/{batch_id}` and read `counts_by_status`. Items surface their translation id as soon as the job is created, so you can start fetching finished translations with [`GET /v3/video-translations/{video_translation_id}`](/reference/get-video-translation) while the rest of the batch is still processing.
