Grok Video API Documentation
Grok Video API Documentation
xAI's Grok Imagine provides video generation models. This document describes the API interface for using Grok video models for video generation. All video generation calls use the same /v1/video/generations endpoint, with different parameters depending on the use case.
Supported Models
Currently supported models include:
| Model | Description |
|---|---|
| grok-imagine-video | Grok Imagine video generation model (text-to-video, image-to-video, reference-to-video) |
Overview
The Grok video generation feature provides an asynchronous task processing mechanism:
- Submit Task: Send a text prompt (and optionally one or more images) to create a video task
- Query Status: Query generation progress and status through task ID
- Get Results: Retrieve the generated video file after task completion
The same /v1/video/generations endpoint serves three use cases, selected by whether images is present and by metadata.imageMode: no images performs text-to-video; images with metadata.imageMode omitted or set to "keyframe" (the default) performs image-to-video, using only the first image; images with metadata.imageMode set to "reference" performs reference-to-video.
Task Status Flow
queued → in_progress → completed
↓
failed- queued: Task has been submitted and is waiting to be processed
- in_progress: Task is being processed
- completed: Task completed successfully, video has been generated
- failed: Task failed
Note: Grok video does not support push callbacks. Poll 2. Query Task Status until the task reaches a terminal status.
API List
| Method | Path | Description |
|---|---|---|
| POST | /v1/video/generations | Submit video generation task |
| GET | /v1/video/generations/{task_id} | Query task status |
Usage Examples
1. Text-to-Video
Text-to-video uses prompt and model only — no images. Optional top-level fields include duration and size. aspect_ratio is set via metadata.
Request body:
{
"prompt": "A glowing crystal-powered rocket launching from the red dunes of Mars",
"model": "grok-imagine-video",
"duration": 10,
"size": "720p",
"metadata": {
"aspect_ratio": "16:9"
}
}| Field | Type | Required | Description |
|---|---|---|---|
| prompt | string | Yes | Text prompt for the video |
| model | string | Yes | Model name: grok-imagine-video |
| duration | integer | Yes | Allowed: integers from 1 to 15, inclusive |
| size | string | No | Default 480p. Allowed: 480p, 720p, 1080p |
| metadata | object | No | Extra metadata |
| metadata.aspect_ratio | string | No | Default 16:9 (applied by xAI when omitted). Allowed: 1:1, 16:9, 9:16, 4:3, 3:4, 3:2, 2:3 |
2. Image-to-Video
Provide one or more image URLs (or base64 data URIs) in images with metadata.imageMode omitted or set to "keyframe" (the default). Only the first image in the array is used — it becomes the video's locked first frame; any additional images are ignored.
Request body:
{
"prompt": "The rocket's engines ignite and it lifts off in a cloud of dust",
"model": "grok-imagine-video",
"images": [
"https://example.com/rocket-on-launchpad.jpg"
],
"duration": 8,
"size": "720p",
"metadata": {
"aspect_ratio": "16:9"
}
}| Field | Type | Required | Description |
|---|---|---|---|
| prompt | string | Yes | Text prompt describing how the image should animate |
| model | string | Yes | Model name: grok-imagine-video |
| images | array of string | Yes | One or more image URLs or base64 data URIs; only the first is used, becoming the locked first frame |
| duration | integer | Yes | Allowed: integers from 1 to 15, inclusive |
| size | string | No | Default 480p. Allowed: 480p, 720p, 1080p |
| metadata | object | No | Extra metadata |
| metadata.imageMode | string | No | Default keyframe. Must be keyframe (or omitted) for this mode |
| metadata.aspect_ratio | string | No | Default 16:9. Allowed: 1:1, 16:9, 9:16, 4:3, 3:4, 3:2, 2:3 |
Note: Image-to-video does not support a separate last-frame image. To use multiple images without locking a frame, set
metadata.imageModeto"reference"— see 3. Reference-to-Video.
3. Reference-to-Video
Set metadata.imageMode to "reference" so every URL in images is treated as a reference image that influences the video without locking any frame. Reference images by position in the prompt with tags such as <IMAGE_1>, <IMAGE_2>, … in the same order as images.
Request body:
{
"prompt": "The model from <IMAGE_1> walks the runway wearing the shirt from <IMAGE_2>",
"model": "grok-imagine-video",
"images": [
"https://example.com/model-reference.jpg",
"https://example.com/shirt-reference.jpg"
],
"duration": 10,
"size": "720p",
"metadata": {
"imageMode": "reference",
"aspect_ratio": "16:9"
}
}| Field | Type | Required | Description |
|---|---|---|---|
| prompt | string | Yes | Text prompt; use <IMAGE_1> … <IMAGE_N> to refer to images in order |
| model | string | Yes | Model name: grok-imagine-video |
| images | array of string | Yes | Reference image URLs or base64 data URIs (one or more) |
| duration | integer | Yes | Allowed: integers from 1 to 15, inclusive |
| size | string | No | Default 480p. Allowed: 480p, 720p, 1080p |
| metadata | object | No | Must include imageMode for this mode |
| metadata.imageMode | string | Yes (this mode) | Set to reference |
| metadata.aspect_ratio | string | No | Default 16:9. Allowed: 1:1, 16:9, 9:16, 4:3, 3:4, 3:2, 2:3 |
1. Submit Video Generation Task
Use the JSON bodies in Usage Examples above; adjust fields for your scenario.
Complete Request:
curl -X POST "https://www.unodetech.xyz/v1/video/generations" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer API_KEY" \
-d @request-body.jsonEndpoint:
POST /v1/video/generationsRequest Headers:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Content-Type | string | Yes | application/json |
| Authorization | string | Yes | Bearer API_KEY |
Response Example:
{
"id": "TASK_ID",
"task_id": "TASK_ID",
"object": "video",
"model": "grok-imagine-video",
"status": "queued",
"progress": 0,
"created_at": 1776717808
}Response Field Descriptions:
| Field | Type | Description |
|---|---|---|
| id | string | Task ID for subsequent task status queries |
| task_id | string | Same as id; kept for backward compatibility |
| object | string | Always video |
| model | string | Model used for this task |
| status | string | Always queued immediately after submission |
| progress | integer | Always 0 immediately after submission |
| created_at | integer | Unix timestamp (seconds) when the task was created |
2. Query Task Status
Complete Request:
curl -X GET "https://www.unodetech.xyz/v1/video/generations/TASK_ID" \
-H "Authorization: Bearer API_KEY"Endpoint:
GET /v1/video/generations/{task_id}Request Headers:
| Parameter | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer API_KEY |
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| task_id | string | Yes | Task ID |
Response Example (Processing):
{
"code": "success",
"message": "",
"data": {
"task_id": "<TASK_ID>",
"action": "generate",
"status": "IN_PROGRESS",
"fail_reason": "",
"submit_time": 1776717808,
"start_time": 1776717809,
"finish_time": 0,
"progress": "50%",
"data": {
"status": "pending",
"model": "grok-imagine-video"
}
}
}Response Example (Success):
Note: When the task succeeds, the
data.fail_reasonfield will contain the video download URL instead of an error message. The recommended way to retrieve the video URL is viadata.data.video.url.
{
"code": "success",
"message": "",
"data": {
"task_id": "<TASK_ID>",
"action": "generate",
"status": "SUCCESS",
"fail_reason": "<VIDEO_URL>",
"submit_time": 1776717808,
"start_time": 1776717809,
"finish_time": 1776717962,
"progress": "100%",
"data": {
"status": "done",
"model": "grok-imagine-video",
"video": {
"url": "<VIDEO_URL>",
"duration": 8,
"respect_moderation": true
},
"usage": {
"cost_in_usd_ticks": 2500000000
}
}
}
}Response Field Descriptions:
| Field | Type | Description |
|---|---|---|
| data.status | string | Normalized task status: QUEUED, IN_PROGRESS, SUCCESS, FAILURE |
| data.action | string | textGenerate (text-to-video), generate (image-to-video), or referenceGenerate (reference-to-video) |
| data.fail_reason | string | On success: the video URL (see note above). On failure: the error message |
| data.progress | string | Percentage string, e.g. "50%", "100%" |
| data.data.status | string | Raw xAI status: pending, done, expired, failed |
| data.data.video.url | string | Direct URL to the generated video (present once data.data.status is done) |
| data.data.video.duration | number | Actual duration of the generated video, in seconds |
| data.data.usage.cost_in_usd_ticks | integer | Exact cost xAI charged for this task, in USD ticks (10,000,000,000 ticks = $1) |
| data.data.error.message | string | Error message (present when data.data.status is failed or expired) |
Last updated on
