# HeyGen Translate (speed) (dub) > HeyGen Translate re-voices a finished video and moves the speaker's mouth to match the new language. The speed tier is the faster and cheaper of the two HeyGen lanes. Status: roasOS API v1.1. Catalog `model-catalog@2026-10-06.v5`, pricing `customer-pricing@2026-11-05.v15`. The endpoint `POST /v1/dub/heygen-speed` is live. `POST /v1/generations` has no `dub` type, so this endpoint is the only path to this model. ## Endpoint POST https://api.roasos.com/v1/dub/heygen-speed Auth: Authorization: Bearer roasos_sk_… (scope api:write). Idempotency-Key required. quote_only / quote_id / webhook_url as in https://docs.roasos.com/llms.txt. ## Good at Take a talking-head ad into a second market and keep it looking shot in that language. Use this tier for volume: many languages, quick turnaround, and lip-sync that is good rather than perfect. Use `heygen-precision` when one hero asset must hold up on a large screen. The price is $0.05 for each second of the OUTPUT video, not the input. roasOS quotes the input plus 25% and settles on the real output length, so the charge is at or below the number you saw and never above it. ## Pricing Unit: source_second. Pricing key: `heygen-speed`. | request | credits | |---|---| | `30s_source` | 23 | | `60s_source` | 45 | | `120s_source` | 90 | Credits come from the roasOS pricing table (`MODEL_COSTS`) through the catalog. No other field changes the price. ## Modes - `video-dub` Provider endpoints: `fal-ai/heygen/v2/translate/speed`. ## Request fields | field | type | required | default | rule | |---|---|---|---|---| | `enable_dynamic_duration` | boolean | no | `false` | — | | `language` | enum | yes | — | `English`, `Spanish`, `French`, `Hindi`, `Italian`, `German`, `Polish`, `Portuguese`, `Chinese`, `Japanese`, `Dutch`, `Turkish`, `Korean`, `Danish`, `Arabic`, `Romanian`, `Mandarin`, `Filipino`, `Swedish`, `Indonesian`, `Ukrainian`, `Greek`, `Czech`, `Bulgarian`, `Malay`, `Slovak`, `Croatian`, `Tamil`, `Finnish`, `Russian`, `Afrikaans (South Africa)`, `Albanian (Albania)`, `Amharic (Ethiopia)`, `Arabic (Algeria)`, `Arabic (Bahrain)`, `Arabic (Egypt)`, `Arabic (Iraq)`, `Arabic (Jordan)`, `Arabic (Kuwait)`, `Arabic (Lebanon)`, `Arabic (Libya)`, `Arabic (Morocco)`, `Arabic (Oman)`, `Arabic (Qatar)`, `Arabic (Saudi Arabia)`, `Arabic (Syria)`, `Arabic (Tunisia)`, `Arabic (United Arab Emirates)`, `Arabic (Yemen)`, `Armenian (Armenia)`, `Azerbaijani (Latin, Azerbaijan)`, `Bangla (Bangladesh)`, `Basque`, `Bengali (India)`, `Bosnian (Bosnia and Herzegovina)`, `Bulgarian (Bulgaria)`, `Burmese (Myanmar)`, `Catalan`, `Chinese (Cantonese, Traditional)`, `Chinese (Jilu Mandarin, Simplified)`, `Chinese (Mandarin, Simplified)`, `Chinese (Northeastern Mandarin, Simplified)`, `Chinese (Southwestern Mandarin, Simplified)`, `Chinese (Taiwanese Mandarin, Traditional)`, `Chinese (Wu, Simplified)`, `Chinese (Zhongyuan Mandarin Henan, Simplified)`, `Chinese (Zhongyuan Mandarin Shaanxi, Simplified)`, `Croatian (Croatia)`, `Czech (Czechia)`, `Danish (Denmark)`, `Dutch (Belgium)`, `Dutch (Netherlands)`, `English (Australia)`, `English (Canada)`, `English (Hong Kong SAR)`, `English (India)`, `English (Ireland)`, `English (Kenya)`, `English (New Zealand)`, `English (Nigeria)`, `English (Philippines)`, `English (Singapore)`, `English (South Africa)`, `English (Tanzania)`, `English (UK)`, `English (United States)`, `Estonian (Estonia)`, `Filipino (Philippines)`, `Finnish (Finland)`, `French (Belgium)`, `French (Canada)`, `French (France)`, `French (Switzerland)`, `Galician`, `Georgian (Georgia)`, `German (Austria)`, `German (Germany)`, `German (Switzerland)`, `Greek (Greece)`, `Gujarati (India)`, `Hebrew (Israel)`, `Hindi (India)`, `Hungarian (Hungary)`, `Icelandic (Iceland)`, `Indonesian (Indonesia)`, `Irish (Ireland)`, `Italian (Italy)`, `Japanese (Japan)`, `Javanese (Latin, Indonesia)`, `Kannada (India)`, `Kazakh (Kazakhstan)`, `Khmer (Cambodia)`, `Korean (Korea)`, `Lao (Laos)`, `Latvian (Latvia)`, `Lithuanian (Lithuania)`, `Macedonian (North Macedonia)`, `Malay (Malaysia)`, `Malayalam (India)`, `Maltese (Malta)`, `Marathi (India)`, `Mongolian (Mongolia)`, `Nepali (Nepal)`, `Norwegian Bokmål (Norway)`, `Pashto (Afghanistan)`, `Persian (Iran)`, `Polish (Poland)`, `Portuguese (Brazil)`, `Portuguese (Portugal)`, `Romanian (Romania)`, `Russian (Russia)`, `Serbian (Latin, Serbia)`, `Sinhala (Sri Lanka)`, `Slovak (Slovakia)`, `Slovenian (Slovenia)`, `Somali (Somalia)`, `Spanish (Argentina)`, `Spanish (Bolivia)`, `Spanish (Chile)`, `Spanish (Colombia)`, `Spanish (Costa Rica)`, `Spanish (Cuba)`, `Spanish (Dominican Republic)`, `Spanish (Ecuador)`, `Spanish (El Salvador)`, `Spanish (Equatorial Guinea)`, `Spanish (Guatemala)`, `Spanish (Honduras)`, `Spanish (Mexico)`, `Spanish (Nicaragua)`, `Spanish (Panama)`, `Spanish (Paraguay)`, `Spanish (Peru)`, `Spanish (Puerto Rico)`, `Spanish (Spain)`, `Spanish (United States)`, `Spanish (Uruguay)`, `Spanish (Venezuela)`, `Sundanese (Indonesia)`, `Swahili (Kenya)`, `Swahili (Tanzania)`, `Swedish (Sweden)`, `Tamil (India)`, `Tamil (Malaysia)`, `Tamil (Singapore)`, `Tamil (Sri Lanka)`, `Telugu (India)`, `Thai (Thailand)`, `Turkish (Türkiye)`, `Ukrainian (Ukraine)`, `Urdu (India)`, `Urdu (Pakistan)`, `Uzbek (Latin, Uzbekistan)`, `Vietnamese (Vietnam)`, `Welsh (United Kingdom)`, `Zulu (South Africa)`, `English - Your Accent`, `English - American Accent` | | `quote_id` | string | no | — | UUID | | `quote_only` | boolean | no | `false` | — | | `speaker_count` | integer | no | — | 1–50 | | `translate_audio_only` | boolean | no | `false` | — | | `video_url` | string | yes | — | https URL; ≤ 4,096 characters | | `wait_timeout_seconds` | integer | no | `0` | 0–60 | | `webhook_url` | string | no | — | https URL; ≤ 4,096 characters | The schema is strict: a field that is not in this table returns `400 unsupported_option`. Field names are the roasOS role names, one name per role across every family. ## Media - `video_url` — the source video | role | items | max size | content types | duration | |---|---|---|---|---| | `video_url` | ≤ 1 | 100 MB | `video/mp4` | 0–480 s | - Refused: `avatar_id`, `elements`, `product_id`, `product_images`, `references`, `reference_images`, `image_url`, `end_image_url`, `scene_id`, `scene_image`, `video_urls`, `audio_urls`, `audio_url`, `voice_id`. A refused role returns `400 unsupported_option`. - Every URL must be an immutable object on `https://cdn.roasos.com/…` that your workspace owns; any other URL is `400 reference_media_not_workspace_owned`. Upload with `POST /v1/uploads` (direct POST of the bytes to `put_url`, or a `source_url` import), then use the returned CDN URL. ## Prompt None. This model takes no prompt. Send `language` as one of the 178 written names the model publishes, such as `Spanish (Mexico)` or `Japanese (Japan)`. An ISO code is refused. Set `translate_audio_only` to true to leave every face untouched and change the voice track only. `enable_dynamic_duration` lets the output run longer than the input so a slower language still sounds natural. roasOS holds it off by default, because this endpoint bills the output. Turn it on when fluency matters more than the exact length, and expect the price to rise with the clip. ## Not exposed - `brand_glossary_id`: not accepted by this public endpoint. - `srt_url`: not accepted by this public endpoint. - `srt_role`: not accepted by this public endpoint. - `enable_caption`: pinned to `false`. ## Result Result kind `video`. Always present: `url`. ```json { "data": { "id": "gen_…", "kind": "video", "model": "heygen-speed", "status": "completed", "result": {"url":"https://cdn.roasos.com/workspaces/ws_01/result"} } } ``` Files live on `https://cdn.roasos.com` and are immutable; a result URL can be a media input to the next call. Poll `GET /v1/jobs/{id}/status` → `{ id, status, updated_at }`, then `GET /v1/jobs/{id}/result` (`409 run_not_completed` until the job is `completed`, `failed` or `canceled`). Statuses: `queued → processing → completed | failed | canceled`. ## Example ```bash # 1. quote — nothing is spent curl -X POST https://api.roasos.com/v1/dub/heygen-speed \ -H "Authorization: Bearer roasos_sk_live_…" \ -H "Idempotency-Key: 0f1c9e2a-heygen-speed-0001" \ -H "Content-Type: application/json" \ -d '{"quote_only":true,"language":"English","video_url":"https://cdn.roasos.com/workspaces/ws_01/uploads/video_url.mp4"}' # → 200 { "data": { "kind": "quote", "quote_id": "q_7Hk…", "credits": 23, "expires_at": "…", "confirmation": { "model": "heygen-speed", "example": "30s_source" } } } # 2. run — the same body and the same Idempotency-Key, quote_id instead of quote_only curl -X POST https://api.roasos.com/v1/dub/heygen-speed \ -H "Authorization: Bearer roasos_sk_live_…" \ -H "Idempotency-Key: 0f1c9e2a-heygen-speed-0001" \ -H "Content-Type: application/json" \ -d '{"quote_id":"q_7Hk…","language":"English","video_url":"https://cdn.roasos.com/workspaces/ws_01/uploads/video_url.mp4"}' # → 201 { "data": { "id": "gen_…", "kind": "video", "model": "heygen-speed", "status": "queued", "credits_reserved": 23, "links": { "status": "/v1/jobs/gen_…/status", "result": "/v1/jobs/gen_…/result" } } } # 3. poll curl https://api.roasos.com/v1/jobs/gen_…/status -H "Authorization: Bearer roasos_sk_live_…" curl https://api.roasos.com/v1/jobs/gen_…/result -H "Authorization: Bearer roasos_sk_live_…" ``` ## Today `POST /v1/dub/heygen-speed` is the only path to this model. There is no deprecated alias: `POST /v1/generations` has no `dub` type, so the old path cannot reach this family at all. The source must be an MP4 your workspace owns, and at most 480 seconds — the maximum HeyGen states. ## See also https://docs.roasos.com/models/dub/heygen-speed · https://api.roasos.com/v1/catalog/dub/heygen-speed · fal-ai/heygen/v2/translate/speed