CyHUB
РусскийGet an API key

HeyGen Lip Sync API

HeyGen LipSync: a new audio track for an existing video, the lips of the person on screen move to it.

Developer: HeyGenModel key in the API: heygen

For AI assistants:Download .mdAll documentation .mdOpen as text

Connect in three steps

  1. Get a keyCreate a key in the dashboard after you confirm your email. One key opens every model.
  2. Check the pricePOST /v1/price shows the cost of a run in advance, without charging you.
  3. Run a task and collect the resultPOST /v1/tasks starts a task, GET /v1/tasks/{id} shows its status and files.

Ready-to-use code

Replace YOUR_API_KEY with your key. The code starts a task and waits for the result. In cURL, repeat the second request with the id from the first response instead of TASK_ID until status becomes succeeded.

cURL
curl -X POST "https://api.cyhub.ai/v1/tasks" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{
  "model": "heygen",
  "settings": {
    "video_url": [
      "https://example.com/speaker.mp4"
    ],
    "audio_url": [
      "https://example.com/new_voice.mp3"
    ]
  }
}'

curl "https://api.cyhub.ai/v1/tasks/TASK_ID" \
  -H "Authorization: Bearer YOUR_API_KEY"
Python
import time

import requests

API = "https://api.cyhub.ai/v1"
HEADERS = {"Authorization": "Bearer YOUR_API_KEY"}

body = {
    "model": "heygen",
    "settings": {
        "video_url": [
            "https://example.com/speaker.mp4",
        ],
        "audio_url": [
            "https://example.com/new_voice.mp3",
        ],
    },
}

response = requests.post(f"{API}/tasks", json=body, headers=HEADERS, timeout=60)
response.raise_for_status()
task = response.json()
while task["status"] in ("queued", "running"):
    time.sleep(5)
    task = requests.get(f"{API}/tasks/{task['id']}", headers=HEADERS, timeout=30).json()
print(task["status"], task["result"])
Node.js
const API = "https://api.cyhub.ai/v1";
const HEADERS = { Authorization: "Bearer YOUR_API_KEY", "Content-Type": "application/json" };

const body = {
  "model": "heygen",
  "settings": {
    "video_url": [
      "https://example.com/speaker.mp4"
    ],
    "audio_url": [
      "https://example.com/new_voice.mp3"
    ]
  }
};

async function main() {
  let response = await fetch(`${API}/tasks`, { method: "POST", headers: HEADERS, body: JSON.stringify(body) });
  if (!response.ok) throw new Error(await response.text());
  let task = await response.json();
  while (task.status === "queued" || task.status === "running") {
    await new Promise((resolve) => setTimeout(resolve, 5000));
    response = await fetch(`${API}/tasks/${task.id}`, { headers: HEADERS });
    task = await response.json();
  }
  console.log(task.status, task.result);
}

main();
Get a key

Price before the run

Prices as of 15.10.2026: from 3 ₽. POST /v1/price shows the exact price of your settings.

ModePrice
HeyGen Lip Sync with a 1 s filefrom 3 ₽

Send the same settings to POST /v1/price: the response shows the price of the run without charging you.

cURL
curl -X POST "https://api.cyhub.ai/v1/price" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{
  "model": "heygen",
  "settings": {
    "video_url": [
      "https://example.com/speaker.mp4"
    ],
    "audio_url": [
      "https://example.com/new_voice.mp3"
    ]
  }
}'
  • amount_minor: the price of the run in minor units (kopecks for rubles)
  • currency: the wallet currency
  • available_minor: how much your balance has for new tasks right now

Price in this mode from 3 ₽, with a 1 s file.

Parameters

Model parameters go inside settings. Omitted optional fields take their default values.

modeOptional

Quality. Speed suits a face that barely moves. Precision handles head turns, movement and a partly covered face better, takes longer and costs more.

Type: StringAllowed values: speedprecisionDefault: "speed"
video_urlRequired

One URL of the source video. The speaker's face must be clearly visible, and the video must have its own audio track with speech.

Type: List (String, uri)Maximum items: 1
audio_urlRequired

One URL of the new audio track: the lips move to it.

Type: List (String, uri)Maximum items: 1
enable_dynamic_durationOptional

Fit the length of the finished video to the audio. On: the audio and video lengths must differ by at most 15%, otherwise HeyGen refuses. Off: the video keeps its own length.

Type: BooleanDefault: true
disable_music_trackOptional

Remove the background music from the source video.

Type: BooleanDefault: false
enable_speech_enhancementOptional

Improve how the speech sounds in the finished video.

Type: BooleanDefault: false
keep_the_same_formatOptional

Keep the resolution and bitrate of the source video.

Type: BooleanDefault: true
enable_watermarkOptional

Put a HeyGen watermark on the finished video.

Type: BooleanDefault: false

Parameters not listed here are not accepted: the response is 422 unknown_setting.

Input

  • The video is a URL of an MP4, MOV or WebM file up to 200 MB, the audio is a URL of an MP3, WAV, M4A, OGG or FLAC file up to 50 MB. The video is at most 10 minutes long, the audio at most 10 minutes.
  • The URLs must be public and start with https://: HeyGen downloads the files itself.
  • The source video needs its own audio track with speech: HeyGen uses it to find who speaks and when. It does not accept a video without sound or with silence.
  • The video goes to HeyGen whole, and the price follows its full length in seconds.
FieldAcceptsFormatsFilesFile size up to
video_urlVideomp4, mov, webm1200 MB
audio_urlAudiomp3, wav, m4a, ogg, flac150 MB
How to send files

Request example

Send this JSON to POST /v1/tasks with your API key. To check the price first, send the same JSON to POST /v1/price.

New voice-over for a video

JSON
{
  "model": "heygen",
  "settings": {
    "video_url": [
      "https://example.com/speaker.mp4"
    ],
    "audio_url": [
      "https://example.com/new_voice.mp3"
    ]
  }
}

Precision mode, the video keeps its length

JSON
{
  "model": "heygen",
  "settings": {
    "mode": "precision",
    "video_url": [
      "https://example.com/interview.mov"
    ],
    "audio_url": [
      "https://example.com/dub.wav"
    ],
    "enable_dynamic_duration": false,
    "disable_music_track": true
  }
}

The price is calculated when the task is accepted, currency RUB.

Complete generation example

Output

  • One video with the new audio track.
  • Processing usually takes a few minutes, occasionally up to half an hour.
KindFormatsHow manyNote
videomp41

A finished task as GET /v1/tasks/{id} returns it (some fields left out). The caption may sit on the task or on a single file and may be empty; the model picks the file name.

JSON
{
  "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "status": "succeeded",
  "finished_at": "2026-10-01T12:03:41+00:00",
  "result": {
    "caption": "Caption of the result: the model and its settings",
    "texts": [],
    "files_expire_at": "2026-10-08T12:03:41+00:00",
    "files_expired": false,
    "artifacts": [
      {
        "index": 0,
        "kind": "video",
        "filename": "video.mp4",
        "size": 12582912,
        "caption": "",
        "download_path": "/v1/tasks/7c9e6679-7425-40de-944b-e07fc1f90ae7/artifacts/0"
      }
    ]
  }
}
How to read the result and download files

See also

Try HeyGen Lip Sync through the API

One key opens every CyHUB model. Payment in rubles, and you see the price before the run.

Get an API key