Video generation
Unified asynchronous API for text-to-video and image-to-video across providers.
/v1/video/generations
Video generation is asynchronous: you submit a task, receive a task ID, and poll until the video is ready. This unified endpoint uses one request format for every video provider connected to RuToken — for example Kling (kling-v1), Jimeng, Vidu (viduq1), Hailuo, Doubao Seedance, Alibaba Wan, Google Veo (veo-3.0-generate-001) and Sora (sora-2). The model field decides which provider handles the task.
Provider-specific alternatives: OpenAI Videos API, Kling native format, Jimeng native format.
Authentication
Send your key in the Authorization: Bearer sk-xxxx header.
Request body
Content type: application/json (or multipart/form-data with the same field names).
| Parameter | Type | Required | Description |
|---|---|---|---|
model |
string | Yes | Video model ID, e.g. kling-v1, viduq1, sora-2. |
prompt |
string | Yes | Text description of the video. |
image |
string | No | Reference image as a URL or Base64 string. Turns the task into image-to-video. |
images |
string[] | No | Several reference images (for example first and last frame), if the model supports it. |
duration |
integer | No | Video length in seconds. Allowed values depend on the model (Kling: 5 or 10). |
seconds |
string | No | Alias of duration used by Sora-style models, e.g. "4". |
size |
string | No | Resolution such as 1280x720 or 720x1280. Some providers convert it to an aspect ratio. |
aspect_ratio |
string | No | Aspect ratio such as 16:9, 9:16, 1:1. |
ratio |
string | No | Aspect ratio for Doubao / Seedance models. |
mode |
string | No | Generation mode, e.g. Kling std (default) or pro. |
metadata |
object | No | Provider-specific parameters passed through to the upstream request, e.g. negative_prompt, cfg_scale, camera_control for Kling. Keys in metadata override the mapped top-level values. |
Request example
curl https://rutoken.ai/v1/video/generations \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d '{
"model": "kling-v1",
"prompt": "An astronaut stands up and walks across the surface of the moon",
"duration": 5,
"aspect_ratio": "16:9",
"metadata": { "negative_prompt": "blurry, low quality" }
}'
import time
import requests
BASE = "https://rutoken.ai"
HEADERS = {"Authorization": "Bearer sk-xxxx"}
# 1. Submit the task
task = requests.post(f"{BASE}/v1/video/generations", headers=HEADERS, json={
"model": "kling-v1",
"prompt": "An astronaut stands up and walks across the surface of the moon",
"duration": 5,
}).json()
task_id = task["id"]
# 2. Poll until the task finishes
while True:
data = requests.get(f"{BASE}/v1/video/generations/{task_id}", headers=HEADERS).json()["data"]
if data["status"] in ("SUCCESS", "FAILURE"):
break
time.sleep(10)
print(data["status"], data.get("result_url") or data.get("fail_reason"))
Response
The submit call returns a video task object:
{
"id": "task_6Fh2kVb0mQ9xYzA1pL3sT8uWcR4nE7dJ",
"task_id": "task_6Fh2kVb0mQ9xYzA1pL3sT8uWcR4nE7dJ",
"object": "video",
"model": "kling-v1",
"status": "queued",
"progress": 0,
"created_at": 1760000000
}
| Field | Type | Description |
|---|---|---|
id |
string | Task ID (task_…). Use it to query the task. |
task_id |
string | Same as id; kept for older clients. |
status |
string | Initial status, normally queued. |
model |
string | Model that handles the task. |
Query a task
GET /v1/video/generations/{task_id}
| Parameter | In | Type | Description |
|---|---|---|---|
task_id |
path | string | The id returned when the task was created. |
curl https://rutoken.ai/v1/video/generations/task_6Fh2kVb0mQ9xYzA1pL3sT8uWcR4nE7dJ \
-H "Authorization: Bearer $API_KEY"
{
"code": "success",
"message": "",
"data": {
"task_id": "task_6Fh2kVb0mQ9xYzA1pL3sT8uWcR4nE7dJ",
"platform": "50",
"action": "textGenerate",
"status": "SUCCESS",
"progress": "100%",
"fail_reason": "",
"result_url": "https://rutoken.ai/v1/videos/task_6Fh2kVb0mQ9xYzA1pL3sT8uWcR4nE7dJ/content",
"submit_time": 1760000000,
"start_time": 1760000012,
"finish_time": 1760000150,
"quota": 250000,
"data": { }
}
}
| Field | Type | Description |
|---|---|---|
data.status |
string | Task status, see below. |
data.progress |
string | Progress as a percentage string, e.g. 30%. |
data.result_url |
string | Video URL when the task has succeeded. |
data.fail_reason |
string | Error message when the task has failed. |
data.data |
object | Raw provider response, for advanced use. |
data.submit_time / start_time / finish_time |
integer | Unix timestamps. |
You can only query tasks created with your own account.
Task lifecycle
| Status | Meaning |
|---|---|
NOT_START |
Created, not yet sent to the provider. |
SUBMITTED |
Accepted by the provider. |
QUEUED |
Waiting in the provider's queue. |
IN_PROGRESS |
Being generated. |
SUCCESS |
Finished. result_url contains the video. |
FAILURE |
Failed. fail_reason explains why. |
UNKNOWN |
The provider returned a status the gateway does not recognize. |
Poll every 5–15 seconds; most videos take from 30 seconds to several minutes. The gateway also refreshes task status in the background, so polling does not cost extra.
If a task fails, the quota charged for it is refunded automatically. Provider-hosted video URLs may expire — download the file once the task succeeds. The https://rutoken.ai/v1/videos/{task_id}/content URL streams the video through the gateway, see OpenAI Videos API.
See also: Errors.