Vidu Q4 API, Vidu Q3 API Pro 7 Pro & Turbo, Vidu API: Pricing, Documentation

by Vidu

Vidu offers professional AI video generation with advanced reference-based capabilities for maintaining consistency across generated videos. Through Pixazo's API, developers can create videos that follow reference images or styles, ensuring brand consistency and creative control. The API's Q2 Pro model delivers high-quality output suitable for commercial video production and content creation workflows.

Get API Key
Vidu Video API

Models Version

WELCOME BONUS

Get 10% Cashback on Your First Payment (up to $500)

Add funds and get 10% cashback on your first payment (up to $500).

Claim Your Cashback →

Vidu Q4 API Documentation

Animate one image with Vidu Q4: send the image as the first frame and, optionally, a prompt describing the motion. You choose the length (duration, 3 to 16 seconds) and the resolution (resolution, 540p up to 4K). Asynchronous: submit returns a request_id; poll the status endpoint until the request is COMPLETED, then download the video from output.media_url.

POST https://gateway.pixazo.ai/vidu-q4/v1/image-to-video

Authentication

All requests require an API key passed via header.

HeaderTypeRequiredDescription
Ocp-Apim-Subscription-KeystringYesYour API subscription key

Image to Video - Vidu Q4

Request Code

POST https://gateway.pixazo.ai/vidu-q4/v1/image-to-video
Content-Type: application/json
Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY

{
  "prompt": "The subject turns slowly toward the camera and smiles, gentle push-in.",
  "image_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/images/input.jpg",
  "duration": 5,
  "resolution": "720p"
}
import requests

url = "https://gateway.pixazo.ai/vidu-q4/v1/image-to-video"
headers = {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY"
}
data = {
  "prompt": "The subject turns slowly toward the camera and smiles, gentle push-in.",
  "image_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/images/input.jpg",
  "duration": 5,
  "resolution": "720p"
}

resp = requests.post(url, json=data, headers=headers)
print(resp.json())
const res = await fetch("https://gateway.pixazo.ai/vidu-q4/v1/image-to-video", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY"
  },
  body: JSON.stringify({
  "prompt": "The subject turns slowly toward the camera and smiles, gentle push-in.",
  "image_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/images/input.jpg",
  "duration": 5,
  "resolution": "720p"
})
});
console.log(await res.json());
curl -X POST 'https://gateway.pixazo.ai/vidu-q4/v1/image-to-video' \
  -H 'Content-Type: application/json' \
  -H 'Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY' \
  --data-raw '{"prompt": "The subject turns slowly toward the camera and smiles, gentle push-in.", "image_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/images/input.jpg", "duration": 5, "resolution": "720p"}'

Output

{
  "request_id": "vidu-q4_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/vidu-q4_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Webhook (Optional)

Instead of polling, you can receive a Webhook callback when the request reaches a terminal state. Provide a Webhook URL via header on the submit request.

HeaderRequiredDescription
X-Webhook-URLTo enableHTTPS URL to receive the Webhook callback.
X-Webhook-ModeNoterminal (default, one callback on COMPLETED/ERROR) or sync (per-poll callbacks).

Example: enable Webhook

curl -X POST 'https://gateway.pixazo.ai/vidu-q4/v1/image-to-video' \
  -H 'Content-Type: application/json' \
  -H 'Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY' \
  -H 'X-Webhook-URL: https://your-server.com/webhook' \
  --data-raw '{"prompt": "The subject turns slowly toward the camera and smiles, gentle push-in.", "image_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/images/input.jpg", "duration": 5, "resolution": "720p"}'

Callback Payload (success)

{
  "request_id": "vidu-q4_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "vidu-q4",
  "error": null,
  "output": {
    "media_url": [
      "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/{request_id}/output.mp4"
    ],
    "media_type": "video/mp4"
  },
  "created_at": "2026-10-09T10:04:54.387Z",
  "completed_at": "2026-10-09 10:06:21"
}

Failure callback shape

{
  "request_id": "vidu-q4_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "ERROR",
  "model_id": "vidu-q4",
  "error": "Description of the failure"
}

Delivery semantics

  • terminal mode: one Webhook callback when the request is COMPLETED or ERROR.
  • sync mode: a Webhook callback on every poll while the request is processing (status PROCESSING), plus the final COMPLETED/ERROR callback.
  • Callbacks are idempotent on request_id — de-duplicate on it.
  • Respond 200 within a few seconds; the Webhook endpoint must be HTTPS.

Request Parameters

ParameterRequiredTypeDefaultAllowed values / rangeDescription
image_urlYesstring—One image: a publicly reachable https URL (recommended) or a data URIThe image to animate; it becomes the first frame of the video. Use a PNG, JPEG, JPG or WebP file.
promptNostringEmptyText, up to 5000 charactersWhat should happen in the video: the motion, the camera movement and the mood. Optional on image-to-video.
durationNointeger53–16Requested length of the video in whole seconds. Billing is per requested second.
resolutionNostring"720p"540p, 720p, 1080p, 2K, 4KOutput resolution, written exactly as listed (2K and 4K in capitals). Higher resolutions cost more per second.
seedNointegerRandom0–2147483647Seed for the random generator; leave it out for a random seed. It does not change the amount billed.
enable_safety_checkerNobooleantruetrue, falseContent safety screening, on by default. It does not change the amount billed.

Good to know

  • Each request returns one video. batch_size, num_images, number_of_images, n and count are rejected — send one request per video.
  • Set the length with duration, in whole seconds from 3 to 16 (5 when you leave it out); seconds, num_frames, frames_per_second and music_length_ms are rejected.
  • Set the resolution with resolution: 540p, 720p, 1080p, 2K or 4K, written exactly as listed (720p when you leave it out).
  • Send every field at the top level of the JSON body, with the text in prompt; parameters, content and text are rejected.
  • Send exactly one image as image_url; image_urls, image, images and subjects are rejected.
  • Image-to-video has no aspect-ratio or audio setting and takes no references: aspect_ratio, audio, reference_image_urls and reference_audio_urls are rejected (references go to the Reference to Video operation).
  • Use the JSON types shown: duration and seed are whole numbers (5, not "5"), and enable_safety_checker is true or false, not a string.
  • Omit a field instead of sending null.
  • Results are always returned as a URL in output.media_url; sync_mode is accepted only as false.
  • Webhooks are set with the X-Webhook-URL / X-Webhook-Mode headers; webhook_url, webhook_mode and callback_url in the JSON body are rejected.
  • Options this API does not offer are rejected: end_image_url, is_rec, off_peak, movement_amplitude, bgm, watermark, wm_position, wm_url, meta_data, voice_id, sounds, videos and reference_video_urls.

Length and Resolution

Set duration to the length you want in whole seconds, from 3 to 16; 5 applies when you leave it out. Set resolution to one of the values below; 720p applies when you leave it out. Billing is per second of the requested duration at the rate for the requested resolution, so a longer or higher-resolution video costs more.

resolutionNote
540pThe lowest cost per second
720pThe default
1080p—
2K—
4KThe highest cost per second

Example: an 8-second video at 1080p

{
  "image_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/images/input.jpg",
  "prompt": "Slow orbit around the subject, soft morning light.",
  "duration": 8,
  "resolution": "1080p"
}

Source Image

  • Send exactly one image in image_url: a publicly reachable https URL (recommended) or a data URI such as data:image/png;base64,.... A list of images is rejected.
  • Use a PNG, JPEG, JPG or WebP file. The image is downloaded when you submit: a URL that cannot be downloaded, or a very large file, may be refused at once with a 400, with nothing charged.
  • The image becomes the first frame of the video. Image-to-video has no aspect-ratio setting. The video keeps the aspect ratio of your image.
  • Describe the motion in prompt (optional, up to 5000 characters).

Example: send the image as a data URI (a URL is recommended)

{
  "image_url": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ...",
  "duration": 4,
  "resolution": "540p"
}

Audio

Image-to-video has no audio setting: audio and reference_audio_urls are rejected. Image-to-video output includes generated sound.

Example Request

{
  "prompt": "The subject turns slowly toward the camera and smiles, gentle push-in.",
  "image_url": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/images/input.jpg",
  "duration": 5,
  "resolution": "720p"
}

Example Response

{
  "request_id": "vidu-q4_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/vidu-q4_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Request Headers

HeaderRequiredDescription
Content-TypeYesapplication/json
Ocp-Apim-Subscription-KeyYesYour API subscription key.
X-Webhook-URLNoEnable Webhook callbacks (see Webhook section).
X-Webhook-ModeNoterminal (default) or sync (see Webhook section).

Response Handling

Status CodeMeaning
202Accepted — request queued; returns request_id and polling_url.
400Invalid request — a required field is missing, a value has the wrong type, is out of range or is not one of the allowed values, a field this operation does not accept was sent, or the image could not be downloaded. The message says what to fix.
401Unauthorized — missing or invalid subscription key.
402Insufficient balance for the hold this request needs.
429Too many requests.
500Internal server error.

Parameter problems are caught when you submit and returned as a 400, before any hold is placed on your balance. An image that cannot be downloaded is also refused at submit with a 400, and its hold is released at once: nothing is charged. Problems that need the model to run are reported through the status endpoint as status: "ERROR", with a message in error saying what went wrong. Failed requests are not billed — the hold is released in full.

ConditionHow it surfaces
Missing or invalid subscription keysynchronous 401
Balance too low for the holdsynchronous 402
Missing or empty image_url, or image_url sent as anything other than a single stringsynchronous 400
An image_url that cannot be downloaded when you submit, or that returns a web page or an empty file instead of an image (the hold is released at once: nothing is charged)synchronous 400
prompt not a string, or longer than 5000 characterssynchronous 400
resolution not one of the allowed values (written exactly as listed)synchronous 400
enable_safety_checker not true or false — for example the string "true"synchronous 400
duration not a whole number from 3 to 16 — for example 2, 17 or the string "5"synchronous 400
seed not a whole number from 0 to 2147483647 — for example -1, 2147483648 or the string "0"synchronous 400
sync_mode set to anything other than false (results are always returned as a URL in output.media_url)synchronous 400
batch_size, num_images, number_of_images, n, count (one video per request)synchronous 400
seconds, num_frames, frames_per_second, music_length_ms (set the length with duration, in whole seconds)synchronous 400
parameters, content, text (send the fields at the top level of the JSON body, the text in prompt)synchronous 400
aspect_ratio, audio (image-to-video has no aspect-ratio or audio setting)synchronous 400
reference_image_urls, reference_audio_urls (references go to the Reference to Video operation)synchronous 400
image_urls, image, images, subjects (send exactly one image, as image_url)synchronous 400
voice_id, sounds (reference audio clips go in reference_audio_urls on Reference to Video)synchronous 400
videos, reference_video_urls (this API takes no reference videos)synchronous 400
webhook_url, webhook_mode, callback_url in the JSON body (use the X-Webhook-URL / X-Webhook-Mode headers)synchronous 400
end_image_url, is_rec, off_peak, movement_amplitude, bgm, watermark, wm_position, wm_url, meta_data (not offered on this API)synchronous 400
An image the model cannot use, for example a file that is not an imagestatus: "ERROR"
A prompt or image the model refuses, for example under its content policystatus: "ERROR"

Example error responses

A refused request returns error, a message that joins every problem found, and the same problems one by one in violations.

Missing image_url (synchronous 400)

{
  "error": "Invalid request parameters",
  "message": "'image_url' is required",
  "violations": [
    "'image_url' is required"
  ]
}

A value that is not allowed (synchronous 400)

{
  "error": "Invalid request parameters",
  "message": "'resolution' must be one of: \"540p\", \"720p\", \"1080p\", \"2K\", \"4K\" (got \"1440p\")",
  "violations": [
    "'resolution' must be one of: \"540p\", \"720p\", \"1080p\", \"2K\", \"4K\" (got \"1440p\")"
  ]
}

A value out of range (synchronous 400)

{
  "error": "Invalid request parameters",
  "message": "'duration' must be <= 16 (got 17)",
  "violations": [
    "'duration' must be <= 16 (got 17)"
  ]
}

A number sent as a string (synchronous 400)

{
  "error": "Invalid request parameters",
  "message": "'duration' must be integer (got string)",
  "violations": [
    "'duration' must be integer (got string)"
  ]
}

A field image-to-video does not accept (synchronous 400)

{
  "error": "Invalid request parameters",
  "message": "'aspect_ratio' must be one of:  (got \"16:9\"); 'aspect_ratio' is not accepted by image-to-video, which has no aspect-ratio setting. Remove the field from the request.",
  "violations": [
    "'aspect_ratio' must be one of:  (got \"16:9\")",
    "'aspect_ratio' is not accepted by image-to-video, which has no aspect-ratio setting. Remove the field from the request."
  ]
}

Retrieving Results

Poll the status endpoint with the request_id from the submit response until status is COMPLETED or ERROR, then download the video from output.media_url. Treat any status other than QUEUED, PROCESSING or COMPLETED as a failure.

Endpoint

GET https://gateway.pixazo.ai/v2/requests/status/{request_id}
Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY

cURL example

curl 'https://gateway.pixazo.ai/v2/requests/status/vidu-q4_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' \
  -H 'Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY'

Completed response

{
  "request_id": "vidu-q4_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "vidu-q4",
  "error": null,
  "output": {
    "media_url": [
      "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/{request_id}/output.mp4"
    ],
    "media_type": "video/mp4"
  },
  "created_at": "2026-10-09T10:04:54.387Z",
  "completed_at": "2026-10-09 10:06:21"
}

Response Fields

FieldTypeDescription
request_idstringUnique request identifier.
statusstringQUEUED, PROCESSING, COMPLETED or ERROR.
model_idstringThe model that handled the request — vidu-q4 for this endpoint.
output.media_urlarray of stringsURL of the video (one MP4 file per request).
output.media_typestringvideo/mp4.
created_atstringRequest creation timestamp.
completed_atstringCompletion timestamp.
errorstringError message when status is ERROR.
polling_urlstringStatus URL for this request (submit response only).

Status Values & Flow

QUEUED → PROCESSING → COMPLETED (success) or ERROR (failure).

Typical workflow

  1. Send the request to POST https://gateway.pixazo.ai/vidu-q4/v1/image-to-video.
  2. Save the request_id from the 202 response.
  3. Poll GET /v2/requests/status/{request_id} every 10 seconds or so, or use a Webhook instead.
  4. When status is COMPLETED, download the video from output.media_url.

How Billing Is Measured

Billing is measured per second of the requested duration, at the rate for the requested resolution: the amount is the per-second rate for resolution (720p when you leave it out) times duration (5 seconds when you leave it out). Higher resolutions cost more per second. The prompt, seed and safety setting do not change the amount. The amount is placed as a hold when the request is submitted and released in full if the request fails. The current rate is shown in the pricing panel on this page.

Vidu Q4 API Pricing

Billed per second of video at the requested resolution (540p, 720p, 1080p, 2K or 4K). 720p and 5 seconds are the defaults; duration can be 3 to 16 seconds.

ResolutionPrice (USD)
540p / per second$0.045
720p / per second$0.095
1080p / per second$0.12
2K / per second$0.19
4K / per second$0.39
Reference to Video

Vidu Q4 API Documentation

Generate a video from a prompt and 1 to 12 reference images with Vidu Q4: refer to each reference in the prompt by its position ([@reference_image_1], ...), choose the aspect ratio, the length (3 to 16 seconds) and the resolution (540p up to 4K), and optionally add up to 3 reference audio clips with audio turned on. Asynchronous: submit returns a request_id; poll the status endpoint until the request is COMPLETED, then download the video from output.media_url.

POST https://gateway.pixazo.ai/vidu-q4/v1/reference-to-video

Authentication

All requests require an API key passed via header.

HeaderTypeRequiredDescription
Ocp-Apim-Subscription-KeystringYesYour API subscription key

Reference to Video - Vidu Q4

Request Code

POST https://gateway.pixazo.ai/vidu-q4/v1/reference-to-video
Content-Type: application/json
Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY

{
  "prompt": "[@reference_image_1] walks slowly toward the camera and smiles.",
  "reference_image_urls": [
    "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/images/input.jpg"
  ],
  "duration": 5,
  "resolution": "720p",
  "aspect_ratio": "16:9"
}
import requests

url = "https://gateway.pixazo.ai/vidu-q4/v1/reference-to-video"
headers = {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY"
}
data = {
  "prompt": "[@reference_image_1] walks slowly toward the camera and smiles.",
  "reference_image_urls": [
    "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/images/input.jpg"
  ],
  "duration": 5,
  "resolution": "720p",
  "aspect_ratio": "16:9"
}

resp = requests.post(url, json=data, headers=headers)
print(resp.json())
const res = await fetch("https://gateway.pixazo.ai/vidu-q4/v1/reference-to-video", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY"
  },
  body: JSON.stringify({
  "prompt": "[@reference_image_1] walks slowly toward the camera and smiles.",
  "reference_image_urls": [
    "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/images/input.jpg"
  ],
  "duration": 5,
  "resolution": "720p",
  "aspect_ratio": "16:9"
})
});
console.log(await res.json());
curl -X POST 'https://gateway.pixazo.ai/vidu-q4/v1/reference-to-video' \
  -H 'Content-Type: application/json' \
  -H 'Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY' \
  --data-raw '{"prompt": "[@reference_image_1] walks slowly toward the camera and smiles.", "reference_image_urls": ["https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/images/input.jpg"], "duration": 5, "resolution": "720p", "aspect_ratio": "16:9"}'

