šŸŽ¬ Avatar Video Generator

Generate AI talking head videos from a face image and audio

šŸ“Š Dashboard
Input
šŸ–¼ļø Image preview
šŸŽµ Audio preview
Progress
Starting...
Result

Authentication

Include the authorization header with your secret token in all API requests:

Authorization: Bearer magicroll-avatar-2026

Async Workflow

Due to GPU cold start times (~5-9 min) and HTTP timeout limits, the API operates asynchronously:

  1. Submit job via POST /api/generate. This returns a job_id instantly.
  2. Poll status via GET /api/jobs/{job_id} until the status is completed or failed.

1. Submit Job Endpoint

POST /api/generate

Submits a talking head generation request. Automatically applies silence-based smart chunking to process long audio in parallel.

Request Body

ParameterTypeDescription
image_urlstring requiredURL of the face image (JPG/PNG)
audio_urlstring requiredURL of the speech audio (MP3/WAV)
promptstringScene description for the video
fpsnumberFrames per second (default: 30)
seedintegerRandom seed for reproducibility (-1 = random)
use_vocals_onlybooleanExtract vocals from audio before generation

Submit Response

{ "job_id": "c138f619e07f4f6ca5ff9341498b8de3", "status": "queued", "poll_url": "/api/jobs/c138f619e07f4f6ca5ff9341498b8de3" }

2. Poll Job Status Endpoint

GET /api/jobs/{job_id}

Polls for the progress and result of a submitted job.

Poll Response (Completed)

{ "job_id": "c138f619e07f4f6ca5ff9341498b8de3", "status": "completed", "elapsed": 128.5, "result": { "video_base64": "AAAAIGZ0eXB...", "format": "mp4", "total_duration": 55.4, "num_chunks": 3, "successful_chunks": 3, "failed_chunks": 0, "chunk_boundaries": [ {"start": 0.0, "end": 20.2, "duration": 20.2, "status": "success"}, {"start": 20.2, "end": 38.5, "duration": 18.3, "status": "success"}, {"start": 38.5, "end": 55.4, "duration": 16.9, "status": "success"} ], "generation_time": 121.2, "stitch_time": 1.8, "total_time": 123.0, "size_kb": 18200 } }

cURL Example (Submit & Poll)

Submit Job:

curl -X POST "https://avatar-video-api-production.up.railway.app/api/generate" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer magicroll-avatar-2026" \ -d '{ "image_url": "https://d4g1s8ya3xoeq.cloudfront.net/4faf801f-1755-450a-a7e7-cde87830cf4b.jpg", "audio_url": "https://magicrollai-videos.s3.ap-south-1.amazonaws.com/magic-agent/sessions/bae09b6c-f61c-43bf-861e-f4b471d30bf6/uploaded_assets/narration.mp3", "prompt": "A distinguished Indian gentleman speaking passionately in Hindi" }'

Poll Status:

curl -X GET "https://avatar-video-api-production.up.railway.app/api/jobs/<job_id>" \ -H "Authorization: Bearer magicroll-avatar-2026"

Python Integration Example

import requests, base64, time API_BASE = "https://avatar-video-api-production.up.railway.app" AUTH_TOKEN = "magicroll-avatar-2026" headers = { "Content-Type": "application/json", "Authorization": f"Bearer {AUTH_TOKEN}" } # 1. Submit Job resp = requests.post(f"{API_BASE}/api/generate", headers=headers, json={ "image_url": "https://d4g1s8ya3xoeq.cloudfront.net/4faf801f-1755-450a-a7e7-cde87830cf4b.jpg", "audio_url": "https://magicrollai-videos.s3.ap-south-1.amazonaws.com/magic-agent/sessions/bae09b6c-f61c-43bf-861e-f4b471d30bf6/uploaded_assets/narration.mp3", "prompt": "A distinguished Indian gentleman speaking passionately in Hindi" }) job_id = resp.json()["job_id"] # 2. Poll Status while True: status_resp = requests.get(f"{API_BASE}/api/jobs/{job_id}", headers=headers) status_data = status_resp.json() if status_data["status"] == "completed": video_bytes = base64.b64decode(status_data["result"]["video_base64"]) with open("output.mp4", "wb") as f: f.write(video_bytes) break elif status_data["status"] == "failed": print("Failed:", status_data["error"]) break time.sleep(5)

Cost & Timing

ScenarioWall TimeCost (approx)
Short (<20s) cold~5 min₹24
Short (<20s) warm~2 min₹10
1 min audio, cold~5 min₹94
1 min audio, warm~2 min₹39

Cold start happens when GPU containers are idle for >10s. All chunks run in parallel — wall time stays ~constant regardless of duration.