Media API: images, video, speech, music
The uttapen media API: image generation, async video, text to speech and music, automatic model picking, signed file links and 30-day retention.
Updated: 4 Oct 2026
The same sk-up-… key and the same base_url that serve text also make images, video, speech and music. There are four routes:
| Task | Route | Answer |
|---|---|---|
| Images | POST /v1/images/generations | synchronous; a file link or b64_json |
| Video | POST /v1/videos | asynchronous; a job id, then poll GET /v1/videos/{id} |
| Text to speech | POST /v1/audio/speech | the audio file itself, as in OpenAI |
| Music | POST /v1/audio/music | synchronous; a file link |
Every model and its toman price is on the models page. If you would rather not write code, the studio does all of this in the browser.
Automatic model picking
Leave model empty, or send one of these ids, and the best-suited model is chosen for the request:
| Id | For |
|---|---|
uttapen/auto-image | images: photoreal, product shots, anime, posters with text, photo edits |
uttapen/auto-video | video: text to video, animating a photo, a cheap draft |
uttapen/auto-music | music: a full track or a short clip |
uttapen/auto-speech | speech: Persian or English text |
A cheap language model reads the request and picks from our routing table. That decision is billed on its own (usually a fraction of a toman) and reported as uttapen.classifier_cost_toman; the reason is in uttapen.auto. If the classifier fails for any reason, fixed rules decide instead — a request with an attached image goes to an editing model, for example — and the failed classification costs nothing. Name a model yourself and that model always runs.
Billing
- Before a run an amount is held: video at duration × the per-second price of the chosen resolution and sound, images at the per-image price, speech by character count, music at the per-track price.
- After the run only the real cost the model maker reported is charged and the rest of the hold returns. Speech is the exception: its makers report no cost, so it is charged at the model's published price × characters.
- Failed runs are free. An error, a content-policy refusal, a video that misses its deadline or a file that never arrives all release the hold in full.
- Synchronous answers carry
X-Uttapen-Cost-TomanandX-Uttapen-Balance-Toman; for video,cost_tomanon the job fills in once it completes.
Files and retention
Outputs are stored on our own servers in Iran. Every url in an answer is a signed link on https://api.uttapen.ir/v1/files/… that opens without a key for 24 hours; fetch the job again for a fresh one:
curl https://api.uttapen.ir/v1/uttapen/media/<id> -H "Authorization: Bearer sk-up-..."
Files are kept for 30 days and then deleted, so download what you need. Your recent jobs: GET /v1/uttapen/media?kind=video&limit=20. The text of API requests is never stored.
Content policy
Sexual content, anything harmful involving children, graphic violence, and images or voices made to look like real people are not generated. Such a request is refused before anything is charged, with 400 content_policy_violation. If the model maker itself refuses a request, you get the same code and nothing is charged.
Errors and limits
| status | code | meaning |
|---|---|---|
| 400 | content_policy_violation | forbidden content |
| 400 | invalid_request | a bad parameter; param names it (for example a duration the model does not offer) |
| 400 | model_not_available | this model's price cannot be computed right now |
| 402 | insufficient_balance | not enough balance for the hold |
| 429 | too_many_active_jobs | more than 3 runs at once |
| 429 | rate_limit_exceeded | the per-minute cap |
| 503 | server_busy | capacity is briefly full; honour Retry-After |
Limits: 4 images per request, a 4,000-character prompt (5,000 for speech), video up to 20 seconds, and at most 4 reference images of up to 10 MB each (an https URL or data:image/png|jpeg|webp;base64). The general codes are on Errors.
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 →