Output

{
  "request_id": "vidu-q4_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/vidu-q4_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Webhook (Optional)

Instead of polling, you can receive a Webhook callback when the request reaches a terminal state. Provide a Webhook URL via header on the submit request.

HeaderRequiredDescription
X-Webhook-URLTo enableHTTPS URL to receive the Webhook callback.
X-Webhook-ModeNoterminal (default, one callback on COMPLETED/ERROR) or sync (per-poll callbacks).

Example: enable Webhook

curl -X POST 'https://gateway.pixazo.ai/vidu-q4/v1/reference-to-video' \
  -H 'Content-Type: application/json' \
  -H 'Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY' \
  -H 'X-Webhook-URL: https://your-server.com/webhook' \
  --data-raw '{"prompt": "[@reference_image_1] walks slowly toward the camera and smiles.", "reference_image_urls": ["https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/images/input.jpg"], "duration": 5, "resolution": "720p", "aspect_ratio": "16:9"}'

Callback Payload (success)

{
  "request_id": "vidu-q4_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "vidu-q4",
  "error": null,
  "output": {
    "media_url": [
      "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/{request_id}/output.mp4"
    ],
    "media_type": "video/mp4"
  },
  "created_at": "2026-10-09T10:04:54.387Z",
  "completed_at": "2026-10-09 10:06:21"
}

Failure callback shape

{
  "request_id": "vidu-q4_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "ERROR",
  "model_id": "vidu-q4",
  "error": "Description of the failure"
}

Delivery semantics

  • terminal mode: one Webhook callback when the request is COMPLETED or ERROR.
  • sync mode: a Webhook callback on every poll while the request is processing (status PROCESSING), plus the final COMPLETED/ERROR callback.
  • Callbacks are idempotent on request_id — de-duplicate on it.
  • Respond 200 within a few seconds; the Webhook endpoint must be HTTPS.

Request Parameters

ParameterRequiredTypeDefaultAllowed values / rangeDescription
promptYesstring—Non-empty text, up to 5000 charactersWhat happens in the video. Refer to each reference by its position: [@reference_image_1], [@reference_image_2], ... for images and [reference_audio_1], ... for audio clips (see the Prompting Guide below).
reference_image_urlsYesarray—1–12 images: https URLs (recommended) or data URIsImages of the subjects, characters, objects or places you want in the video (PNG, JPEG, JPG or WebP), as non-empty URL strings. The first one is [@reference_image_1] in the prompt.
reference_audio_urlsNoarray—Up to 3 mp3 clips, 3–12 seconds eachReference audio clips to refer to in the prompt as [reference_audio_1], ... Requires audio: true.
aspect_ratioNostring"16:9"16:9, 9:16, 4:3, 3:4, 1:1Frame shape of the video. It does not change the amount billed.
audioNobooleanfalsetrue, falseSet to true to request generated audio for the video. Turning audio on does not change the price. Must be true when you send reference_audio_urls.
durationNointeger53–16Requested length of the video in whole seconds. Billing is per requested second.
resolutionNostring"720p"540p, 720p, 1080p, 2K, 4KOutput resolution, written exactly as listed (2K and 4K in capitals). Higher resolutions cost more per second.
seedNointegerRandom0–2147483647Seed for the random generator; leave it out for a random seed. It does not change the amount billed.
enable_safety_checkerNobooleantruetrue, falseContent safety screening, on by default. It does not change the amount billed.

Good to know

  • Each request returns one video. batch_size, num_images, number_of_images, n and count are rejected — send one request per video.
  • Set the length with duration, in whole seconds from 3 to 16 (5 when you leave it out); seconds, num_frames, frames_per_second and music_length_ms are rejected.
  • Set the resolution with resolution: 540p, 720p, 1080p, 2K or 4K, written exactly as listed (720p when you leave it out).
  • Send every field at the top level of the JSON body, with the text in prompt; parameters, content and text are rejected.
  • Send 1 to 12 reference images in reference_image_urls and refer to them in prompt by their position in the list ([@reference_image_1] is the first); image_url, image_urls, image, images and subjects are rejected.
  • Omit a field instead of sending null; reference_image_urls must be non-empty URL strings.
  • reference_audio_urls requires audio: true (it takes up to 3 mp3 clips).
  • Use the JSON types shown: duration and seed are whole numbers (5, not "5"), and audio and enable_safety_checker are true or false, not strings.
  • Results are always returned as a URL in output.media_url; sync_mode is accepted only as false.
  • Webhooks are set with the X-Webhook-URL / X-Webhook-Mode headers; webhook_url, webhook_mode and callback_url in the JSON body are rejected.
  • Options this API does not offer are rejected: end_image_url, is_rec, off_peak, movement_amplitude, bgm, watermark, wm_position, wm_url, meta_data, voice_id, sounds, videos and reference_video_urls.

Length and Resolution

Set duration to the length you want in whole seconds, from 3 to 16; 5 applies when you leave it out. Set resolution to one of the values below; 720p applies when you leave it out. Billing is per second of the requested duration at the rate for the requested resolution, so a longer or higher-resolution video costs more.

resolutionNote
540pThe lowest cost per second
720pThe default
1080p—
2K—
4KThe highest cost per second

Example: an 8-second video at 1080p

{
  "prompt": "[@reference_image_1] walks slowly toward the camera and smiles.",
  "reference_image_urls": [
    "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/images/input.jpg"
  ],
  "duration": 8,
  "resolution": "1080p",
  "aspect_ratio": "16:9"
}

References

  • Send 1 to 12 images in reference_image_urls, as non-empty URL strings: publicly reachable https URLs are recommended; data URIs are accepted. Use PNG, JPEG, JPG or WebP images.
  • Optionally send up to 3 mp3 clips of 3 to 12 seconds each in reference_audio_urls; they need audio: true.
  • Every input is downloaded when you submit. Very many or very large inputs may be refused at once with a 400, with nothing charged; so may a URL that cannot be downloaded.

Example: a portrait video

{
  "prompt": "[@reference_image_1] looks up at the falling snow and smiles.",
  "reference_image_urls": [
    "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/images/input.jpg"
  ],
  "aspect_ratio": "9:16",
  "duration": 8,
  "resolution": "1080p"
}

Prompting Guide

  • Refer to each reference by its position in its list: [@reference_image_1] is the first URL in reference_image_urls, [@reference_image_2] the second, and so on; [reference_audio_1] is the first clip in reference_audio_urls.
  • Describe the action, the camera movement and the setting, and say which reference does what. The prompt is required and can be up to 5000 characters.

Example prompt with two references

[@reference_image_1] walks along the beach at sunset holding [@reference_image_2], then turns to the camera and smiles.

Aspect Ratio

Set aspect_ratio to 16:9, 9:16, 4:3, 3:4 or 1:1; 16:9 applies when you leave it out. It does not change the amount billed.

Audio

Set audio to true to request generated audio for the video; false applies when you leave it out. Turning audio on does not change the price. reference_audio_urls requires audio: true: a request with reference audio clips and audio left out or false is refused with a 400.

Example: turn audio on

{
  "prompt": "[@reference_image_1] waves and says hello.",
  "reference_image_urls": [
    "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/images/input.jpg"
  ],
  "audio": true,
  "duration": 5,
  "resolution": "720p"
}

Example Request

{
  "prompt": "[@reference_image_1] walks slowly toward the camera and smiles.",
  "reference_image_urls": [
    "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/images/input.jpg"
  ],
  "duration": 5,
  "resolution": "720p",
  "aspect_ratio": "16:9"
}

Example Response

{
  "request_id": "vidu-q4_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/vidu-q4_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Request Headers

HeaderRequiredDescription
Content-TypeYesapplication/json
Ocp-Apim-Subscription-KeyYesYour API subscription key.
X-Webhook-URLNoEnable Webhook callbacks (see Webhook section).
X-Webhook-ModeNoterminal (default) or sync (see Webhook section).

Response Handling

Status CodeMeaning
202Accepted — request queued; returns request_id and polling_url.
400Invalid request — a required field is missing, a value has the wrong type, is out of range or is not one of the allowed values, a field this operation does not accept was sent, or an input could not be downloaded. The message says what to fix.
401Unauthorized — missing or invalid subscription key.
402Insufficient balance for the hold this request needs.
429Too many requests.
500Internal server error.

Parameter problems are caught when you submit and returned as a 400, before any hold is placed on your balance. An input that cannot be downloaded is also refused at submit with a 400, and so may be very many or very large inputs; the hold is then released at once: nothing is charged. Problems that need the model to run are reported through the status endpoint as status: "ERROR", with a message in error saying what went wrong. Failed requests are not billed — the hold is released in full.

ConditionHow it surfaces
Missing or invalid subscription keysynchronous 401
Balance too low for the holdsynchronous 402
Missing or empty prompt, prompt not a string, or longer than 5000 characterssynchronous 400
Missing or empty reference_image_urls, reference_image_urls not a list, or more than 12 itemssynchronous 400
A reference_image_urls or reference_audio_urls entry that cannot be downloaded when you submit, or very many or very large inputs (the hold is released at once: nothing is charged)synchronous 400
reference_audio_urls not a list, or more than 3 itemssynchronous 400
reference_audio_urls sent without audio: truesynchronous 400
resolution not one of the allowed values (written exactly as listed)synchronous 400
aspect_ratio not one of the allowed values (written exactly as listed)synchronous 400
enable_safety_checker or audio not true or false — for example the string "true"synchronous 400
duration not a whole number from 3 to 16 — for example 2, 17 or the string "5"synchronous 400
seed not a whole number from 0 to 2147483647 — for example -1, 2147483648 or the string "0"synchronous 400
sync_mode set to anything other than false (results are always returned as a URL in output.media_url)synchronous 400
batch_size, num_images, number_of_images, n, count (one video per request)synchronous 400
seconds, num_frames, frames_per_second, music_length_ms (set the length with duration, in whole seconds)synchronous 400
parameters, content, text (send the fields at the top level of the JSON body, the text in prompt)synchronous 400
image_url, image_urls, image, images, subjects (send images in reference_image_urls)synchronous 400
voice_id, sounds (reference audio clips go in reference_audio_urls on Reference to Video)synchronous 400
videos, reference_video_urls (this API takes no reference videos)synchronous 400
webhook_url, webhook_mode, callback_url in the JSON body (use the X-Webhook-URL / X-Webhook-Mode headers)synchronous 400
end_image_url, is_rec, off_peak, movement_amplitude, bgm, watermark, wm_position, wm_url, meta_data (not offered on this API)synchronous 400
A reference the model cannot use, for example a file that is not an image, or an audio clip that is not an mp3 of 3 to 12 secondsstatus: "ERROR"
A prompt or reference the model refuses, for example under its content policystatus: "ERROR"

Example error responses

A refused request returns error, a message that joins every problem found, and the same problems one by one in violations.

Missing prompt (synchronous 400)

{
  "error": "Invalid request parameters",
  "message": "'prompt' is required",
  "violations": [
    "'prompt' is required"
  ]
}

More than 12 reference images (synchronous 400)

{
  "error": "Invalid request parameters",
  "message": "'reference_image_urls' must have at most 12 items (got 13)",
  "violations": [
    "'reference_image_urls' must have at most 12 items (got 13)"
  ]
}

A value that is not allowed (synchronous 400)

{
  "error": "Invalid request parameters",
  "message": "'resolution' must be one of: \"540p\", \"720p\", \"1080p\", \"2K\", \"4K\" (got \"4k\")",
  "violations": [
    "'resolution' must be one of: \"540p\", \"720p\", \"1080p\", \"2K\", \"4K\" (got \"4k\")"
  ]
}

Reference audio without audio: true (synchronous 400)

{
  "error": "Invalid request parameters",
  "message": "'reference_audio_urls' needs 'audio': true. Set 'audio': true, or remove 'reference_audio_urls'.",
  "violations": [
    "'reference_audio_urls' needs 'audio': true. Set 'audio': true, or remove 'reference_audio_urls'."
  ]
}

A field this operation does not accept (synchronous 400)

{
  "error": "Invalid request parameters",
  "message": "'num_images' must be one of:  (got 2); 'num_images' is not supported: Vidu Q4 returns one video per request. Send one request per video.",
  "violations": [
    "'num_images' must be one of:  (got 2)",
    "'num_images' is not supported: Vidu Q4 returns one video per request. Send one request per video."
  ]
}

Retrieving Results

Poll the status endpoint with the request_id from the submit response until status is COMPLETED or ERROR, then download the video from output.media_url. Treat any status other than QUEUED, PROCESSING or COMPLETED as a failure.

Endpoint

GET https://gateway.pixazo.ai/v2/requests/status/{request_id}
Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY

cURL example

curl 'https://gateway.pixazo.ai/v2/requests/status/vidu-q4_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' \
  -H 'Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY'

Completed response

{
  "request_id": "vidu-q4_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "vidu-q4",
  "error": null,
  "output": {
    "media_url": [
      "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/{request_id}/output.mp4"
    ],
    "media_type": "video/mp4"
  },
  "created_at": "2026-10-09T10:04:54.387Z",
  "completed_at": "2026-10-09 10:06:21"
}

Response Fields

FieldTypeDescription
request_idstringUnique request identifier.
statusstringQUEUED, PROCESSING, COMPLETED or ERROR.
model_idstringThe model that handled the request — vidu-q4 for this endpoint.
output.media_urlarray of stringsURL of the video (one MP4 file per request).
output.media_typestringvideo/mp4.
created_atstringRequest creation timestamp.
completed_atstringCompletion timestamp.
errorstringError message when status is ERROR.
polling_urlstringStatus URL for this request (submit response only).

Status Values & Flow

QUEUED → PROCESSING → COMPLETED (success) or ERROR (failure).

Typical workflow

  1. Send the request to POST https://gateway.pixazo.ai/vidu-q4/v1/reference-to-video.
  2. Save the request_id from the 202 response.
  3. Poll GET /v2/requests/status/{request_id} every 10 seconds or so, or use a Webhook instead.
  4. When status is COMPLETED, download the video from output.media_url.

How Billing Is Measured

Billing is measured per second of the requested duration, at the rate for the requested resolution: the amount is the per-second rate for resolution (720p when you leave it out) times duration (5 seconds when you leave it out). Higher resolutions cost more per second. The prompt, seed, aspect ratio and safety setting do not change the amount. Turning audio on does not change the price. The amount is placed as a hold when the request is submitted and released in full if the request fails. The current rate is shown in the pricing panel on this page.

Vidu Q4 API Pricing

Billed per second of video at the requested resolution (540p, 720p, 1080p, 2K or 4K); turning audio on does not change the price. 720p and 5 seconds are the defaults; duration can be 3 to 16 seconds.

ResolutionPrice (USD)
540p / per second$0.045
720p / per second$0.095
1080p / per second$0.12
2K / per second$0.19
4K / per second$0.39
2. Vidu Q3 Pro

Vidu Q3 Pro API Documentation

https://gateway.pixazo.ai/vidu-q3-pro/v1/text-to-video

Authentication

All requests require an API key passed via header.

HeaderTypeRequiredDescription
Ocp-Apim-Subscription-KeystringYesYour API subscription key

Text to Video - Vidu Q3 Pro

Request Code

POST https://gateway.pixazo.ai/vidu-q3-pro/v1/text-to-video
Content-Type: application/json
Cache-Control: no-cache
Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY

{
  "prompt": "A golden retriever running through a sunlit meadow in slow motion"
}
import requests

url = "https://gateway.pixazo.ai/vidu-q3-pro/v1/text-to-video"
headers = {
    "Content-Type": "application/json",
    "Cache-Control": "no-cache",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY"
}
data = {
    "prompt": "A golden retriever running through a sunlit meadow in slow motion"
}

response = requests.post(url, json=data, headers=headers)
print(response.json())
const url = 'https://gateway.pixazo.ai/vidu-q3-pro/v1/text-to-video';
const headers = {
  'Content-Type': 'application/json',
  'Cache-Control': 'no-cache',
  'Ocp-Apim-Subscription-Key': 'YOUR_SUBSCRIPTION_KEY'
};
const data = {
  prompt: 'A golden retriever running through a sunlit meadow in slow motion'
};

fetch(url, {
  method: 'POST',
  headers: headers,
  body: JSON.stringify(data)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
curl -v -X POST "https://gateway.pixazo.ai/vidu-q3-pro/v1/text-to-video" \
  -H "Content-Type: application/json" \
  -H "Cache-Control: no-cache" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "prompt": "A golden retriever running through a sunlit meadow in slow motion"
  }'

Output

{
  "request_id": "vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Webhook (Optional)

Add the X-Webhook-URL header to your submit request to receive a POST callback when the job completes — no polling required.

Using curl? These are HTTP request headers — pass each with -H, e.g. -H "X-Webhook-URL: https://your-server.com/webhook/callback". Do not paste them as bare lines, and end every line of a multi-line command with \.

Webhook Headers

HeaderRequiredDefaultDescription
X-Webhook-URLYes (to enable)—HTTPS endpoint on your server that will receive the POST callback. Must respond 2xx within a few seconds (process async if needed).
X-Webhook-ModeNoterminalterminal — fires once at the final status (COMPLETED/FAILED/ERROR). sync — fires on every poll cycle plus the terminal event, and caps the queue’s polling delay at 15s for tighter progress updates.

Example: enable webhook

X-Webhook-URL: https://your-server.com/webhook/callback
X-Webhook-Mode: terminal

Callback Payload

Your endpoint receives a POST application/json with the same shape as the GET /v2/requests/status/{request_id} response. Example terminal callback (mode terminal):

{
  "request_id": "vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "vidu-q3-pro",
  "error": null,
  "output": {
    "media_url": [
      "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/output.mp4"
    ],
    "media_type": "video/mp4"
  },
  "created_at": "2026-05-22T13:17:32.110Z",
  "updated_at": "2026-05-22 13:19:23",
  "completed_at": "2026-05-22 13:19:23"
}

Failure callback shape

{
  "request_id": "vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "ERROR",
  "model_id": "vidu-q3-pro",
  "error": "Description of the error",
  "output": null,
  "created_at": "...",
  "updated_at": "...",
  "completed_at": "..."
}

Delivery semantics

  • terminal mode (default) — exactly one POST when the request reaches a terminal status. No callback during PROCESSING.
  • sync mode — POST on every status poll (with delay capped at ~15s) plus a final POST at terminal status. Use when you want progress updates.
  • Idempotency — use request_id as your idempotency key. Network retries can deliver the same callback more than once; your handler must tolerate duplicates.
  • Response — respond 200 OK within a few seconds. The queue does not block on slow handlers, but persistent failures may stop further deliveries.
  • HTTPS required — plain http:// URLs are rejected.

Request Parameters - Text to Video

Parameter Required Type Default Allowed values / range Description
promptYesstring—non-empty; ≤ 5000 charsText description of the video to generate.
durationNointeger51–16 (seconds)Video length in seconds. Billed per second.
resolutionNostring"720p""540p", "720p", "1080p"Output resolution. Billed per second by resolution.
aspect_ratioNostring"16:9""16:9", "9:16", "3:4", "4:3", "1:1"Output aspect ratio (text-to-video only).
audioNobooleantruetrue, falseEnable audio-video sync. false outputs a silent video.

Example Request

{
  "prompt": "A golden retriever running through a sunlit meadow in slow motion",
  "duration": 5,
  "resolution": "720p",
  "aspect_ratio": "16:9",
  "audio": true
}

Response

{
  "request_id": "vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Request Headers

Header Value
Content-Typeapplication/json
Cache-Controlno-cache
Ocp-Apim-Subscription-KeyYOUR_SUBSCRIPTION_KEY

Response Handling

Common status codes.

CodeMeaning
202Accepted — Request queued
Bad Request
401Unauthorized
402Insufficient Balance
403Forbidden
Too Many Requests
500Internal Server Error

Error Responses

Queue system errors and model validation errors.

Queue System Errors

// 402 — Insufficient balance
{
  "error": "Insufficient Balance",
  "message": "Your wallet does not have enough balance."
}
// 400 — Model not found
{
  "error": "Model not found",
  "message": "Model 'vidu-q3-pro' not found or is disabled"
}

Error via Status/Webhook

{
  "request_id": "vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "ERROR",
  "model_id": "vidu-q3-pro",
  "error": "Description of the error",
  "output": null
}

Retrieving Results

Poll the universal status endpoint to check progress and retrieve results.

Endpoint

GET https://gateway.pixazo.ai/v2/requests/status/{request_id}
Ocp-Apim-Subscription-Key: YOUR_API_KEY

cURL Example

curl -H "Ocp-Apim-Subscription-Key: YOUR_API_KEY" \
  "https://gateway.pixazo.ai/v2/requests/status/vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

Response (Completed)

{
  "request_id": "vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "vidu-q3-pro",
  "error": null,
  "output": {
    "media_url": [
      "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/vidu-q3-pro_019dxxxx-xxxx/output.mp4"
    ],
    "media_type": "video/mp4"
  },
  "created_at": "2026-04-07T10:00:00.000Z",
  "updated_at": "2026-04-07T10:02:30.000Z",
  "completed_at": "2026-04-07T10:02:30.000Z"
}

Response Fields

FieldTypeDescription
request_idstringUnique request identifier
statusstringQUEUED, PROCESSING, COMPLETED, FAILED, or ERROR
model_idstringModel that processed the request
errorstring|nullError message if failed
output.media_urlarrayURLs to generated media (R2 CDN)
output.media_typestringMIME type of the output
created_atstringWhen request was created
completed_atstring|nullWhen request completed
polling_urlstringStatus URL (initial response only)

Status Values

StatusDescription
QUEUEDRequest accepted, waiting to be processed
PROCESSINGBeing processed by the model
COMPLETEDDone — output contains the result
FAILEDFailed — check error field
ERRORSystem error — not charged

Status Flow

QUEUED → PROCESSING → COMPLETED
                    → FAILED
                    → ERROR

Typical Workflow

  1. Send a generate request to the API endpoint
  2. Save the request_id from the response
  3. Poll every 5-10 seconds: GET /v2/requests/status/{request_id}
  4. When status is "COMPLETED", download from output.media_url

Tip: Use X-Webhook-URL header to get a callback instead of polling.

Examples

Common ways to call POST /vidu-q3-pro/v1/text-to-video. Each submit returns a request_id — poll GET /v2/requests/status/{request_id} until COMPLETED.

Portrait Aspect Ratio — Vertical video for social media.
const res = await fetch("https://gateway.pixazo.ai/vidu-q3-pro/v1/text-to-video", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY",
  },
  body: JSON.stringify({
    prompt: "A busy street in Tokyo at night with neon signs reflecting on wet pavement, rain falling",
    aspect_ratio: "9:16",
    duration: 5,
    resolution: "720p",
  }),
});

const { request_id } = await res.json() as { request_id: string };
// Poll GET /v2/requests/status/{request_id} until status === "COMPLETED"
curl -X POST "https://gateway.pixazo.ai/vidu-q3-pro/v1/text-to-video" \
  -H "Content-Type: application/json" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "prompt": "A busy street in Tokyo at night with neon signs reflecting on wet pavement, rain falling",
    "aspect_ratio": "9:16",
    "duration": 5,
    "resolution": "720p"
  }'
Silent Video — Generate video without audio.
const res = await fetch("https://gateway.pixazo.ai/vidu-q3-pro/v1/text-to-video", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY",
  },
  body: JSON.stringify({
    audio: false,
    prompt: "Abstract paint swirls slowly mixing in water, vivid blues and golds",
    duration: 8,
    resolution: "720p",
  }),
});

