Video
Video takes longer than an HTTP timeout allows, so it works as create → poll → download.
1. Create a job
Section titled “1. Create a job”import requests
job = requests.post( "https://api.mixen.ai/v1/videos", headers={"Authorization": f"Bearer {API_KEY}"}, json={ "model": "seedance-2.5", "prompt": "A drone circles a lighthouse on a rocky shore at sunrise", "seconds": "5", "size": "1280x720", },).json()print(job["id"], job["status"])const res = await fetch('https://api.mixen.ai/v1/videos', { method: 'POST', headers: { Authorization: `Bearer ${process.env.MIXEN_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ model: 'seedance-2.5', prompt: 'A drone circles a lighthouse on a rocky shore at sunrise', seconds: '5', size: '1280x720', }),})const job = await res.json()console.log(job.id, job.status)curl https://api.mixen.ai/v1/videos \ -H "Authorization: Bearer $MIXEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "seedance-2.5", "prompt": "A drone circles a lighthouse on a rocky shore at sunrise", "seconds": "5", "size": "1280x720" }'The response comes back immediately with queued:
{"id": "video_...", "object": "video", "model": "bytedance/seedance-2.5", "status": "queued"}| Field | Description |
|---|---|
model |
A catalog model or the sora-2 / sora-2-pro aliases; defaults to sora-2 |
prompt |
Scene description, required |
seconds |
Duration; accepted values are the seconds field in the catalog |
size |
WxH; accepted values are the sizes field in the catalog |
input_reference |
Image-to-video: {"image_url": "data:image/png;base64,..."} |
input_references |
Reference-to-video: 2 to 9 images, on models that support it |
input_reference accepts data: URLs only — external links will not work, so base64-encode the image.
2. Poll the job
Section titled “2. Poll the job”curl https://api.mixen.ai/v1/videos/video_... \ -H "Authorization: Bearer $MIXEN_API_KEY"Statuses run queued → in_progress → completed or failed. Poll every 5–10 seconds; faster gains nothing and spends your rate limit.
A job stuck for more than 20 minutes is marked failed automatically and is not charged.
3. Download the result
Section titled “3. Download the result”curl -L https://api.mixen.ai/v1/videos/video_.../content \ -H "Authorization: Bearer $MIXEN_API_KEY" \ -o result.mp4The endpoint returns a finished mp4.
Image-to-video
Section titled “Image-to-video”{ "model": "happyhorse-1.1", "prompt": "The camera slowly pushes in, wind moves the hair", "input_reference": {"image_url": "data:image/jpeg;base64,/9j/4AAQ..."}}Worth knowing: models in this class inherit the aspect ratio of the source image and ignore an explicit size. If you want vertical video, feed a vertical reference.
Upscaling
Section titled “Upscaling”POST /v1/videos/upscale takes multipart/form-data with a finished file:
curl https://api.mixen.ai/v1/videos/upscale \ -H "Authorization: Bearer $MIXEN_API_KEY" \ -F video=@clip.mp4 \ -F upscale_factor=2 \ -F creativity=0upscale_factor defaults to 1.5 and creativity to 0: at zero the upscaler preserves the frame as-is, higher values invent detail and can alter faces.
Upscaling is an async job too — the response is status: queued, then poll and download through the same /videos/{id} endpoints.
Video is billed per second: per_second_rub from the catalog times the actual duration. Resolution moves the price, so 720p costs more than 480p on the same model. Check the catalog before putting generation in a loop.