Skip to main content

Video Generation

Video generation lets applications submit prompt-to-video tasks through AISIX while keeping caller authentication, model aliases, upstream credentials, rate limits, and content guardrails in one gateway path.

AISIX exposes an OpenAI-compatible video surface with three routes that mirror the provider-side asynchronous workflow: submit a task, poll its status, and download the result. The gateway holds no task state — the returned video ID encodes everything AISIX needs to route later status and download calls to the right provider.

In this guide, you will generate a video through AISIX using an Alibaba Model Studio video model and follow the task to a downloadable result.

Prerequisites

Before starting, prepare the following:

  • A running AISIX gateway that can serve proxy requests.
  • A caller API key that can access the video model alias.
  • A model alias whose configured provider is one of the supported video providers (see Endpoint Behavior). Every provider except OpenAI needs a provider key whose api_base reaches the provider's API — there is no built-in default base URL for them. An OpenAI model falls back to the standard OpenAI base URL when api_base is unset. The examples below use an Alibaba Model Studio model.

The examples use a model alias configured like the following. The upstream model name is a text-to-video model from the provider's catalog:

{
"display_name": "wan-video-prod",
"model_name": "wan2.7-t2v",
"provider_key_id": "YOUR_PROVIDER_KEY_ID"
}

Create a Video Generation Task

Submit the task with the model alias, a prompt, and optionally a duration in seconds:

curl -sS -X POST "http://127.0.0.1:3000/v1/videos" \
-H "Authorization: Bearer YOUR_CALLER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "wan-video-prod",
"prompt": "A miniature city built from cardboard comes alive at night.",
"seconds": 5
}'

AISIX resolves the alias, runs input guardrails on the prompt, reserves rate-limit capacity, and submits the task to the provider asynchronously. The response is a video job object:

{
"id": "bW9kZWwtaWQtMTpkMkZ1TFhacFpHVnZMWEJ5YjJROnRhc2stMDE",
"object": "video",
"model": "wan-video-prod",
"status": "queued",
"progress": 0,
"created_at": 1753257600,
"seconds": "5"
}

The id value is an opaque gateway-issued video ID. Store it — the status and download routes take it as the path parameter.

Request fields:

FieldRequiredMeaning
modelYesThe AISIX model alias.
promptYesThe text prompt for the video.
secondsNoVideo duration in seconds, as an integer or a numeric string. Forwarded as the provider's duration parameter (duration for Alibaba, Zhipu, Volcengine Ark, and Runway). For OpenAI it is forwarded as seconds rendered as a string, and Sora accepts only 4, 8, or 12.
sizeNoPixel dimensions as WIDTHxHEIGHT, for example 1280x720. Forwarded as the pixel-size parameter for providers whose models accept explicit dimensions (early Alibaba Wan families, Zhipu CogVideoX, OpenAI Sora), and as the equivalent WIDTH:HEIGHT resolution string for Runway. Volcengine Ark models, and Alibaba's wan2.7 family, express output dimensions as resolution and ratio quality tiers instead; for Ark the value is validated but not forwarded and the provider default applies. Consult the provider's model documentation before setting it — each provider validates the value against its own per-model list.

Unset optional fields are omitted from the upstream request entirely.

Poll the Task Status

Poll the task with the video ID until the status reaches a terminal value:

curl -sS "http://127.0.0.1:3000/v1/videos/YOUR_VIDEO_ID" \
-H "Authorization: Bearer YOUR_CALLER_API_KEY"

A finished task reports completed and, when the provider states it, the actual video duration:

{
"id": "bW9kZWwtaWQtMTpkMkZ1TFhacFpHVnZMWEJ5YjJROnRhc2stMDE",
"object": "video",
"model": "wan-video-prod",
"status": "completed",
"progress": 100,
"created_at": 0,
"seconds": "5"
}

The status field is a four-value enum. AISIX maps each provider's task states onto it. Some providers report no distinct queued state, so a submission may start directly at in_progress:

StatusMeaning
queuedThe provider accepted the task and has not started it.
in_progressThe provider is generating the video.
completedThe video is ready to download.
failedGeneration failed, was canceled, or the provider no longer knows the task (for example, an expired task). The response carries an error object with the provider's code and message when available.

progress reports a real completion percentage for providers that expose one (OpenAI Sora). For providers that do not, it reports 0 until the task completes and 100 afterward. Because the gateway stores no task state, created_at is populated on the submit response only; poll responses report 0.

Download the Video