const { request_id } = await res.json() as { request_id: string };
// Poll GET /v2/requests/status/{request_id} until status === "COMPLETED"
curl -X POST "https://gateway.pixazo.ai/vidu-q3-pro/v1/text-to-video" \
  -H "Content-Type: application/json" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "audio": false,
    "prompt": "Abstract paint swirls slowly mixing in water, vivid blues and golds",
    "duration": 8,
    "resolution": "720p"
  }'
Square Format — Square video for product demos or social posts.
const res = await fetch("https://gateway.pixazo.ai/vidu-q3-pro/v1/text-to-video", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY",
  },
  body: JSON.stringify({
    prompt: "A sleek wireless headphone rotating on a pedestal with soft studio lighting and a white background",
    aspect_ratio: "1:1",
    duration: 5,
    resolution: "720p",
  }),
});

const { request_id } = await res.json() as { request_id: string };
// Poll GET /v2/requests/status/{request_id} until status === "COMPLETED"
curl -X POST "https://gateway.pixazo.ai/vidu-q3-pro/v1/text-to-video" \
  -H "Content-Type: application/json" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "prompt": "A sleek wireless headphone rotating on a pedestal with soft studio lighting and a white background",
    "aspect_ratio": "1:1",
    "duration": 5,
    "resolution": "720p"
  }'

Vidu Q3 Pro API Pricing

ResolutionPrice (USD)
540p (per second of video)$0.05
720p (per second of video)$0.125
1080p (per second of video)$0.15
Image to Video

Vidu Q3 Pro API Documentation

https://gateway.pixazo.ai/vidu-q3-pro/v1/image-to-video

Authentication

All requests require an API key passed via header.

HeaderTypeRequiredDescription
Ocp-Apim-Subscription-KeystringYesYour API subscription key

Image to Video - Vidu Q3 Pro

Request Code

POST https://gateway.pixazo.ai/vidu-q3-pro/v1/image-to-video
Content-Type: application/json
Cache-Control: no-cache
Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY

{
  "start_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
  "prompt": "the subject turns toward the camera, gentle natural motion"
}
import requests

