Videos
Video takes time, so it is a job: submit it, poll until it completes, download the file. The shapes follow OpenAI’s video API. You are billed per second of finished video, at the rate for the resolution you chose, and only when the job completes.
Submit#
/v1/videoscurl https://api.ahurasense.com/v1/videos \
-H "Authorization: Bearer $AHURA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "x-ai/grok-imagine-video-1.5",
"prompt": "A paper boat drifting on a calm pond at sunrise, soft light.",
"duration_seconds": 5,
"resolution": "720p",
"ratio": "16:9"
}'modelstringrequired- A catalog id whose modality is
video. See Models. promptstringrequired- What to generate, up to 4,000 characters.
duration_secondsintegerrequired- Whole seconds, within the model’s range in
capabilities.duration_seconds. This is what you pay for. resolutionstringrequired- One of the model’s
capabilities.resolutions, such as480p,720p,1080por4K. Decides the per-second rate. ratiostringoptional- Aspect ratio, such as
16:9or9:16. Unsupported values are refused withvideo_ratio_invalid. modestringoptionaldefault text_to_video- Generation mode. Text to video is the default; other modes depend on the model.
The response is 202 Accepted with the job:
{
"id": "video_3be098cc-0311-42cd-aec6-849c107d0c76",
"object": "video",
"status": "in_progress",
"model": "x-ai/grok-imagine-video-1.5",
"mode": "text_to_video",
"prompt": "A paper boat drifting on a calm pond at sunrise, soft light.",
"duration_seconds": 5,
"ratio": "16:9",
"resolution": "720p",
"created_at": "2026-09-18T15:09:58.184Z",
"completed_at": null,
"error": null,
"content_url": null,
"content_expires_at": null
}Poll#
/v1/videos/{id}Returns the same job object, refreshed. Poll every few seconds; a short clip finishes in under a minute, a 30-second one can take several. Terminal statuses are completed, failed and cancelled. On completion content_url is set and content_expires_at says how long the file is kept.
| Status | Meaning |
|---|---|
queued | Accepted, not started. Usually gone within a second. |
in_progress | Generating. Keep polling. |
completed | Done. Download from content_url. Billed now. |
failed | error carries a code and message. Not billed. |
cancelled | Stopped before completion. Not billed. |
You do not have to poll for billing to be correct. The gateway settles every open job on its own each minute, so a job you submit and walk away from is still billed when it completes, and still closed if it is lost.
Download#
/v1/videos/{id}/contentStreams the MP4 with Content-Type: video/mp4. Before completion it answers 409 video_not_ready; after the retention period it answers 410 video_content_expired. Files are kept for seven days after completion, so copy the file to your own storage if you need it longer.
List#
/v1/videosYour organization’s twenty most recent jobs, newest first, in the same shape.
Billing#
- Cost is
duration_secondstimes the per-second rate for the resolution, from the model’spricesblock inGET /v1/models. - Charged once, when the job completes. Failed and cancelled jobs cost nothing.
- Video is available on platform billing; keys on BYOK billing are refused with
byok_unsupported.
Errors#
| Status | Code | Meaning |
|---|---|---|
| 400 | video_duration_invalid | Outside the model’s range, or not a whole number. |
| 400 | video_resolution_unsupported | Not one the model offers; the message lists them. |
| 400 | video_ratio_invalid | The aspect ratio is not supported. |
| 400 | video_mode_unsupported | The model does not support that mode. |
| 404 | video_not_found | No such job in your organization. |
| 409 | video_not_ready | Content requested before completion. |
| 410 | video_content_expired | The file is past its seven-day retention. |
| 503 | media_unavailable | The video service is down or overloaded. Retry after a few seconds. |
Something missing or wrong on this page? Tell us, and quote the page title.