Skip to content
DashboardGet API Key
Getting Started

Quickstart

Go from zero to your first AI lip sync or video translation request in minutes.

This guide walks you through generating your first AI lip-synced video with the CHAMELAION API, then shows how to translate a video with the same workflow. You’ll need an API key and a video + audio pair to get started.

  • A CHAMELAION account with an API key (get one from the Dashboard)
  • A source video URL (MP4) containing a speaking person
  • A target audio URL (WAV or MP3) to sync the lips to

Log in to your CHAMELAION Dashboard and create a new API key. Copy it somewhere safe; you’ll need it for all API requests.

Send a POST request to /v1/lipsync/generate with your video and audio URLs:

Terminal window
curl -X POST https://api.chamelaion.com/api/v1/lipsync/generate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"reference_id": "my-first-lipsync",
"inputs": [
{
"type": "video",
"url": "https://storage.googleapis.com/chamelaion-test-media/video.mp4"
},
{
"type": "audio",
"url": "https://storage.googleapis.com/chamelaion-test-media/audio.wav"
}
]
}'
import requests
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.chamelaion.com/api"
response = requests.post(
f"{BASE_URL}/v1/lipsync/generate",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
},
json={
"reference_id": "my-first-lipsync",
"inputs": [
{"type": "video", "url": "https://storage.googleapis.com/chamelaion-test-media/video.mp4"},
{"type": "audio", "url": "https://storage.googleapis.com/chamelaion-test-media/audio.wav"},
],
},
)
data = response.json()
print(f"Request ID: {data['request_id']}")
print(f"Status: {data['status']}")
const API_KEY = "YOUR_API_KEY";
const BASE_URL = "https://api.chamelaion.com/api";
const response = await fetch(`${BASE_URL}/v1/lipsync/generate`, {
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
reference_id: "my-first-lipsync",
inputs: [
{
type: "video",
url: "https://storage.googleapis.com/chamelaion-test-media/video.mp4",
},
{
type: "audio",
url: "https://storage.googleapis.com/chamelaion-test-media/audio.wav",
},
],
}),
});
const data = await response.json();
console.log(`Request ID: ${data.request_id}`);
console.log(`Status: ${data.status}`);

You’ll get back a response like:

{
"status": "success",
"request_id": "6f82a2d8-a6d4-4e8a-a0fa-e8b09823a2d8"
}

Lip sync generation is asynchronous. Use the request_id from Step 2 to check on your job:

Terminal window
curl https://api.chamelaion.com/api/v1/lipsync/requests/6f82a2d8-a6d4-4e8a-a0fa-e8b09823a2d8 \
-H "Authorization: Bearer YOUR_API_KEY"

A lip sync request moves from queued to started to finished (or failed). When it is finished, the response includes the output URL:

{
"id": "6f82a2d8-a6d4-4e8a-a0fa-e8b09823a2d8",
"reference_id": "my-first-lipsync",
"status": "finished",
"created_at": "2026-04-07T10:00:00Z",
"started_at": "2026-04-07T10:00:05Z",
"finished_at": "2026-04-07T10:01:30Z",
"output_url": "https://storage.chamelaion.com/output/6f82a2d8.mp4"
}

Once the status is finished, the output_url field contains a link to your lip-synced video. The link is signed and expires after one hour, so download it promptly or retrieve the request again for a fresh link.

Terminal window
curl -o result.mp4 "https://storage.chamelaion.com/output/6f82a2d8.mp4"

Here’s a full end-to-end script that submits a job and waits for the result:

import requests
import time
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.chamelaion.com/api"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
# 1. Submit the lip sync job
response = requests.post(
f"{BASE_URL}/v1/lipsync/generate",
headers={**HEADERS, "Content-Type": "application/json"},
json={
"reference_id": "quickstart-demo",
"inputs": [
{"type": "video", "url": "https://storage.googleapis.com/chamelaion-test-media/video.mp4"},
{"type": "audio", "url": "https://storage.googleapis.com/chamelaion-test-media/audio.wav"},
],
},
)
response.raise_for_status()
request_id = response.json()["request_id"]
print(f"Submitted job: {request_id}")
# 2. Poll until complete
while True:
status_response = requests.get(
f"{BASE_URL}/v1/lipsync/requests/{request_id}",
headers=HEADERS,
)
status_response.raise_for_status()
result = status_response.json()
print(f"Status: {result['status']}")
if result["status"] == "finished":
print(f"Output URL: {result['output_url']}")
break
elif result["status"] == "failed":
print(f"Error: {result.get('error_message', 'Unknown error')}")
break
time.sleep(5)

Video Translate follows the same submit-and-poll flow. Send one video and the languages you want; CHAMELAION handles transcription, translation, voices, and lip sync. Replace the URL with your own video:

Terminal window
curl -X POST https://api.chamelaion.com/api/v1/video-translate/generate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"reference_id": "my-first-translation",
"source_language": "en",
"target_languages": ["de", "fr"],
"inputs": [
{
"type": "video",
"url": "https://storage.googleapis.com/chamelaion-test-media/video.mp4"
}
]
}'

Poll GET /v1/video-translate/requests/{request_id} until the status is completed. The response then contains a video, audio, and SRT URL for each target language.