url = "https://gateway.pixazo.ai/vidu-q3-pro/v1/image-to-video"
headers = {
    "Content-Type": "application/json",
    "Cache-Control": "no-cache",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY"
}
data = {
    "start_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    "prompt": "the subject turns toward the camera, gentle natural motion"
}

response = requests.post(url, json=data, headers=headers)
print(response.json())
const url = 'https://gateway.pixazo.ai/vidu-q3-pro/v1/image-to-video';
const headers = {
  'Content-Type': 'application/json',
  'Cache-Control': 'no-cache',
  'Ocp-Apim-Subscription-Key': 'YOUR_SUBSCRIPTION_KEY'
};
const data = {
  start_image: 'https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png',
  prompt: 'the subject turns toward the camera, gentle natural motion'
};

fetch(url, {
  method: 'POST',
  headers: headers,
  body: JSON.stringify(data)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
curl -v -X POST "https://gateway.pixazo.ai/vidu-q3-pro/v1/image-to-video" \
  -H "Content-Type: application/json" \
  -H "Cache-Control: no-cache" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "start_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    "prompt": "the subject turns toward the camera, gentle natural motion"
  }'

Output

{
  "request_id": "vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Webhook (Optional)

Add the X-Webhook-URL header to your submit request to receive a POST callback when the job completes — no polling required.

Using curl? These are HTTP request headers — pass each with -H, e.g. -H "X-Webhook-URL: https://your-server.com/webhook/callback". Do not paste them as bare lines, and end every line of a multi-line command with \.

Webhook Headers

HeaderRequiredDefaultDescription
X-Webhook-URLYes (to enable)—HTTPS endpoint on your server that will receive the POST callback. Must respond 2xx within a few seconds (process async if needed).
X-Webhook-ModeNoterminalterminal — fires once at the final status (COMPLETED/FAILED/ERROR). sync — fires on every poll cycle plus the terminal event, and caps the queue’s polling delay at 15s for tighter progress updates.

Example: enable webhook

X-Webhook-URL: https://your-server.com/webhook/callback
X-Webhook-Mode: terminal

Callback Payload

Your endpoint receives a POST application/json with the same shape as the GET /v2/requests/status/{request_id} response. Example terminal callback (mode terminal):

{
  "request_id": "vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "vidu-q3-pro",
  "error": null,
  "output": {
    "media_url": [
      "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/output.mp4"
    ],
    "media_type": "video/mp4"
  },
  "created_at": "2026-05-22T13:17:32.110Z",
  "updated_at": "2026-05-22 13:19:23",
  "completed_at": "2026-05-22 13:19:23"
}

Failure callback shape

{
  "request_id": "vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "ERROR",
  "model_id": "vidu-q3-pro",
  "error": "Description of the error",
  "output": null,
  "created_at": "...",
  "updated_at": "...",
  "completed_at": "..."
}

Delivery semantics

  • terminal mode (default) — exactly one POST when the request reaches a terminal status. No callback during PROCESSING.
  • sync mode — POST on every status poll (with delay capped at ~15s) plus a final POST at terminal status. Use when you want progress updates.
  • Idempotency — use request_id as your idempotency key. Network retries can deliver the same callback more than once; your handler must tolerate duplicates.
  • Response — respond 200 OK within a few seconds. The queue does not block on slow handlers, but persistent failures may stop further deliveries.
  • HTTPS required — plain http:// URLs are rejected.

Request Parameters - Image to Video

Parameter Required Type Default Allowed values / range Description
start_imageYesstring—public URL or data:image/...;base64,…Starting frame to animate.
promptNostring—≤ 5000 charsOptional text guiding the motion / scene.
durationNointeger51–16 (seconds)Video length in seconds. Billed per second.
resolutionNostring"720p""540p", "720p", "1080p"Output resolution. Billed per second by resolution.
audioNobooleantruetrue, falseEnable audio-video sync. false outputs a silent video.

Content Item Types & Limits

TypeMaxFormat / SizeDescription
image1JPG, PNG, WEBP · < 50 MBStart image.

Example Request

{
  "start_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
  "prompt": "the subject turns toward the camera, gentle natural motion",
  "duration": 5,
  "resolution": "720p",
  "audio": true
}

Response

{
  "request_id": "vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Request Headers

Header Value
Content-Typeapplication/json
Cache-Controlno-cache
Ocp-Apim-Subscription-KeyYOUR_SUBSCRIPTION_KEY

Response Handling

Common status codes.

CodeMeaning
202Accepted — Request queued
Bad Request
401Unauthorized
402Insufficient Balance
403Forbidden
Too Many Requests
500Internal Server Error

Error Responses

Queue system errors and model validation errors.

Queue System Errors

// 402 — Insufficient balance
{
  "error": "Insufficient Balance",
  "message": "Your wallet does not have enough balance."
}
// 400 — Model not found
{
  "error": "Model not found",
  "message": "Model 'vidu-q3-pro' not found or is disabled"
}

Error via Status/Webhook

{
  "request_id": "vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "ERROR",
  "model_id": "vidu-q3-pro",
  "error": "Description of the error",
  "output": null
}

Retrieving Results

Poll the universal status endpoint to check progress and retrieve results.

Endpoint

GET https://gateway.pixazo.ai/v2/requests/status/{request_id}
Ocp-Apim-Subscription-Key: YOUR_API_KEY

cURL Example

curl -H "Ocp-Apim-Subscription-Key: YOUR_API_KEY" \
  "https://gateway.pixazo.ai/v2/requests/status/vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

Response (Completed)

{
  "request_id": "vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "vidu-q3-pro",
  "error": null,
  "output": {
    "media_url": [
      "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/vidu-q3-pro_019dxxxx-xxxx/output.mp4"
    ],
    "media_type": "video/mp4"
  },
  "created_at": "2026-04-07T10:00:00.000Z",
  "updated_at": "2026-04-07T10:02:30.000Z",
  "completed_at": "2026-04-07T10:02:30.000Z"
}

Response Fields

FieldTypeDescription
request_idstringUnique request identifier
statusstringQUEUED, PROCESSING, COMPLETED, FAILED, or ERROR
model_idstringModel that processed the request
errorstring|nullError message if failed
output.media_urlarrayURLs to generated media (R2 CDN)
output.media_typestringMIME type of the output
created_atstringWhen request was created
completed_atstring|nullWhen request completed
polling_urlstringStatus URL (initial response only)

Status Values

StatusDescription
QUEUEDRequest accepted, waiting to be processed
PROCESSINGBeing processed by the model
COMPLETEDDone — output contains the result
FAILEDFailed — check error field
ERRORSystem error — not charged

Status Flow

QUEUED → PROCESSING → COMPLETED
                    → FAILED
                    → ERROR

Typical Workflow

  1. Send a generate request to the API endpoint
  2. Save the request_id from the response
  3. Poll every 5-10 seconds: GET /v2/requests/status/{request_id}
  4. When status is "COMPLETED", download from output.media_url

Tip: Use X-Webhook-URL header to get a callback instead of polling.

Examples

Common ways to call POST /vidu-q3-pro/v1/image-to-video. Each submit returns a request_id — poll GET /v2/requests/status/{request_id} until COMPLETED.

Animate a Still Image — Bring a single image to life with a motion prompt.
const res = await fetch("https://gateway.pixazo.ai/vidu-q3-pro/v1/image-to-video", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY",
  },
  body: JSON.stringify({
    start_image: "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    prompt: "the camera slowly pushes in as gentle wind moves through the scene",
    duration: 5,
    resolution: "720p",
  }),
});

const { request_id } = await res.json() as { request_id: string };
// Poll GET /v2/requests/status/{request_id} until status === "COMPLETED"
curl -X POST "https://gateway.pixazo.ai/vidu-q3-pro/v1/image-to-video" \
  -H "Content-Type: application/json" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "start_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    "prompt": "the camera slowly pushes in as gentle wind moves through the scene",
    "duration": 5,
    "resolution": "720p"
  }'
Silent Animation — Animate an image without audio.
const res = await fetch("https://gateway.pixazo.ai/vidu-q3-pro/v1/image-to-video", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY",
  },
  body: JSON.stringify({
    start_image: "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    audio: false,
    prompt: "subtle parallax motion, leaves drifting in the breeze",
    duration: 5,
    resolution: "720p",
  }),
});

const { request_id } = await res.json() as { request_id: string };
// Poll GET /v2/requests/status/{request_id} until status === "COMPLETED"
curl -X POST "https://gateway.pixazo.ai/vidu-q3-pro/v1/image-to-video" \
  -H "Content-Type: application/json" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "start_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    "audio": false,
    "prompt": "subtle parallax motion, leaves drifting in the breeze",
    "duration": 5,
    "resolution": "720p"
  }'
1080p, 8-Second Clip — Higher resolution and a longer duration.
const res = await fetch("https://gateway.pixazo.ai/vidu-q3-pro/v1/image-to-video", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY",
  },
  body: JSON.stringify({
    start_image: "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    prompt: "slow cinematic dolly across the scene at golden hour",
    duration: 8,
    resolution: "1080p",
  }),
});

const { request_id } = await res.json() as { request_id: string };
// Poll GET /v2/requests/status/{request_id} until status === "COMPLETED"
curl -X POST "https://gateway.pixazo.ai/vidu-q3-pro/v1/image-to-video" \
  -H "Content-Type: application/json" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "start_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    "prompt": "slow cinematic dolly across the scene at golden hour",
    "duration": 8,
    "resolution": "1080p"
  }'

Vidu Q3 Pro API Pricing

ResolutionPrice (USD)
540p (per second of video)$0.05
720p (per second of video)$0.125
1080p (per second of video)$0.15
Start / End Frame to Video

Vidu Q3 Pro API Documentation

https://gateway.pixazo.ai/vidu-q3-pro/v1/start-end-to-video

Authentication

All requests require an API key passed via header.

HeaderTypeRequiredDescription
Ocp-Apim-Subscription-KeystringYesYour API subscription key

Start / End Frame to Video - Vidu Q3 Pro

Request Code

POST https://gateway.pixazo.ai/vidu-q3-pro/v1/start-end-to-video
Content-Type: application/json
Cache-Control: no-cache
Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY

{
  "start_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
  "end_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f2.png"
}
import requests

url = "https://gateway.pixazo.ai/vidu-q3-pro/v1/start-end-to-video"
headers = {
    "Content-Type": "application/json",
    "Cache-Control": "no-cache",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY"
}
data = {
    "start_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    "end_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f2.png"
}

response = requests.post(url, json=data, headers=headers)
print(response.json())
const url = 'https://gateway.pixazo.ai/vidu-q3-pro/v1/start-end-to-video';
const headers = {
  'Content-Type': 'application/json',
  'Cache-Control': 'no-cache',
  'Ocp-Apim-Subscription-Key': 'YOUR_SUBSCRIPTION_KEY'
};
const data = {
  start_image: 'https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png',
  end_image: 'https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f2.png'
};

