Video generation API (videos)
Async video with POST /v1/videos, polling GET /v1/videos/{id} and the content download: duration, resolution, sound, first frame and per-second pricing.
Updated: 4 Oct 2026
A video takes from tens of seconds to a few minutes, so the route is asynchronous: submit, get a job id, poll the status, then download the file once it completes.
1. Submit
curl https://api.uttapen.ir/v1/videos \
-H "Authorization: Bearer sk-up-..." -H "Content-Type: application/json" \
-d '{
"model": "uttapen/auto-video",
"prompt": "ocean waves at sunset, slow aerial shot",
"seconds": 8,
"resolution": "720p",
"aspect_ratio": "16:9"
}'
The answer is the job itself, with status queued or in_progress:
{ "id": "01a1043f-…", "object": "video", "status": "in_progress", "progress": 0, "model": "google/veo-3.1-fast",
"params": { "seconds": 8, "resolution": "720p", "aspect_ratio": "16:9", "generate_audio": true },
"hold_toman": "266915.000000", "cost_toman": null, "outputs": [], "error": null }
2. Poll
import time, httpx
H = {"Authorization": "Bearer sk-up-..."}
job_id = "01a1043f-..."
while True:
job = httpx.get(f"https://api.uttapen.ir/v1/videos/{job_id}", headers=H).json()
if job["status"] in ("completed", "failed", "expired"):
break
time.sleep(5) # every 5–10 seconds is plenty
print(job["status"], job["cost_toman"], job["error"])
status | Meaning |
|---|---|
queued / in_progress | running; progress is an estimate from 0 to 95 |
completed | ready; outputs[].url and cost_toman are filled |
failed | it failed; error.code and error.message explain; nothing was charged |
expired | it did not finish within the deadline (60 minutes); the hold was released |
3. Download
outputs[0].url is a signed link valid for 24 hours that opens without a key. Or fetch it directly with your key:
curl -L -o video.mp4 https://api.uttapen.ir/v1/videos/<id>/content -H "Authorization: Bearer sk-up-..."
Before the job completes this route answers 409 not_ready. Files are kept for 30 days.
Fields
| Field | Meaning |
|---|---|
model | a model id or uttapen/auto-video |
prompt | up to 4,000 characters |
seconds (or duration) | must be one of the model's durations (listed on its page), at most 20; empty means 5 seconds, or the shortest |
resolution | e.g. 480p, 720p, 1080p; empty means 720p when the model has it |
aspect_ratio | e.g. 16:9, 9:16, 1:1 |
generate_audio | for models that make sound; on by default |
image | the first frame (an https URL or data:image/…;base64) to animate a photo |
last_image | the last frame, for models that support it |
seed | a fixed number for repeatable output |
An invalid value is refused before any hold, with 400 invalid_request, param naming the field, and the allowed values.
Price
Video is priced per second and depends on resolution and sound; each model's table is under video models. The hold is duration × that option's per-second price; on completion the real reported cost is charged. A run that fails, expires or whose file cannot be downloaded returns the whole hold. More in the media overview.
Sign up with a phone number, top up your wallet from 100,000 toman and create a key. Free models work without a top-up — up to 50 requests a day. Create an API key →