Skip to content
Radient LogoRadient Documentation

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:

bash
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:

json
{"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:

bash
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
json
{"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:

json
{"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.

FieldTypeNotes
modelstringRequired for video: a "type": "video" id from the models endpoint. Unknown ids are rejected with 400 media_rejected.
promptstringWhat to generate.
durationintegerSeconds, 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.
resolutionstringThe model's declared tiers (e.g. 480p, 720p, 1080p, 4k). Lower tiers are cheaper — set it explicitly.
audiobooleanWhere the model supports generated audio, it may default to on at a higher per-second rate. Set it off for silent, cheaper output.
seedintegerReproducibility, where supported.
start_image_urlstringImage-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:

json
{
  "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/cancel works 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 duration costs 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:

StatusCodeMeaning
400media_rejectedCould 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).
404media_not_foundUnknown request id, or one that belongs to another account.
409media_already_completedCancel of a completed request.
413payload_too_largeSubmission body over 1 MiB.
429media_rate_limitedThe generation service is busy; retry shortly.
503media_unavailableThe generation service is temporarily unavailable; retry later.

Real bodies:

json
{"code":"media_rejected","error":"This generation request could not be priced or accepted."}
json
{"code":"media_unavailable","error":"Media generation is temporarily unavailable."}
json
{"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_position tells you whether the request is still queued.

For the full endpoint list, see the API Reference.