fetch(url, {
  method: 'POST',
  headers: headers,
  body: JSON.stringify(data)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
curl -v -X POST "https://gateway.pixazo.ai/vidu-q3-pro/v1/start-end-to-video" \
  -H "Content-Type: application/json" \
  -H "Cache-Control: no-cache" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "start_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    "end_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f2.png"
  }'

Output

{
  "request_id": "vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Webhook (Optional)

Add the X-Webhook-URL header to your submit request to receive a POST callback when the job completes — no polling required.

Using curl? These are HTTP request headers — pass each with -H, e.g. -H "X-Webhook-URL: https://your-server.com/webhook/callback". Do not paste them as bare lines, and end every line of a multi-line command with \.

Webhook Headers

HeaderRequiredDefaultDescription
X-Webhook-URLYes (to enable)—HTTPS endpoint on your server that will receive the POST callback. Must respond 2xx within a few seconds (process async if needed).
X-Webhook-ModeNoterminalterminal — fires once at the final status (COMPLETED/FAILED/ERROR). sync — fires on every poll cycle plus the terminal event, and caps the queue’s polling delay at 15s for tighter progress updates.

Example: enable webhook

X-Webhook-URL: https://your-server.com/webhook/callback
X-Webhook-Mode: terminal

Callback Payload

Your endpoint receives a POST application/json with the same shape as the GET /v2/requests/status/{request_id} response. Example terminal callback (mode terminal):

{
  "request_id": "vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "vidu-q3-pro",
  "error": null,
  "output": {
    "media_url": [
      "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/output.mp4"
    ],
    "media_type": "video/mp4"
  },
  "created_at": "2026-05-22T13:17:32.110Z",
  "updated_at": "2026-05-22 13:19:23",
  "completed_at": "2026-05-22 13:19:23"
}

Failure callback shape

{
  "request_id": "vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "ERROR",
  "model_id": "vidu-q3-pro",
  "error": "Description of the error",
  "output": null,
  "created_at": "...",
  "updated_at": "...",
  "completed_at": "..."
}

Delivery semantics

  • terminal mode (default) — exactly one POST when the request reaches a terminal status. No callback during PROCESSING.
  • sync mode — POST on every status poll (with delay capped at ~15s) plus a final POST at terminal status. Use when you want progress updates.
  • Idempotency — use request_id as your idempotency key. Network retries can deliver the same callback more than once; your handler must tolerate duplicates.
  • Response — respond 200 OK within a few seconds. The queue does not block on slow handlers, but persistent failures may stop further deliveries.
  • HTTPS required — plain http:// URLs are rejected.

Request Parameters - Start / End Frame to Video

Parameter Required Type Default Allowed values / range Description
start_imageYesstring—public URL or data:image/...;base64,…First frame of the video.
end_imageYesstring—public URL or data:image/...;base64,…Last frame. Must be used together with start_image.
promptNostring—≤ 5000 charsOptional text guiding the motion / scene.
durationNointeger51–16 (seconds)Video length in seconds. Billed per second.
resolutionNostring"720p""540p", "720p", "1080p"Output resolution. Billed per second by resolution.
audioNobooleantruetrue, falseEnable audio-video sync. false outputs a silent video.

Content Item Types & Limits

TypeMaxFormat / SizeDescription
image1JPG, PNG, WEBP · < 50 MBStart / end frame image.

Example Request

{
  "start_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
  "end_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f2.png",
  "prompt": "a smooth, natural transition between the two frames",
  "duration": 5,
  "resolution": "720p",
  "audio": true
}

Response

{
  "request_id": "vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Request Headers

Header Value
Content-Typeapplication/json
Cache-Controlno-cache
Ocp-Apim-Subscription-KeyYOUR_SUBSCRIPTION_KEY

Response Handling

Common status codes.

CodeMeaning
202Accepted — Request queued
Bad Request
401Unauthorized
402Insufficient Balance
403Forbidden
Too Many Requests
500Internal Server Error

Error Responses

Queue system errors and model validation errors.

Queue System Errors

// 402 — Insufficient balance
{
  "error": "Insufficient Balance",
  "message": "Your wallet does not have enough balance."
}
// 400 — Model not found
{
  "error": "Model not found",
  "message": "Model 'vidu-q3-pro' not found or is disabled"
}

Error via Status/Webhook

{
  "request_id": "vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "ERROR",
  "model_id": "vidu-q3-pro",
  "error": "Description of the error",
  "output": null
}

Retrieving Results

Poll the universal status endpoint to check progress and retrieve results.

Endpoint

GET https://gateway.pixazo.ai/v2/requests/status/{request_id}
Ocp-Apim-Subscription-Key: YOUR_API_KEY

cURL Example

curl -H "Ocp-Apim-Subscription-Key: YOUR_API_KEY" \
  "https://gateway.pixazo.ai/v2/requests/status/vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

Response (Completed)

{
  "request_id": "vidu-q3-pro_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "vidu-q3-pro",
  "error": null,
  "output": {
    "media_url": [
      "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/vidu-q3-pro_019dxxxx-xxxx/output.mp4"
    ],
    "media_type": "video/mp4"
  },
  "created_at": "2026-04-07T10:00:00.000Z",
  "updated_at": "2026-04-07T10:02:30.000Z",
  "completed_at": "2026-04-07T10:02:30.000Z"
}

Response Fields

FieldTypeDescription
request_idstringUnique request identifier
statusstringQUEUED, PROCESSING, COMPLETED, FAILED, or ERROR
model_idstringModel that processed the request
errorstring|nullError message if failed
output.media_urlarrayURLs to generated media (R2 CDN)
output.media_typestringMIME type of the output
created_atstringWhen request was created
completed_atstring|nullWhen request completed
polling_urlstringStatus URL (initial response only)

Status Values

StatusDescription
QUEUEDRequest accepted, waiting to be processed
PROCESSINGBeing processed by the model
COMPLETEDDone — output contains the result
FAILEDFailed — check error field
ERRORSystem error — not charged

Status Flow

QUEUED → PROCESSING → COMPLETED
                    → FAILED
                    → ERROR

Typical Workflow

  1. Send a generate request to the API endpoint
  2. Save the request_id from the response
  3. Poll every 5-10 seconds: GET /v2/requests/status/{request_id}
  4. When status is "COMPLETED", download from output.media_url

Tip: Use X-Webhook-URL header to get a callback instead of polling.

Examples

Common ways to call POST /vidu-q3-pro/v1/start-end-to-video. Each submit returns a request_id — poll GET /v2/requests/status/{request_id} until COMPLETED.

Frame-to-Frame Transition — Generate a video that morphs from a start frame to an end frame.
const res = await fetch("https://gateway.pixazo.ai/vidu-q3-pro/v1/start-end-to-video", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY",
  },
  body: JSON.stringify({
    start_image: "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    end_image: "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f2.png",
    prompt: "a smooth, natural transition between the two frames",
    duration: 5,
    resolution: "720p",
  }),
});

const { request_id } = await res.json() as { request_id: string };
// Poll GET /v2/requests/status/{request_id} until status === "COMPLETED"
curl -X POST "https://gateway.pixazo.ai/vidu-q3-pro/v1/start-end-to-video" \
  -H "Content-Type: application/json" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "start_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    "end_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f2.png",
    "prompt": "a smooth, natural transition between the two frames",
    "duration": 5,
    "resolution": "720p"
  }'
Silent Transition — Frame-to-frame transition without audio.
const res = await fetch("https://gateway.pixazo.ai/vidu-q3-pro/v1/start-end-to-video", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY",
  },
  body: JSON.stringify({
    start_image: "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    end_image: "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f2.png",
    audio: false,
    prompt: "seamless dissolve from the first scene to the last",
    duration: 5,
    resolution: "720p",
  }),
});

const { request_id } = await res.json() as { request_id: string };
// Poll GET /v2/requests/status/{request_id} until status === "COMPLETED"
curl -X POST "https://gateway.pixazo.ai/vidu-q3-pro/v1/start-end-to-video" \
  -H "Content-Type: application/json" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "start_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    "end_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f2.png",
    "audio": false,
    "prompt": "seamless dissolve from the first scene to the last",
    "duration": 5,
    "resolution": "720p"
  }'
1080p, 8-Second Transition — Higher resolution and a longer transition.
const res = await fetch("https://gateway.pixazo.ai/vidu-q3-pro/v1/start-end-to-video", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY",
  },
  body: JSON.stringify({
    start_image: "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    end_image: "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f2.png",
    prompt: "cinematic morph with dynamic camera movement",
    duration: 8,
    resolution: "1080p",
  }),
});

const { request_id } = await res.json() as { request_id: string };
// Poll GET /v2/requests/status/{request_id} until status === "COMPLETED"
curl -X POST "https://gateway.pixazo.ai/vidu-q3-pro/v1/start-end-to-video" \
  -H "Content-Type: application/json" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "start_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    "end_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f2.png",
    "prompt": "cinematic morph with dynamic camera movement",
    "duration": 8,
    "resolution": "1080p"
  }'

Vidu Q3 Pro API Pricing

ResolutionPrice (USD)
540p (per second of video)$0.05
720p (per second of video)$0.125
1080p (per second of video)$0.15
3. Vidu Q3 Turbo

Vidu Q3 Turbo API Documentation

https://gateway.pixazo.ai/vidu-q3-turbo/v1/text-to-video

Authentication

All requests require an API key passed via header.

HeaderTypeRequiredDescription
Ocp-Apim-Subscription-KeystringYesYour API subscription key

Text to Video - Vidu Q3 Turbo

Request Code

POST https://gateway.pixazo.ai/vidu-q3-turbo/v1/text-to-video
Content-Type: application/json
Cache-Control: no-cache
Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY

{
  "prompt": "A cat lazily stretching on a sunlit windowsill"
}
import requests

url = "https://gateway.pixazo.ai/vidu-q3-turbo/v1/text-to-video"
headers = {
    "Content-Type": "application/json",
    "Cache-Control": "no-cache",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY"
}
data = {
    "prompt": "A cat lazily stretching on a sunlit windowsill"
}

response = requests.post(url, json=data, headers=headers)
print(response.json())
const url = 'https://gateway.pixazo.ai/vidu-q3-turbo/v1/text-to-video';
const headers = {
  'Content-Type': 'application/json',
  'Cache-Control': 'no-cache',
  'Ocp-Apim-Subscription-Key': 'YOUR_SUBSCRIPTION_KEY'
};
const data = {
  prompt: 'A cat lazily stretching on a sunlit windowsill'
};

fetch(url, {
  method: 'POST',
  headers: headers,
  body: JSON.stringify(data)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
curl -v -X POST "https://gateway.pixazo.ai/vidu-q3-turbo/v1/text-to-video" \
  -H "Content-Type: application/json" \
  -H "Cache-Control: no-cache" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "prompt": "A cat lazily stretching on a sunlit windowsill"
  }'

Output

{
  "request_id": "vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Webhook (Optional)

Add the X-Webhook-URL header to your submit request to receive a POST callback when the job completes — no polling required.

Using curl? These are HTTP request headers — pass each with -H, e.g. -H "X-Webhook-URL: https://your-server.com/webhook/callback". Do not paste them as bare lines, and end every line of a multi-line command with \.

Webhook Headers

HeaderRequiredDefaultDescription
X-Webhook-URLYes (to enable)—HTTPS endpoint on your server that will receive the POST callback. Must respond 2xx within a few seconds (process async if needed).
X-Webhook-ModeNoterminalterminal — fires once at the final status (COMPLETED/FAILED/ERROR). sync — fires on every poll cycle plus the terminal event, and caps the queue’s polling delay at 15s for tighter progress updates.

Example: enable webhook

X-Webhook-URL: https://your-server.com/webhook/callback
X-Webhook-Mode: terminal

Callback Payload

Your endpoint receives a POST application/json with the same shape as the GET /v2/requests/status/{request_id} response. Example terminal callback (mode terminal):

{
  "request_id": "vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "vidu-q3-turbo",
  "error": null,
  "output": {
    "media_url": [
      "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/output.mp4"
    ],
    "media_type": "video/mp4"
  },
  "created_at": "2026-05-22T13:17:32.110Z",
  "updated_at": "2026-05-22 13:19:23",
  "completed_at": "2026-05-22 13:19:23"
}

Failure callback shape

{
  "request_id": "vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "ERROR",
  "model_id": "vidu-q3-turbo",
  "error": "Description of the error",
  "output": null,
  "created_at": "...",
  "updated_at": "...",
  "completed_at": "..."
}

Delivery semantics

  • terminal mode (default) — exactly one POST when the request reaches a terminal status. No callback during PROCESSING.
  • sync mode — POST on every status poll (with delay capped at ~15s) plus a final POST at terminal status. Use when you want progress updates.
  • Idempotency — use request_id as your idempotency key. Network retries can deliver the same callback more than once; your handler must tolerate duplicates.
  • Response — respond 200 OK within a few seconds. The queue does not block on slow handlers, but persistent failures may stop further deliveries.
  • HTTPS required — plain http:// URLs are rejected.

Request Parameters - Text to Video

Parameter Required Type Default Allowed values / range Description
promptYesstring—non-empty; ≤ 5000 charsText description of the video to generate.
durationNointeger51–16 (seconds)Video length in seconds. Billed per second.
resolutionNostring"720p""540p", "720p", "1080p"Output resolution. Billed per second by resolution.
aspect_ratioNostring"16:9""16:9", "9:16", "3:4", "4:3", "1:1"Output aspect ratio (text-to-video only).
audioNobooleantruetrue, falseEnable audio-video sync. false outputs a silent video.

Example Request

{
  "prompt": "A cat lazily stretching on a sunlit windowsill",
  "duration": 5,
  "resolution": "720p",
  "aspect_ratio": "16:9",
  "audio": true
}

Response

{
  "request_id": "vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Request Headers

Header Value
Content-Typeapplication/json
Cache-Controlno-cache
Ocp-Apim-Subscription-KeyYOUR_SUBSCRIPTION_KEY

Response Handling

Common status codes.

CodeMeaning
202Accepted — Request queued
Bad Request
401Unauthorized
402Insufficient Balance
403Forbidden
Too Many Requests
500Internal Server Error

Error Responses

Queue system errors and model validation errors.

Queue System Errors

// 402 — Insufficient balance
{
  "error": "Insufficient Balance",
  "message": "Your wallet does not have enough balance."
}
// 400 — Model not found
{
  "error": "Model not found",
  "message": "Model 'vidu-q3-turbo' not found or is disabled"
}

Error via Status/Webhook

{
  "request_id": "vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "ERROR",
  "model_id": "vidu-q3-turbo",
  "error": "Description of the error",
  "output": null
}

Retrieving Results

Poll the universal status endpoint to check progress and retrieve results.

Endpoint

GET https://gateway.pixazo.ai/v2/requests/status/{request_id}
Ocp-Apim-Subscription-Key: YOUR_API_KEY

cURL Example

curl -H "Ocp-Apim-Subscription-Key: YOUR_API_KEY" \
  "https://gateway.pixazo.ai/v2/requests/status/vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

Response (Completed)

{
  "request_id": "vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "vidu-q3-turbo",
  "error": null,
  "output": {
    "media_url": [
      "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/vidu-q3-turbo_019dxxxx-xxxx/output.mp4"
    ],
    "media_type": "video/mp4"
  },
  "created_at": "2026-04-07T10:00:00.000Z",
  "updated_at": "2026-04-07T10:02:30.000Z",
  "completed_at": "2026-04-07T10:02:30.000Z"
}

Response Fields

FieldTypeDescription
request_idstringUnique request identifier
statusstringQUEUED, PROCESSING, COMPLETED, FAILED, or ERROR
model_idstringModel that processed the request
errorstring|nullError message if failed
output.media_urlarrayURLs to generated media (R2 CDN)
output.media_typestringMIME type of the output
created_atstringWhen request was created
completed_atstring|nullWhen request completed
polling_urlstringStatus URL (initial response only)

Status Values

StatusDescription
QUEUEDRequest accepted, waiting to be processed
PROCESSINGBeing processed by the model
COMPLETEDDone — output contains the result
FAILEDFailed — check error field
ERRORSystem error — not charged

Status Flow

QUEUED → PROCESSING → COMPLETED
                    → FAILED
                    → ERROR

Typical Workflow

  1. Send a generate request to the API endpoint
  2. Save the request_id from the response
  3. Poll every 5-10 seconds: GET /v2/requests/status/{request_id}
  4. When status is "COMPLETED", download from output.media_url

Tip: Use X-Webhook-URL header to get a callback instead of polling.

Examples

Common ways to call POST /vidu-q3-turbo/v1/text-to-video. Each submit returns a request_id — poll GET /v2/requests/status/{request_id} until COMPLETED.

Portrait Aspect Ratio — Vertical video for social media.
const res = await fetch("https://gateway.pixazo.ai/vidu-q3-turbo/v1/text-to-video", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY",
  },
  body: JSON.stringify({
    prompt: "A busy street in Tokyo at night with neon signs reflecting on wet pavement, rain falling",
    aspect_ratio: "9:16",
    duration: 5,
    resolution: "720p",
  }),
});

const { request_id } = await res.json() as { request_id: string };
// Poll GET /v2/requests/status/{request_id} until status === "COMPLETED"
curl -X POST "https://gateway.pixazo.ai/vidu-q3-turbo/v1/text-to-video" \
  -H "Content-Type: application/json" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "prompt": "A busy street in Tokyo at night with neon signs reflecting on wet pavement, rain falling",
    "aspect_ratio": "9:16",
    "duration": 5,
    "resolution": "720p"
  }'
Silent Video — Generate video without audio.
const res = await fetch("https://gateway.pixazo.ai/vidu-q3-turbo/v1/text-to-video", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY",
  },
  body: JSON.stringify({
    audio: false,
    prompt: "Abstract paint swirls slowly mixing in water, vivid blues and golds",
    duration: 8,
    resolution: "720p",
  }),
});