When the status is completed, request the content route. Use curl -L so the command works for every provider — AISIX either redirects to the provider's download URL or streams the video itself, depending on how the provider delivers finished files:

curl -sS -L -o video.mp4 \
"http://127.0.0.1:3000/v1/videos/YOUR_VIDEO_ID/content" \
-H "Authorization: Bearer YOUR_CALLER_API_KEY"

Both paths save the same MP4. The difference matters when you script around the response:

DeliveryProvidersWhat the content route returns
RedirectAlibaba, Zhipu, Volcengine Ark, Runway302 with a Location header pointing at the provider's signed download URL. The transfer goes directly from the provider's storage to the client and does not pass through the gateway. AISIX only redirects to absolute http or https URLs.
Gateway streamOpenAI200 with the MP4 bytes, the provider's Content-Type (normally video/mp4), and a Content-Disposition attachment header. The provider requires its own credential to download the file, so AISIX fetches it with the configured provider key and streams the bytes through. The provider credential is never exposed to the caller.

Streamed responses pass through the gateway chunk by chunk rather than being held in memory, so a large file does not grow the gateway's memory use. Per-chunk reads are bounded by the model's stream timeout: if a slow upstream stalls, the transfer is cut mid-body. When the provider declares a Content-Length, the gateway relays it, so an interrupted transfer surfaces to the client as a short read against that length — retry the content request.

To inspect which path a provider uses, ask curl for the status without following redirects:

curl -sS -o /dev/null -w "%{http_code} %{redirect_url}\n" \
"http://127.0.0.1:3000/v1/videos/YOUR_VIDEO_ID/content" \
-H "Authorization: Bearer YOUR_CALLER_API_KEY"

A redirect provider prints the redirect status and the provider-hosted URL:

302 https://provider-cdn.example.com/videos/task-01/out.mp4

A gateway-stream provider prints 200 with an empty redirect URL. On that path the probe transfers the whole file to /dev/null, so run it against a small task:

200

If the task is not finished, the content route returns 400 with a message telling the caller to keep polling. If the task failed, it returns 400 with the provider's failure detail. An error from the provider's download endpoint is always returned as a JSON error envelope, never as a truncated video body.

Rate Limits and Guardrails

Before a task reaches the provider, the submit route reserves the caller API key layers and the model's limits, as it does for other modeled routes. Model limits include the inline rate_limit and any model-scope rate limit policies. See API Key and Model Rate Limits and Rate Limit Policies.

The status and content routes reserve only the caller API key layers. Task polling is deliberately exempt from model-level limits: a client that submits a task and then hits the model's submission cap can still poll that task to completion. For gateway-stream providers this also means the video bytes transit the gateway without counting against the model's limits — size the gateway's egress accordingly.

Input guardrails resolved for the request — whether attached to the model, the caller API key, the team, or the environment — scan the prompt before submission. A blocked prompt is rejected before any provider task is created and does not consume the model's rate-limit capacity.

Endpoint Behavior

  • The video ID is scoped by model access: callers whose API key cannot access the model alias receive 404 for that ID, and unknown or malformed IDs also return 404. The error type is video_not_found.
  • Submitting with a model alias whose provider is not listed under Supported Providers returns a not-implemented error.
  • If the provider key's api_base ends with the provider's OpenAI-compatible or versioned suffix (/compatible-mode/v1, /api/v1, or /v1 for Alibaba; /api/paas/v4 for Zhipu; /api/v3 for Volcengine Ark), AISIX derives the provider root automatically — an existing key configured for chat traffic works unchanged. Runway's documented base is the bare host, and OpenAI accepts either the bare host or a /v1 base.
  • OpenAI is the only video provider with a built-in default base URL: an OpenAI model with no api_base resolves to the standard OpenAI API. Every other provider requires api_base on the provider key.
  • Each submission is recorded in usage logs with zero tokens. Duration-based cost accounting for video tasks is not yet applied to budgets.

Supported Providers

provider valueModelsDelivery
alibabaAlibaba Model Studio WanRedirect
zhipuai (zhipu also accepted)Zhipu CogVideoXRedirect
volcengineVolcengine Ark SeedanceRedirect
runwayml (runway also accepted)Runway Gen family and Runway-hosted VeoRedirect
openaiOpenAI SoraGateway stream

Next Steps

You have now generated a video through the gateway's modeled video surface. For provider video APIs that AISIX has not modeled yet, use Provider Passthrough — model-level rate limits apply there as well when the request body names a configured model.