Video API Usage Guide
Generate a short video from a text prompt, or animate an existing image (image-to-video). Video generation uses the same media API as image generation — submit, poll, fetch — with video models and per-second billing.
Submit: POST https://api.radienthq.com/v1/tools/media/generate. Poll: GET /v1/tools/media/status?request_id=…. Fetch: GET /v1/tools/media/result?request_id=…. There is no default video model — pass a video model id explicitly.
#Quickstart
List the models, pick the id of a "type": "video" entry, then submit. The numbers below come from the budget model at its cheapest settings, 480p for 2 seconds:
curl https://api.radienthq.com/v1/tools/media/generate \
-H "Authorization: Bearer $RADIENT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "YOUR_VIDEO_MODEL_ID", "prompt": "A red apple rotating slowly on a white table", "resolution": "480p", "duration": 2}'
The response is the queue handle and the quoted price:
{"request_id":"01a1218f-a31d-79a1-8fbe-063444e46450","model":"…","provider":"…","status":"IN_QUEUE","queue_position":0,"cost_usd":0.136,"units":2,"unit":"second"}
Poll until "settled": true — a 2-second video takes roughly 40–90 seconds in practice, so poll every few seconds or back off:
request_id=01a1218f-a31d-79a1-8fbe-063444e46450
while ! curl -sS "https://api.radienthq.com/v1/tools/media/status?request_id=$request_id" \
-H "Authorization: Bearer $RADIENT_API_KEY" | grep -q '"settled":true'; do sleep 5; done
{"request_id":"01a1218f-a31d-79a1-8fbe-063444e46450","model":"…","status":"COMPLETED","metrics":{"inference_time":82.34800004959106},"settled":true,"cost_usd":0.136,"units":2,"unit":"second"}
Fetch the result and download the video:
{"request_id":"01a1218f-a31d-79a1-8fbe-063444e46450","model":"…","status":"COMPLETED","output":{"actual_prompt":null,"duration":2.02,"seed":1369620805,"video":{"content_type":"video/mp4","duration":2.02,"file_name":"7KeMAzbttCUagZ1AQYm6-_c9SMigat.mp4","file_size":695889,"fps":30.0,"height":640,"num_frames":60,"url":"https://…/7KeMAzbttCUagZ1AQYm6-_c9SMigat.mp4","width":640}}}
Example bodies on this page come from live calls; … marks a value trimmed here. Download the file from output.video.url and store the bytes you need — treat the link as temporary.
#Choosing a video model
GET https://api.radienthq.com/v1/tools/media/models (public) lists every model with id, display_name, type ("video" for videos), unit (second), unit_price_usd and a pricing_note. Video entries carry "default": false — there is no default video model, so a submission without model (or with an image model's id) will not produce a video.
Prices are per second of output video and differ by model and by the settings that affect cost (resolution tier, whether audio is generated). The cheapest plans start below $0.07/s at the lowest resolution; the high-end model starts at $0.20/s and doubles with audio. Read unit_price_usd and pricing_note from the models endpoint before submitting.
Watch the defaults. A submission that omits duration and resolution gets the model's defaults, which for one budget model are 1080p for 5 seconds (about $1.40) and for the high-end model are 8 seconds with audio (about $3.20). Always set duration and resolution explicitly when you are experimenting.
#Request parameters
The body is the selected model's own parameter object plus the reserved model key. The parameters below are the ones you will use across models; a model ignores or rejects fields it does not define.
| Field | Type | Notes |
|---|---|---|
model | string | Required for video: a "type": "video" id from the models endpoint. Unknown ids are rejected with 400 media_rejected. |
prompt | string | What to generate. |
duration | integer | Seconds, within the model's declared range (some models declare fixed sets such as 4/6/8 s). Where a model declares nothing, the platform prices up to 60 s. |
resolution | string | The model's declared tiers (e.g. 480p, 720p, 1080p, 4k). Lower tiers are cheaper — set it explicitly. |
audio | boolean | Where the model supports generated audio, it may default to on at a higher per-second rate. Set it off for silent, cheaper output. |
seed | integer | Reproducibility, where supported. |
start_image_url | string | Image-to-video: the URL of the first frame (see below). |
#Image-to-video
Pass a start_image_url to animate an image, using an image-to-video entry (its id and display name in GET /v1/tools/media/models say so), typically a still you just generated via image generation or any publicly reachable image URL:
{
"model": "YOUR_VIDEO_MODEL_ID",
"prompt": "The apple slowly rotates",
"start_image_url": "https://…/QWj1y0ZmH04O4QYZZEgHF_JngXHa9M.jpg",
"resolution": "480p",
"duration": 2
}
The platform prices this identically to text-to-video — the input image is not charged. Editing a still image (rather than animating it) is an image-model task; see Editing an image.
#Job model, settlement and cancellation
The lifecycle is the same as for images — submit returns a quote (cost_usd / units / unit) and a request_id; poll status until "settled": true; fetch result for output. See Job and progress model for the field-by-field details.
Video-specific notes:
- Nothing is charged at submit. The charge lands when the platform observes completion and fetches a valid result — so poll your requests. A generation that fails settles at
cost_usd: 0. A cancelled request that nevertheless completes is charged when its result is fetched. POST /v1/tools/media/cancelworks the same way as for images — idempotent, best-effort, 409 on an already completed request — and there is no restart: submit a new request to retry.- Videos are billed per second of output, so a longer
durationcosts proportionally more; the resulting file's actual length (e.g. 2.02 s for a 2 s request) does not change the settled figure — the quote does not change once issued.
#Errors
Errors use the same codes and bodies as image generation; the common ones:
| Status | Code | Meaning |
|---|---|---|
| 400 | media_rejected | Could not be priced or accepted — unknown model, a resolution outside the model's set, a duration the model does not accept. Nothing ran, nothing was charged. |
| 401 / 402 | – | Missing or invalid credentials; insufficient credits (Radient Pass). |
| 404 | media_not_found | Unknown request id, or one that belongs to another account. |
| 409 | media_already_completed | Cancel of a completed request. |
| 413 | payload_too_large | Submission body over 1 MiB. |
| 429 | media_rate_limited | The generation service is busy; retry shortly. |
| 503 | media_unavailable | The generation service is temporarily unavailable; retry later. |
Real bodies:
{"code":"media_rejected","error":"This generation request could not be priced or accepted."}
{"code":"media_unavailable","error":"Media generation is temporarily unavailable."}
{"error":"insufficient credits"}
#Limits
- Submission body: 1 MiB.
- Duration: within the model's declared set; up to 60 seconds where the model declares no bound.
- Resolution: the model's declared tiers only.
- Rendering time: tens of seconds to a few minutes — budget your polling accordingly. The status response's
queue_positiontells you whether the request is still queued.
For the full endpoint list, see the API Reference.