const { request_id } = await res.json() as { request_id: string };
// Poll GET /v2/requests/status/{request_id} until status === "COMPLETED"
curl -X POST "https://gateway.pixazo.ai/vidu-q3-turbo/v1/text-to-video" \
  -H "Content-Type: application/json" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "audio": false,
    "prompt": "Abstract paint swirls slowly mixing in water, vivid blues and golds",
    "duration": 8,
    "resolution": "720p"
  }'
Square Format — Square video for product demos or social posts.
const res = await fetch("https://gateway.pixazo.ai/vidu-q3-turbo/v1/text-to-video", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY",
  },
  body: JSON.stringify({
    prompt: "A sleek wireless headphone rotating on a pedestal with soft studio lighting and a white background",
    aspect_ratio: "1:1",
    duration: 5,
    resolution: "720p",
  }),
});

const { request_id } = await res.json() as { request_id: string };
// Poll GET /v2/requests/status/{request_id} until status === "COMPLETED"
curl -X POST "https://gateway.pixazo.ai/vidu-q3-turbo/v1/text-to-video" \
  -H "Content-Type: application/json" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "prompt": "A sleek wireless headphone rotating on a pedestal with soft studio lighting and a white background",
    "aspect_ratio": "1:1",
    "duration": 5,
    "resolution": "720p"
  }'

Vidu Q3 Turbo API Pricing

ResolutionPrice (USD)
540p (per second of video)$0.04
720p (per second of video)$0.06
1080p (per second of video)$0.07
Image to Video

Vidu Q3 Turbo API Documentation

https://gateway.pixazo.ai/vidu-q3-turbo/v1/image-to-video

Authentication

All requests require an API key passed via header.

HeaderTypeRequiredDescription
Ocp-Apim-Subscription-KeystringYesYour API subscription key

Image to Video - Vidu Q3 Turbo

Request Code

POST https://gateway.pixazo.ai/vidu-q3-turbo/v1/image-to-video
Content-Type: application/json
Cache-Control: no-cache
Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY

{
  "start_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
  "prompt": "the subject turns toward the camera, gentle natural motion"
}
import requests

url = "https://gateway.pixazo.ai/vidu-q3-turbo/v1/image-to-video"
headers = {
    "Content-Type": "application/json",
    "Cache-Control": "no-cache",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY"
}
data = {
    "start_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    "prompt": "the subject turns toward the camera, gentle natural motion"
}

response = requests.post(url, json=data, headers=headers)
print(response.json())
const url = 'https://gateway.pixazo.ai/vidu-q3-turbo/v1/image-to-video';
const headers = {
  'Content-Type': 'application/json',
  'Cache-Control': 'no-cache',
  'Ocp-Apim-Subscription-Key': 'YOUR_SUBSCRIPTION_KEY'
};
const data = {
  start_image: 'https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png',
  prompt: 'the subject turns toward the camera, gentle natural motion'
};

fetch(url, {
  method: 'POST',
  headers: headers,
  body: JSON.stringify(data)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
curl -v -X POST "https://gateway.pixazo.ai/vidu-q3-turbo/v1/image-to-video" \
  -H "Content-Type: application/json" \
  -H "Cache-Control: no-cache" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "start_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    "prompt": "the subject turns toward the camera, gentle natural motion"
  }'

Output

{
  "request_id": "vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Webhook (Optional)

Add the X-Webhook-URL header to your submit request to receive a POST callback when the job completes — no polling required.

Using curl? These are HTTP request headers — pass each with -H, e.g. -H "X-Webhook-URL: https://your-server.com/webhook/callback". Do not paste them as bare lines, and end every line of a multi-line command with \.

Webhook Headers

HeaderRequiredDefaultDescription
X-Webhook-URLYes (to enable)—HTTPS endpoint on your server that will receive the POST callback. Must respond 2xx within a few seconds (process async if needed).
X-Webhook-ModeNoterminalterminal — fires once at the final status (COMPLETED/FAILED/ERROR). sync — fires on every poll cycle plus the terminal event, and caps the queue’s polling delay at 15s for tighter progress updates.

Example: enable webhook

X-Webhook-URL: https://your-server.com/webhook/callback
X-Webhook-Mode: terminal

Callback Payload

Your endpoint receives a POST application/json with the same shape as the GET /v2/requests/status/{request_id} response. Example terminal callback (mode terminal):

{
  "request_id": "vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "vidu-q3-turbo",
  "error": null,
  "output": {
    "media_url": [
      "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/output.mp4"
    ],
    "media_type": "video/mp4"
  },
  "created_at": "2026-05-22T13:17:32.110Z",
  "updated_at": "2026-05-22 13:19:23",
  "completed_at": "2026-05-22 13:19:23"
}

Failure callback shape

{
  "request_id": "vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "ERROR",
  "model_id": "vidu-q3-turbo",
  "error": "Description of the error",
  "output": null,
  "created_at": "...",
  "updated_at": "...",
  "completed_at": "..."
}

Delivery semantics

  • terminal mode (default) — exactly one POST when the request reaches a terminal status. No callback during PROCESSING.
  • sync mode — POST on every status poll (with delay capped at ~15s) plus a final POST at terminal status. Use when you want progress updates.
  • Idempotency — use request_id as your idempotency key. Network retries can deliver the same callback more than once; your handler must tolerate duplicates.
  • Response — respond 200 OK within a few seconds. The queue does not block on slow handlers, but persistent failures may stop further deliveries.
  • HTTPS required — plain http:// URLs are rejected.

Request Parameters - Image to Video

Parameter Required Type Default Allowed values / range Description
start_imageYesstring—public URL or data:image/...;base64,…Starting frame to animate.
promptNostring—≤ 5000 charsOptional text guiding the motion / scene.
durationNointeger51–16 (seconds)Video length in seconds. Billed per second.
resolutionNostring"720p""540p", "720p", "1080p"Output resolution. Billed per second by resolution.
audioNobooleantruetrue, falseEnable audio-video sync. false outputs a silent video.

Content Item Types & Limits

TypeMaxFormat / SizeDescription
image1JPG, PNG, WEBP · < 50 MBStart image.

Example Request

{
  "start_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
  "prompt": "the subject turns toward the camera, gentle natural motion",
  "duration": 5,
  "resolution": "720p",
  "audio": true
}

Response

{
  "request_id": "vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Request Headers

Header Value
Content-Typeapplication/json
Cache-Controlno-cache
Ocp-Apim-Subscription-KeyYOUR_SUBSCRIPTION_KEY

Response Handling

Common status codes.

CodeMeaning
202Accepted — Request queued
Bad Request
401Unauthorized
402Insufficient Balance
403Forbidden
Too Many Requests
500Internal Server Error

Error Responses

Queue system errors and model validation errors.

Queue System Errors

// 402 — Insufficient balance
{
  "error": "Insufficient Balance",
  "message": "Your wallet does not have enough balance."
}
// 400 — Model not found
{
  "error": "Model not found",
  "message": "Model 'vidu-q3-turbo' not found or is disabled"
}

Error via Status/Webhook

{
  "request_id": "vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "ERROR",
  "model_id": "vidu-q3-turbo",
  "error": "Description of the error",
  "output": null
}

Retrieving Results

Poll the universal status endpoint to check progress and retrieve results.

Endpoint

GET https://gateway.pixazo.ai/v2/requests/status/{request_id}
Ocp-Apim-Subscription-Key: YOUR_API_KEY

cURL Example

curl -H "Ocp-Apim-Subscription-Key: YOUR_API_KEY" \
  "https://gateway.pixazo.ai/v2/requests/status/vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

Response (Completed)

{
  "request_id": "vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "vidu-q3-turbo",
  "error": null,
  "output": {
    "media_url": [
      "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/vidu-q3-turbo_019dxxxx-xxxx/output.mp4"
    ],
    "media_type": "video/mp4"
  },
  "created_at": "2026-04-07T10:00:00.000Z",
  "updated_at": "2026-04-07T10:02:30.000Z",
  "completed_at": "2026-04-07T10:02:30.000Z"
}

Response Fields

FieldTypeDescription
request_idstringUnique request identifier
statusstringQUEUED, PROCESSING, COMPLETED, FAILED, or ERROR
model_idstringModel that processed the request
errorstring|nullError message if failed
output.media_urlarrayURLs to generated media (R2 CDN)
output.media_typestringMIME type of the output
created_atstringWhen request was created
completed_atstring|nullWhen request completed
polling_urlstringStatus URL (initial response only)

Status Values

StatusDescription
QUEUEDRequest accepted, waiting to be processed
PROCESSINGBeing processed by the model
COMPLETEDDone — output contains the result
FAILEDFailed — check error field
ERRORSystem error — not charged

Status Flow

QUEUED → PROCESSING → COMPLETED
                    → FAILED
                    → ERROR

Typical Workflow

  1. Send a generate request to the API endpoint
  2. Save the request_id from the response
  3. Poll every 5-10 seconds: GET /v2/requests/status/{request_id}
  4. When status is "COMPLETED", download from output.media_url

Tip: Use X-Webhook-URL header to get a callback instead of polling.

Examples

Common ways to call POST /vidu-q3-turbo/v1/image-to-video. Each submit returns a request_id — poll GET /v2/requests/status/{request_id} until COMPLETED.

Animate a Still Image — Bring a single image to life with a motion prompt.
const res = await fetch("https://gateway.pixazo.ai/vidu-q3-turbo/v1/image-to-video", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY",
  },
  body: JSON.stringify({
    start_image: "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    prompt: "the camera slowly pushes in as gentle wind moves through the scene",
    duration: 5,
    resolution: "720p",
  }),
});

const { request_id } = await res.json() as { request_id: string };
// Poll GET /v2/requests/status/{request_id} until status === "COMPLETED"
curl -X POST "https://gateway.pixazo.ai/vidu-q3-turbo/v1/image-to-video" \
  -H "Content-Type: application/json" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "start_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    "prompt": "the camera slowly pushes in as gentle wind moves through the scene",
    "duration": 5,
    "resolution": "720p"
  }'
Silent Animation — Animate an image without audio.
const res = await fetch("https://gateway.pixazo.ai/vidu-q3-turbo/v1/image-to-video", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY",
  },
  body: JSON.stringify({
    start_image: "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    audio: false,
    prompt: "subtle parallax motion, leaves drifting in the breeze",
    duration: 5,
    resolution: "720p",
  }),
});

const { request_id } = await res.json() as { request_id: string };
// Poll GET /v2/requests/status/{request_id} until status === "COMPLETED"
curl -X POST "https://gateway.pixazo.ai/vidu-q3-turbo/v1/image-to-video" \
  -H "Content-Type: application/json" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "start_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    "audio": false,
    "prompt": "subtle parallax motion, leaves drifting in the breeze",
    "duration": 5,
    "resolution": "720p"
  }'
1080p, 8-Second Clip — Higher resolution and a longer duration.
const res = await fetch("https://gateway.pixazo.ai/vidu-q3-turbo/v1/image-to-video", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY",
  },
  body: JSON.stringify({
    start_image: "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    prompt: "slow cinematic dolly across the scene at golden hour",
    duration: 8,
    resolution: "1080p",
  }),
});

const { request_id } = await res.json() as { request_id: string };
// Poll GET /v2/requests/status/{request_id} until status === "COMPLETED"
curl -X POST "https://gateway.pixazo.ai/vidu-q3-turbo/v1/image-to-video" \
  -H "Content-Type: application/json" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "start_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    "prompt": "slow cinematic dolly across the scene at golden hour",
    "duration": 8,
    "resolution": "1080p"
  }'

Vidu Q3 Turbo API Pricing

ResolutionPrice (USD)
540p (per second of video)$0.04
720p (per second of video)$0.06
1080p (per second of video)$0.07
Reference to Video

Vidu Q3 Turbo API Documentation

https://gateway.pixazo.ai/vidu-q3-turbo/v1/reference-to-video

Authentication

All requests require an API key passed via header.

HeaderTypeRequiredDescription
Ocp-Apim-Subscription-KeystringYesYour API subscription key

Reference to Video - Vidu Q3 Turbo

Request Code

POST https://gateway.pixazo.ai/vidu-q3-turbo/v1/reference-to-video
Content-Type: application/json
Cache-Control: no-cache
Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY

{
  "start_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
  "end_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f2.png"
}
import requests

url = "https://gateway.pixazo.ai/vidu-q3-turbo/v1/reference-to-video"
headers = {
    "Content-Type": "application/json",
    "Cache-Control": "no-cache",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY"
}
data = {
    "start_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    "end_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f2.png"
}

response = requests.post(url, json=data, headers=headers)
print(response.json())
const url = 'https://gateway.pixazo.ai/vidu-q3-turbo/v1/reference-to-video';
const headers = {
  'Content-Type': 'application/json',
  'Cache-Control': 'no-cache',
  'Ocp-Apim-Subscription-Key': 'YOUR_SUBSCRIPTION_KEY'
};
const data = {
  start_image: 'https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png',
  end_image: 'https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f2.png'
};

fetch(url, {
  method: 'POST',
  headers: headers,
  body: JSON.stringify(data)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
curl -v -X POST "https://gateway.pixazo.ai/vidu-q3-turbo/v1/reference-to-video" \
  -H "Content-Type: application/json" \
  -H "Cache-Control: no-cache" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "start_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    "end_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f2.png"
  }'

Output

{
  "request_id": "vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Webhook (Optional)

Add the X-Webhook-URL header to your submit request to receive a POST callback when the job completes — no polling required.

Using curl? These are HTTP request headers — pass each with -H, e.g. -H "X-Webhook-URL: https://your-server.com/webhook/callback". Do not paste them as bare lines, and end every line of a multi-line command with \.

Webhook Headers

HeaderRequiredDefaultDescription
X-Webhook-URLYes (to enable)—HTTPS endpoint on your server that will receive the POST callback. Must respond 2xx within a few seconds (process async if needed).
X-Webhook-ModeNoterminalterminal — fires once at the final status (COMPLETED/FAILED/ERROR). sync — fires on every poll cycle plus the terminal event, and caps the queue’s polling delay at 15s for tighter progress updates.

Example: enable webhook

X-Webhook-URL: https://your-server.com/webhook/callback
X-Webhook-Mode: terminal

Callback Payload

Your endpoint receives a POST application/json with the same shape as the GET /v2/requests/status/{request_id} response. Example terminal callback (mode terminal):

{
  "request_id": "vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "vidu-q3-turbo",
  "error": null,
  "output": {
    "media_url": [
      "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/output.mp4"
    ],
    "media_type": "video/mp4"
  },
  "created_at": "2026-05-22T13:17:32.110Z",
  "updated_at": "2026-05-22 13:19:23",
  "completed_at": "2026-05-22 13:19:23"
}

Failure callback shape

{
  "request_id": "vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "ERROR",
  "model_id": "vidu-q3-turbo",
  "error": "Description of the error",
  "output": null,
  "created_at": "...",
  "updated_at": "...",
  "completed_at": "..."
}

Delivery semantics

  • terminal mode (default) — exactly one POST when the request reaches a terminal status. No callback during PROCESSING.
  • sync mode — POST on every status poll (with delay capped at ~15s) plus a final POST at terminal status. Use when you want progress updates.
  • Idempotency — use request_id as your idempotency key. Network retries can deliver the same callback more than once; your handler must tolerate duplicates.
  • Response — respond 200 OK within a few seconds. The queue does not block on slow handlers, but persistent failures may stop further deliveries.
  • HTTPS required — plain http:// URLs are rejected.

Request Parameters - Reference to Video

Parameter Required Type Default Allowed values / range Description
start_imageYesstring—public URL or data:image/...;base64,…First frame of the video.
end_imageYesstring—public URL or data:image/...;base64,…Last frame. Must be used together with start_image.
promptNostring—≤ 5000 charsOptional text guiding the motion / scene.
durationNointeger51–16 (seconds)Video length in seconds. Billed per second.
resolutionNostring"720p""540p", "720p", "1080p"Output resolution. Billed per second by resolution.
audioNobooleantruetrue, falseEnable audio-video sync. false outputs a silent video.

Content Item Types & Limits

TypeMaxFormat / SizeDescription
image1JPG, PNG, WEBP · < 50 MBStart / end frame image.

Example Request

{
  "start_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
  "end_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f2.png",
  "prompt": "a smooth, natural transition between the two frames",
  "duration": 5,
  "resolution": "720p",
  "audio": true
}

Response

{
  "request_id": "vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Request Headers

Header Value
Content-Typeapplication/json
Cache-Controlno-cache
Ocp-Apim-Subscription-KeyYOUR_SUBSCRIPTION_KEY

Response Handling

Common status codes.

CodeMeaning
202Accepted — Request queued
Bad Request
401Unauthorized
402Insufficient Balance
403Forbidden
Too Many Requests
500Internal Server Error

Error Responses

Queue system errors and model validation errors.

Queue System Errors

// 402 — Insufficient balance
{
  "error": "Insufficient Balance",
  "message": "Your wallet does not have enough balance."
}
// 400 — Model not found
{
  "error": "Model not found",
  "message": "Model 'vidu-q3-turbo' not found or is disabled"
}

Error via Status/Webhook

{
  "request_id": "vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "ERROR",
  "model_id": "vidu-q3-turbo",
  "error": "Description of the error",
  "output": null
}

Retrieving Results

Poll the universal status endpoint to check progress and retrieve results.

Endpoint

GET https://gateway.pixazo.ai/v2/requests/status/{request_id}
Ocp-Apim-Subscription-Key: YOUR_API_KEY

cURL Example

curl -H "Ocp-Apim-Subscription-Key: YOUR_API_KEY" \
  "https://gateway.pixazo.ai/v2/requests/status/vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

Response (Completed)

{
  "request_id": "vidu-q3-turbo_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "vidu-q3-turbo",
  "error": null,
  "output": {
    "media_url": [
      "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/vidu-q3-turbo_019dxxxx-xxxx/output.mp4"
    ],
    "media_type": "video/mp4"
  },
  "created_at": "2026-04-07T10:00:00.000Z",
  "updated_at": "2026-04-07T10:02:30.000Z",
  "completed_at": "2026-04-07T10:02:30.000Z"
}

Response Fields

FieldTypeDescription
request_idstringUnique request identifier
statusstringQUEUED, PROCESSING, COMPLETED, FAILED, or ERROR
model_idstringModel that processed the request
errorstring|nullError message if failed
output.media_urlarrayURLs to generated media (R2 CDN)
output.media_typestringMIME type of the output
created_atstringWhen request was created
completed_atstring|nullWhen request completed
polling_urlstringStatus URL (initial response only)

Status Values

StatusDescription
QUEUEDRequest accepted, waiting to be processed
PROCESSINGBeing processed by the model
COMPLETEDDone — output contains the result
FAILEDFailed — check error field
ERRORSystem error — not charged

Status Flow

QUEUED → PROCESSING → COMPLETED
                    → FAILED
                    → ERROR

Typical Workflow

  1. Send a generate request to the API endpoint
  2. Save the request_id from the response
  3. Poll every 5-10 seconds: GET /v2/requests/status/{request_id}
  4. When status is "COMPLETED", download from output.media_url

Tip: Use X-Webhook-URL header to get a callback instead of polling.

Examples

Common ways to call POST /vidu-q3-turbo/v1/reference-to-video. Each submit returns a request_id — poll GET /v2/requests/status/{request_id} until COMPLETED.

Frame-to-Frame Transition — Generate a video that morphs from a start frame to an end frame.
const res = await fetch("https://gateway.pixazo.ai/vidu-q3-turbo/v1/reference-to-video", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY",
  },
  body: JSON.stringify({
    start_image: "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    end_image: "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f2.png",
    prompt: "a smooth, natural transition between the two frames",
    duration: 5,
    resolution: "720p",
  }),
});

const { request_id } = await res.json() as { request_id: string };
// Poll GET /v2/requests/status/{request_id} until status === "COMPLETED"
curl -X POST "https://gateway.pixazo.ai/vidu-q3-turbo/v1/reference-to-video" \
  -H "Content-Type: application/json" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "start_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    "end_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f2.png",
    "prompt": "a smooth, natural transition between the two frames",
    "duration": 5,
    "resolution": "720p"
  }'
Silent Transition — Frame-to-frame transition without audio.
const res = await fetch("https://gateway.pixazo.ai/vidu-q3-turbo/v1/reference-to-video", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY",
  },
  body: JSON.stringify({
    start_image: "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    end_image: "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f2.png",
    audio: false,
    prompt: "seamless dissolve from the first scene to the last",
    duration: 5,
    resolution: "720p",
  }),
});

const { request_id } = await res.json() as { request_id: string };
// Poll GET /v2/requests/status/{request_id} until status === "COMPLETED"
curl -X POST "https://gateway.pixazo.ai/vidu-q3-turbo/v1/reference-to-video" \
  -H "Content-Type: application/json" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "start_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    "end_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f2.png",
    "audio": false,
    "prompt": "seamless dissolve from the first scene to the last",
    "duration": 5,
    "resolution": "720p"
  }'
1080p, 8-Second Transition — Higher resolution and a longer transition.
const res = await fetch("https://gateway.pixazo.ai/vidu-q3-turbo/v1/reference-to-video", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY",
  },
  body: JSON.stringify({
    start_image: "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    end_image: "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f2.png",
    prompt: "cinematic morph with dynamic camera movement",
    duration: 8,
    resolution: "1080p",
  }),
});

const { request_id } = await res.json() as { request_id: string };
// Poll GET /v2/requests/status/{request_id} until status === "COMPLETED"
curl -X POST "https://gateway.pixazo.ai/vidu-q3-turbo/v1/reference-to-video" \
  -H "Content-Type: application/json" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "start_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f1.png",
    "end_image": "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/f2.png",
    "prompt": "cinematic morph with dynamic camera movement",
    "duration": 8,
    "resolution": "1080p"
  }'

Vidu Q3 Turbo API Pricing

ResolutionPrice (USD)
540p (per second of video)$0.04
720p (per second of video)$0.06
1080p (per second of video)$0.07
4. Vidu Q3

Vidu Q3 API Documentation

https://gateway.pixazo.ai/vidu/v1/vidu-request

Authentication

All requests require an API key passed via header.

Header Type Required Description
Ocp-Apim-Subscription-Key string Yes Your API subscription key

Vidu generate request - Vidu

Request Code

POST https://gateway.pixazo.ai/vidu/v1/vidu-request
Content-Type: application/json
Cache-Control: no-cache
Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY

{
  "prompt": "A slow-motion capture of a hummingbird hovering beside a vibrant red hibiscus flower, iridescent feathers catching sunlight, shallow depth of field, garden background",
  "duration": 5,
  "aspect_ratio": "16:9",
  "resolution": "720p",
  "audio": true
}
import requests

url = "https://gateway.pixazo.ai/vidu/v1/vidu-request"
headers = {
    "Content-Type": "application/json",
    "Cache-Control": "no-cache",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY"
}
data = {
    "prompt": "A slow-motion capture of a hummingbird hovering beside a vibrant red hibiscus flower, iridescent feathers catching sunlight, shallow depth of field, garden background",
    "duration": 5,
    "aspect_ratio": "16:9",
    "resolution": "720p",
    "audio": True
}

response = requests.post(url, json=data, headers=headers)
print(response.json())
const url = 'https://gateway.pixazo.ai/vidu/v1/vidu-request';

const data = {
  prompt: 'A slow-motion capture of a hummingbird hovering beside a vibrant red hibiscus flower, iridescent feathers catching sunlight, shallow depth of field, garden background',
  duration: 5,
  aspect_ratio: '16:9',
  resolution: '720p',
  audio: true
};

fetch(url, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Cache-Control': 'no-cache',
    'Ocp-Apim-Subscription-Key': 'YOUR_SUBSCRIPTION_KEY'
  },
  body: JSON.stringify(data)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
curl -X POST "https://gateway.pixazo.ai/vidu/v1/vidu-request" \
  -H "Content-Type: application/json" \
  -H "Cache-Control: no-cache" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "prompt": "A slow-motion capture of a hummingbird hovering beside a vibrant red hibiscus flower, iridescent feathers catching sunlight, shallow depth of field, garden background",
    "duration": 5,
    "aspect_ratio": "16:9",
    "resolution": "720p",
    "audio": true
}'

Output

{
  "request_id": "vidu_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/vidu_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Webhook (Optional)

Add the X-Webhook-URL header to your submit request to receive a POST callback when the job completes — no polling required.

Using curl? These are HTTP request headers — pass each with -H, e.g. -H "X-Webhook-URL: https://your-server.com/webhook/callback". Do not paste them as bare lines, and end every line of a multi-line command with \.

Webhook Headers

HeaderRequiredDefaultDescription
X-Webhook-URLYes (to enable)—HTTPS endpoint on your server that will receive the POST callback. Must respond 2xx within a few seconds (process async if needed).
X-Webhook-ModeNoterminalterminal — fires once at the final status (COMPLETED/FAILED/ERROR). sync — fires on every poll cycle plus the terminal event, and caps the queue’s polling delay at 15s for tighter progress updates.

Example: enable webhook

X-Webhook-URL: https://your-server.com/webhook/callback
X-Webhook-Mode: terminal

Callback Payload

Your endpoint receives a POST application/json with the same shape as the GET /v2/requests/status/{request_id} response. Example terminal callback (mode terminal):

{
  "request_id": "vidu_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "vidu",
  "error": null,
  "output": {
    "media_url": [
      "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/vidu_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/output.mp4"
    ],
    "media_type": "video/mp4"
  },
  "created_at": "2026-05-22T13:17:32.110Z",
  "updated_at": "2026-05-22 13:19:23",
  "completed_at": "2026-05-22 13:19:23"
}

Failure callback shape

{
  "request_id": "vidu_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "ERROR",
  "model_id": "vidu",
  "error": "Description of the error",
  "output": null,
  "created_at": "...",
  "updated_at": "...",
  "completed_at": "..."
}

Delivery semantics

  • terminal mode (default) — exactly one POST when the request reaches a terminal status. No callback during PROCESSING.
  • sync mode — POST on every status poll (with delay capped at ~15s) plus a final POST at terminal status. Use when you want progress updates.
  • Idempotency — use request_id as your idempotency key. Network retries can deliver the same callback more than once; your handler must tolerate duplicates.
  • Response — respond 200 OK within a few seconds. The queue does not block on slow handlers, but persistent failures may stop further deliveries.
  • HTTPS required — plain http:// URLs are rejected.

Request Parameters - Vidu generate request

ParameterRequiredTypeDefaultAllowed values / rangeDescription
promptYesstring—non-empty; ≤ 2000 charsText prompt describing the video to generate.
durationNointeger51–16 (seconds)Length of the generated video in seconds.
seedNointeger—any integerRandom seed for reproducible results. Omit for a random seed.
aspect_ratioNostring"16:9""16:9", "9:16", "4:3", "3:4", "1:1"Aspect ratio of the output video.
resolutionNostring"720p""360p", "540p", "720p", "1080p"Output resolution of the generated video.
audioNobooleantruetrue, falseWhether to generate synchronized audio with the video. false outputs a silent video.

Minimum Request

{
  "prompt": "A slow-motion capture of a hummingbird hovering beside a vibrant red hibiscus flower, iridescent feathers catching sunlight, shallow depth of field, garden background",
  "duration": 5,
  "aspect_ratio": "16:9",
  "resolution": "720p",
  "audio": true
}

Full Request (all options)

{
  "prompt": "A slow-motion capture of a hummingbird hovering beside a vibrant red hibiscus flower, iridescent feathers catching sunlight, shallow depth of field, garden background",
  "duration": 5,
  "aspect_ratio": "16:9",
  "resolution": "720p",
  "audio": true
}

Response

{
  "request_id": "vidu_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/vidu_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Request Headers

Header Value
Content-Type application/json
Cache-Control no-cache
Ocp-Apim-Subscription-Key Your API subscription key

Response Handling

Common status codes for Vidu generate request.

Code Meaning
202 Accepted — Request queued
Bad Request
401 Unauthorized
403 Forbidden
404 Not Found
Too Many Requests
500 Internal Server Error

Error Responses

Queue system errors and model validation errors.

Queue System Errors

// 402 — Insufficient balance
{
  "error": "Insufficient Balance",
  "message": "Your wallet does not have enough balance."
}
// 400 — Model not found
{
  "error": "Model not found",
  "message": "Model 'vidu' not found or is disabled"
}

Error via Status/Webhook

{
  "request_id": "vidu_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "ERROR",
  "model_id": "vidu",
  "error": "Description of the error",
  "output": null
}

Retrieving Results

Poll the universal status endpoint to check progress and retrieve results.

Endpoint

GET https://gateway.pixazo.ai/v2/requests/status/{request_id}
Ocp-Apim-Subscription-Key: YOUR_API_KEY

cURL Example

curl -H "Ocp-Apim-Subscription-Key: YOUR_API_KEY" \
  "https://gateway.pixazo.ai/v2/requests/status/vidu_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

Response (Completed)

{
  "request_id": "vidu_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "vidu",
  "error": null,
  "output": {
    "media_url": [
      "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/vidu_019dxxxx-xxxx/output.ext"
    ],
    "media_type": "application/octet-stream"
  },
  "created_at": "2026-03-31T10:00:00.000Z",
  "updated_at": "2026-03-31T10:00:15.000Z",
  "completed_at": "2026-03-31T10:00:15.000Z"
}

Response Fields

FieldTypeDescription
request_idstringUnique request identifier
statusstringQUEUED, PROCESSING, COMPLETED, FAILED, or ERROR
model_idstringModel that processed the request
errorstring|nullError message if failed
output.media_urlarrayURLs to generated media (R2 CDN)
output.media_typestringMIME type of the output
created_atstringWhen request was created
completed_atstring|nullWhen request completed
polling_urlstringStatus URL (initial response only)

Status Values

StatusDescription
QUEUEDRequest accepted, waiting to be processed
PROCESSINGBeing processed by the model
COMPLETEDDone — output contains the result
FAILEDFailed — check error field
ERRORSystem error — not charged

Status Flow

QUEUED → PROCESSING → COMPLETED
                    → FAILED
                    → ERROR

Typical Workflow

  1. Send a generate request to the API endpoint
  2. Save the request_id from the response
  3. Poll every 5-10 seconds: GET /v2/requests/status/{request_id}
  4. When status is "COMPLETED", download from output.media_url

Tip: Use X-Webhook-URL header to get a callback instead of polling.

Vidu Q3 API Pricing

ResolutionPrice (USD)
360p / per second$0.07
540p / per second$0.07
720p / per second$0.154
1080p / per second$0.154
5. Vidu Q2

Vidu Q2 API Documentation

https://gateway.pixazo.ai/vidu-q2-reference-to-video-pro-api-454/v1/vidu-q2-reference-to-video-pro-api-request

Authentication

All requests require an API key passed via header.

HeaderTypeRequiredDescription
Ocp-Apim-Subscription-KeystringYesYour API subscription key

Vidu Q2 Reference to Video Pro API generate request - Vidu Q2 Reference to Video Pro API

Request Code

POST https://gateway.pixazo.ai/vidu-q2-reference-to-video-pro-api-454/v1/vidu-q2-reference-to-video-pro-api-request
Content-Type: application/json
Cache-Control: no-cache
Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY

{
  "prompt": "@Figure 1 Character Reference@Refer to the special effects, movements, and camera work of Video 1.",
  "reference_image_urls": [
    "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/images/input.jpg"
  ],
  "reference_video_urls": [
    "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/video/input-17s.mp4"
  ],
  "duration": 4,
  "resolution": "720p",
  "aspect_ratio": "16:9",
  "movement_amplitude": "auto"
}
import requests

url = "https://gateway.pixazo.ai/vidu-q2-reference-to-video-pro-api-454/v1/vidu-q2-reference-to-video-pro-api-request"
headers = {
    "Content-Type": "application/json",
    "Cache-Control": "no-cache",
    "Ocp-Apim-Subscription-Key": "YOUR_SUBSCRIPTION_KEY"
}
data = {
    "prompt": "@Figure 1 Character Reference@Refer to the special effects, movements, and camera work of Video 1.",
    "reference_image_urls": [
        "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/images/input.jpg"
    ],
    "reference_video_urls": [
        "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/video/input-17s.mp4"
    ],
    "duration": 4,
    "resolution": "720p",
    "aspect_ratio": "16:9",
    "movement_amplitude": "auto"
}

response = requests.post(url, json=data, headers=headers)
print(response.json())
const url = 'https://gateway.pixazo.ai/vidu-q2-reference-to-video-pro-api-454/v1/vidu-q2-reference-to-video-pro-api-request';

const data = {
  prompt: '@Figure 1 Character Reference@Refer to the special effects, movements, and camera work of Video 1.',
  reference_image_urls: [
    'https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/images/input.jpg'
  ],
  reference_video_urls: [
    'https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/video/input-17s.mp4'
  ],
  duration: 4,
  resolution: '720p',
  aspect_ratio: '16:9',
  movement_amplitude: 'auto'
};

fetch(url, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Cache-Control': 'no-cache',
    'Ocp-Apim-Subscription-Key': 'YOUR_SUBSCRIPTION_KEY'
  },
  body: JSON.stringify(data)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
curl -X POST "https://gateway.pixazo.ai/vidu-q2-reference-to-video-pro-api-454/v1/vidu-q2-reference-to-video-pro-api-request" \
  -H "Content-Type: application/json" \
  -H "Cache-Control: no-cache" \
  -H "Ocp-Apim-Subscription-Key: YOUR_SUBSCRIPTION_KEY" \
  --data-raw '{
    "prompt": "@Figure 1 Character Reference@Refer to the special effects, movements, and camera work of Video 1.",
    "reference_image_urls": [
      "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/images/input.jpg"
    ],
    "reference_video_urls": [
      "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/video/input-17s.mp4"
    ],
    "duration": 4,
    "resolution": "720p",
    "aspect_ratio": "16:9",
    "movement_amplitude": "auto"
  }'

Output

{
  "request_id": "vidu-q2-reference-to-video-pro-api-454_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/vidu-q2-reference-to-video-pro-api-454_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Webhook (Optional)

Add the X-Webhook-URL header to your submit request to receive a POST callback when the job completes — no polling required.

Using curl? These are HTTP request headers — pass each with -H, e.g. -H "X-Webhook-URL: https://your-server.com/webhook/callback". Do not paste them as bare lines, and end every line of a multi-line command with \.

Webhook Headers

HeaderRequiredDefaultDescription
X-Webhook-URLYes (to enable)—HTTPS endpoint on your server that will receive the POST callback. Must respond 2xx within a few seconds (process async if needed).
X-Webhook-ModeNoterminalterminal — fires once at the final status (COMPLETED/FAILED/ERROR). sync — fires on every poll cycle plus the terminal event, and caps the queue’s polling delay at 15s for tighter progress updates.

Example: enable webhook

X-Webhook-URL: https://your-server.com/webhook/callback
X-Webhook-Mode: terminal

Callback Payload

Your endpoint receives a POST application/json with the same shape as the GET /v2/requests/status/{request_id} response. Example terminal callback (mode terminal):

{
  "request_id": "vidu-q2-reference-to-video-pro-api-454_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "vidu-q2-reference-to-video-pro-api-454",
  "error": null,
  "output": {
    "media_url": [
      "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/vidu-q2-reference-to-video-pro-api-454_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/output.mp4"
    ],
    "media_type": "video/mp4"
  },
  "created_at": "2026-05-22T13:17:32.110Z",
  "updated_at": "2026-05-22 13:19:23",
  "completed_at": "2026-05-22 13:19:23"
}

Failure callback shape

{
  "request_id": "vidu-q2-reference-to-video-pro-api-454_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "ERROR",
  "model_id": "vidu-q2-reference-to-video-pro-api-454",
  "error": "Description of the error",
  "output": null,
  "created_at": "...",
  "updated_at": "...",
  "completed_at": "..."
}

Delivery semantics

  • terminal mode (default) — exactly one POST when the request reaches a terminal status. No callback during PROCESSING.
  • sync mode — POST on every status poll (with delay capped at ~15s) plus a final POST at terminal status. Use when you want progress updates.
  • Idempotency — use request_id as your idempotency key. Network retries can deliver the same callback more than once; your handler must tolerate duplicates.
  • Response — respond 200 OK within a few seconds. The queue does not block on slow handlers, but persistent failures may stop further deliveries.
  • HTTPS required — plain http:// URLs are rejected.

Request Parameters - Vidu Q2 Reference to Video Pro API generate request

ParameterRequiredTypeDefaultAllowed values / rangeDescription
promptYesstring—≤ 2000 charactersText prompt for video generation (maximum 2000 characters).
reference_image_urlsNoarray of strings[]up to 7 (or 4 if reference videos are provided)HTTPS URLs of reference images for subject appearance. Up to 4 images when reference videos are also provided; otherwise up to 7.
reference_video_urlsNoarray of strings[]up to 2HTTPS URLs of reference videos for video editing or motion reference. Supports up to 2 videos (MP4).
seedNointeger——Random seed that controls the generation's randomness. Reuse the same seed with identical settings to reproduce the same result; leave it empty for a different output each time.
durationNointeger40 (automatic), or 1–8Duration of the output video in seconds. Accepts 1–8 seconds, or 0 to let the model choose the duration automatically.
resolutionNostring720p"540p", "720p", "1080p"Output video resolution. Supported values: "540p", "720p", "1080p".
aspect_ratioNostring16:9"auto", "16:9", "9:16", "1:1", or any W:HAspect ratio of the output video.
movement_amplitudeNostringauto"auto", "small", "medium", "large"The movement amplitude of objects in the frame.
bgmNobooleanfalsetrue, falseWhether to add background music to the generated video.

Content Item Types & Limits

TypeMaxFormat / SizeDescription
reference_image_urls4JPG, PNG, WEBP · < 50 MBReference image(s), up to 4.
reference_video_urls2MP4 · < 100 MBReference video(s), up to 2.

Example Request

{
  "prompt": "@Figure 1 Character Reference@Refer to the special effects, movements, and camera work of Video 1.",
  "reference_image_urls": [
    "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/images/input.jpg"
  ],
  "reference_video_urls": [
    "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/doc-assets/video/input-17s.mp4"
  ],
  "duration": 4,
  "resolution": "720p",
  "aspect_ratio": "16:9",
  "movement_amplitude": "auto"
}

Response

{
  "request_id": "vidu-q2-reference-to-video-pro-api-454_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "QUEUED",
  "polling_url": "https://gateway.pixazo.ai/v2/requests/status/vidu-q2-reference-to-video-pro-api-454_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Request Headers

Header Value
Content-Typeapplication/json
Cache-Controlno-cache
Ocp-Apim-Subscription-KeyYOUR_SUBSCRIPTION_KEY

Response Handling

Common status codes.

CodeMeaning
202Accepted — Request queued
Bad Request
401Unauthorized
402Insufficient Balance
403Forbidden
Too Many Requests
500Internal Server Error

Error Responses

Queue system errors and model validation errors.

Queue System Errors

// 402 — Insufficient balance
{
  "error": "Insufficient Balance",
  "message": "Your wallet does not have enough balance."
}
// 400 — Model not found
{
  "error": "Model not found",
  "message": "Model 'vidu-q2-reference-to-video-pro-api-454' not found or is disabled"
}

Error via Status/Webhook

{
  "request_id": "vidu-q2-reference-to-video-pro-api-454_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "ERROR",
  "model_id": "vidu-q2-reference-to-video-pro-api-454",
  "error": "Description of the error",
  "output": null
}

Retrieving Results

Poll the universal status endpoint to check progress and retrieve results.

Endpoint

GET https://gateway.pixazo.ai/v2/requests/status/{request_id}
Ocp-Apim-Subscription-Key: YOUR_API_KEY

cURL Example

curl -H "Ocp-Apim-Subscription-Key: YOUR_API_KEY" \
  "https://gateway.pixazo.ai/v2/requests/status/vidu-q2-reference-to-video-pro-api-454_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

Response (Completed)

{
  "request_id": "vidu-q2-reference-to-video-pro-api-454_019dxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "COMPLETED",
  "model_id": "vidu-q2-reference-to-video-pro-api-454",
  "error": null,
  "output": {
    "media_url": [
      "https://pub-582b7213209642b9b995c96c95a30381.r2.dev/v1/vidu-q2-reference-to-video-pro-api-454_019dxxxx-xxxx/output.ext"
    ],
    "media_type": "application/octet-stream"
  },
  "created_at": "2026-03-31T10:00:00.000Z",
  "updated_at": "2026-03-31T10:00:15.000Z",
  "completed_at": "2026-03-31T10:00:15.000Z"
}

Response Fields

FieldTypeDescription
request_idstringUnique request identifier
statusstringQUEUED, PROCESSING, COMPLETED, FAILED, or ERROR
model_idstringModel that processed the request
errorstring|nullError message if failed
output.media_urlarrayURLs to generated media (R2 CDN)
output.media_typestringMIME type of the output
created_atstringWhen request was created
completed_atstring|nullWhen request completed
polling_urlstringStatus URL (initial response only)

Status Values

StatusDescription
QUEUEDRequest accepted, waiting to be processed
PROCESSINGBeing processed by the model
COMPLETEDDone — output contains the result
FAILEDFailed — check error field
ERRORSystem error — not charged

Status Flow

QUEUED → PROCESSING → COMPLETED
                    → FAILED
                    → ERROR

Typical Workflow

  1. Send a generate request to the API endpoint
  2. Save the request_id from the response
  3. Poll every 5-10 seconds: GET /v2/requests/status/{request_id}
  4. When status is "COMPLETED", download from output.media_url

Tip: Use X-Webhook-URL header to get a callback instead of polling.

Vidu Q2 API Pricing

ResolutionPrice (USD)
360p (per video)$0.10
540p (per video)$0.20
720p (per video)$0.30
1080p ($0.20 + $0.10 / sec)$0.20

⚡ Performance

Live usage measured on Pixazo's gateway, split by model version. Generation time is how long a generation takes end-to-end (lower is better). Success rate is the percent of generations that complete (higher is better).

Show data for the last
Generations
400last 30d
~13 per day
Success rate
100.0%
of completed generations
Generation time
2.8minavg
p95 117.3s
Requests
Sep 17max 200Oct 16
Vidu Q4Avg 7/day
Vidu Q3 TurboAvg 3/day
Vidu Q2Avg 3/day
Generation Time
Sep 17max 3.9minOct 16
Vidu Q4Avg 3.9min
Vidu Q3 TurboAvg 101.4s
Vidu Q2Avg —
Error Rate
Sep 17max 5.0%Oct 16
Vidu Q4Avg 0.0%
Vidu Q3 TurboAvg 0.0%
Vidu Q2Avg —

〰 Uptime

Percent of generations that succeeded over the selected period, per model version.

Avg. Success Rate (30d)
100.00%
across all generations of this model family
Uptime
Sep 17max 100%Oct 16
Vidu Q4Avg 100.00%
Vidu Q3 TurboAvg 100.00%
Vidu Q2Avg —