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.

Models Version
Get 10% Cashback on Your First Payment (up to $500)
Add funds and get 10% cashback on your first payment (up to $500).
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-videoAuthentication
All requests require an API key passed via header.
| Header | Type | Required | Description |
|---|---|---|---|
| Ocp-Apim-Subscription-Key | string | Yes | Your 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.
| Header | Required | Description |
|---|---|---|
| X-Webhook-URL | To enable | HTTPS URL to receive the Webhook callback. |
| X-Webhook-Mode | No | terminal (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
200within a few seconds; the Webhook endpoint must be HTTPS.
Request Parameters
| Parameter | Required | Type | Default | Allowed values / range | Description |
|---|---|---|---|---|---|
image_url | Yes | string | — | One image: a publicly reachable https URL (recommended) or a data URI | The image to animate; it becomes the first frame of the video. Use a PNG, JPEG, JPG or WebP file. |
prompt | No | string | Empty | Text, up to 5000 characters | What should happen in the video: the motion, the camera movement and the mood. Optional on image-to-video. |
duration | No | integer | 5 | 3–16 | Requested length of the video in whole seconds. Billing is per requested second. |
resolution | No | string | "720p" | 540p, 720p, 1080p, 2K, 4K | Output resolution, written exactly as listed (2K and 4K in capitals). Higher resolutions cost more per second. |
seed | No | integer | Random | 0–2147483647 | Seed for the random generator; leave it out for a random seed. It does not change the amount billed. |
enable_safety_checker | No | boolean | true | true, false | Content 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,nandcountare 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_secondandmusic_length_msare rejected. - Set the resolution with
resolution:540p,720p,1080p,2Kor4K, 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,contentandtextare rejected. - Send exactly one image as
image_url;image_urls,image,imagesandsubjectsare rejected. - Image-to-video has no aspect-ratio or audio setting and takes no references:
aspect_ratio,audio,reference_image_urlsandreference_audio_urlsare rejected (references go to the Reference to Video operation). - Use the JSON types shown:
durationandseedare whole numbers (5, not"5"), andenable_safety_checkeristrueorfalse, not a string. - Omit a field instead of sending
null. - Results are always returned as a URL in
output.media_url;sync_modeis accepted only asfalse. - Webhooks are set with the
X-Webhook-URL/X-Webhook-Modeheaders;webhook_url,webhook_modeandcallback_urlin 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,videosandreference_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.
| resolution | Note |
|---|---|
540p | The lowest cost per second |
720p | The default |
1080p | — |
2K | — |
4K | The 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 reachablehttpsURL (recommended) or a data URI such asdata: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
| Header | Required | Description |
|---|---|---|
| Content-Type | Yes | application/json |
| Ocp-Apim-Subscription-Key | Yes | Your API subscription key. |
| X-Webhook-URL | No | Enable Webhook callbacks (see Webhook section). |
| X-Webhook-Mode | No | terminal (default) or sync (see Webhook section). |
Response Handling
| Status Code | Meaning |
|---|---|
| 202 | Accepted — request queued; returns request_id and polling_url. |
| 400 | Invalid 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. |
| 401 | Unauthorized — missing or invalid subscription key. |
| 402 | Insufficient balance for the hold this request needs. |
| 429 | Too many requests. |
| 500 | Internal 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.
| Condition | How it surfaces |
|---|---|
| Missing or invalid subscription key | synchronous 401 |
| Balance too low for the hold | synchronous 402 |
Missing or empty image_url, or image_url sent as anything other than a single string | synchronous 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 characters | synchronous 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 image | status: "ERROR" |
| A prompt or image the model refuses, for example under its content policy | status: "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_KEYcURL 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
| Field | Type | Description |
|---|---|---|
| request_id | string | Unique request identifier. |
| status | string | QUEUED, PROCESSING, COMPLETED or ERROR. |
| model_id | string | The model that handled the request — vidu-q4 for this endpoint. |
| output.media_url | array of strings | URL of the video (one MP4 file per request). |
| output.media_type | string | video/mp4. |
| created_at | string | Request creation timestamp. |
| completed_at | string | Completion timestamp. |
| error | string | Error message when status is ERROR. |
| polling_url | string | Status URL for this request (submit response only). |
Status Values & Flow
QUEUED → PROCESSING → COMPLETED (success) or ERROR (failure).
Typical workflow
- Send the request to
POST https://gateway.pixazo.ai/vidu-q4/v1/image-to-video. - Save the
request_idfrom the202response. - Poll
GET /v2/requests/status/{request_id}every 10 seconds or so, or use a Webhook instead. - When
statusisCOMPLETED, download the video fromoutput.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.
| Resolution | Price (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 |
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-videoAuthentication
All requests require an API key passed via header.
| Header | Type | Required | Description |
|---|---|---|---|
| Ocp-Apim-Subscription-Key | string | Yes | Your 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.
| Header | Required | Description |
|---|---|---|
| X-Webhook-URL | To enable | HTTPS URL to receive the Webhook callback. |
| X-Webhook-Mode | No | terminal (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
200within a few seconds; the Webhook endpoint must be HTTPS.
Request Parameters
| Parameter | Required | Type | Default | Allowed values / range | Description |
|---|---|---|---|---|---|
prompt | Yes | string | — | Non-empty text, up to 5000 characters | What 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_urls | Yes | array | — | 1–12 images: https URLs (recommended) or data URIs | Images 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_urls | No | array | — | Up to 3 mp3 clips, 3–12 seconds each | Reference audio clips to refer to in the prompt as [reference_audio_1], ... Requires audio: true. |
aspect_ratio | No | string | "16:9" | 16:9, 9:16, 4:3, 3:4, 1:1 | Frame shape of the video. It does not change the amount billed. |
audio | No | boolean | false | true, false | Set 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. |
duration | No | integer | 5 | 3–16 | Requested length of the video in whole seconds. Billing is per requested second. |
resolution | No | string | "720p" | 540p, 720p, 1080p, 2K, 4K | Output resolution, written exactly as listed (2K and 4K in capitals). Higher resolutions cost more per second. |
seed | No | integer | Random | 0–2147483647 | Seed for the random generator; leave it out for a random seed. It does not change the amount billed. |
enable_safety_checker | No | boolean | true | true, false | Content 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,nandcountare 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_secondandmusic_length_msare rejected. - Set the resolution with
resolution:540p,720p,1080p,2Kor4K, 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,contentandtextare rejected. - Send 1 to 12 reference images in
reference_image_urlsand refer to them inpromptby their position in the list ([@reference_image_1]is the first);image_url,image_urls,image,imagesandsubjectsare rejected. - Omit a field instead of sending
null;reference_image_urlsmust be non-empty URL strings. reference_audio_urlsrequiresaudio:true(it takes up to 3 mp3 clips).- Use the JSON types shown:
durationandseedare whole numbers (5, not"5"), andaudioandenable_safety_checkeraretrueorfalse, not strings. - Results are always returned as a URL in
output.media_url;sync_modeis accepted only asfalse. - Webhooks are set with the
X-Webhook-URL/X-Webhook-Modeheaders;webhook_url,webhook_modeandcallback_urlin 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,videosandreference_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.
| resolution | Note |
|---|---|
540p | The lowest cost per second |
720p | The default |
1080p | — |
2K | — |
4K | The 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 reachablehttpsURLs 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 needaudio: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 inreference_image_urls,[@reference_image_2]the second, and so on;[reference_audio_1]is the first clip inreference_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
| Header | Required | Description |
|---|---|---|
| Content-Type | Yes | application/json |
| Ocp-Apim-Subscription-Key | Yes | Your API subscription key. |
| X-Webhook-URL | No | Enable Webhook callbacks (see Webhook section). |
| X-Webhook-Mode | No | terminal (default) or sync (see Webhook section). |
Response Handling
| Status Code | Meaning |
|---|---|
| 202 | Accepted — request queued; returns request_id and polling_url. |
| 400 | Invalid 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. |
| 401 | Unauthorized — missing or invalid subscription key. |
| 402 | Insufficient balance for the hold this request needs. |
| 429 | Too many requests. |
| 500 | Internal 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.
| Condition | How it surfaces |
|---|---|
| Missing or invalid subscription key | synchronous 401 |
| Balance too low for the hold | synchronous 402 |
Missing or empty prompt, prompt not a string, or longer than 5000 characters | synchronous 400 |
Missing or empty reference_image_urls, reference_image_urls not a list, or more than 12 items | synchronous 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 items | synchronous 400 |
reference_audio_urls sent without audio: true | synchronous 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 seconds | status: "ERROR" |
| A prompt or reference the model refuses, for example under its content policy | status: "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_KEYcURL 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
| Field | Type | Description |
|---|---|---|
| request_id | string | Unique request identifier. |
| status | string | QUEUED, PROCESSING, COMPLETED or ERROR. |
| model_id | string | The model that handled the request — vidu-q4 for this endpoint. |
| output.media_url | array of strings | URL of the video (one MP4 file per request). |
| output.media_type | string | video/mp4. |
| created_at | string | Request creation timestamp. |
| completed_at | string | Completion timestamp. |
| error | string | Error message when status is ERROR. |
| polling_url | string | Status URL for this request (submit response only). |
Status Values & Flow
QUEUED → PROCESSING → COMPLETED (success) or ERROR (failure).
Typical workflow
- Send the request to
POST https://gateway.pixazo.ai/vidu-q4/v1/reference-to-video. - Save the
request_idfrom the202response. - Poll
GET /v2/requests/status/{request_id}every 10 seconds or so, or use a Webhook instead. - When
statusisCOMPLETED, download the video fromoutput.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.
| Resolution | Price (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 |
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.
| Header | Type | Required | Description |
|---|---|---|---|
| Ocp-Apim-Subscription-Key | string | Yes | Your 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
| Header | Required | Default | Description |
|---|---|---|---|
X-Webhook-URL | Yes (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-Mode | No | terminal | terminal — 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
POSTwhen the request reaches a terminal status. No callback duringPROCESSING. - sync mode —
POSTon every status poll (with delay capped at ~15s) plus a finalPOSTat terminal status. Use when you want progress updates. - Idempotency — use
request_idas your idempotency key. Network retries can deliver the same callback more than once; your handler must tolerate duplicates. - Response — respond
200 OKwithin 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 |
|---|---|---|---|---|---|
| prompt | Yes | string | — | non-empty; ≤ 5000 chars | Text description of the video to generate. |
| duration | No | integer | 5 | 1–16 (seconds) | Video length in seconds. Billed per second. |
| resolution | No | string | "720p" | "540p", "720p", "1080p" | Output resolution. Billed per second by resolution. |
| aspect_ratio | No | string | "16:9" | "16:9", "9:16", "3:4", "4:3", "1:1" | Output aspect ratio (text-to-video only). |
| audio | No | boolean | true | true, false | Enable 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-Type | application/json |
| Cache-Control | no-cache |
| Ocp-Apim-Subscription-Key | YOUR_SUBSCRIPTION_KEY |
Response Handling
Common status codes.
| Code | Meaning |
|---|---|
| 202 | Accepted — Request queued |
| 400 | Bad Request |
| 401 | Unauthorized |
| 402 | Insufficient Balance |
| 403 | Forbidden |
| 429 | 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-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
| Field | Type | Description |
|---|---|---|
| request_id | string | Unique request identifier |
| status | string | QUEUED, PROCESSING, COMPLETED, FAILED, or ERROR |
| model_id | string | Model that processed the request |
| error | string|null | Error message if failed |
| output.media_url | array | URLs to generated media (R2 CDN) |
| output.media_type | string | MIME type of the output |
| created_at | string | When request was created |
| completed_at | string|null | When request completed |
| polling_url | string | Status URL (initial response only) |
Status Values
| Status | Description |
|---|---|
| QUEUED | Request accepted, waiting to be processed |
| PROCESSING | Being processed by the model |
| COMPLETED | Done — output contains the result |
| FAILED | Failed — check error field |
| ERROR | System error — not charged |
Status Flow
QUEUED → PROCESSING → COMPLETED
→ FAILED
→ ERROR
Typical Workflow
- Send a generate request to the API endpoint
- Save the
request_idfrom the response - Poll every 5-10 seconds:
GET /v2/requests/status/{request_id} - When
statusis"COMPLETED", download fromoutput.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
| Resolution | Price (USD) |
|---|---|
| 540p (per second of video) | $0.05 |
| 720p (per second of video) | $0.125 |
| 1080p (per second of video) | $0.15 |
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.
| Header | Type | Required | Description |
|---|---|---|---|
| Ocp-Apim-Subscription-Key | string | Yes | Your 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
| Header | Required | Default | Description |
|---|---|---|---|
X-Webhook-URL | Yes (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-Mode | No | terminal | terminal — 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
POSTwhen the request reaches a terminal status. No callback duringPROCESSING. - sync mode —
POSTon every status poll (with delay capped at ~15s) plus a finalPOSTat terminal status. Use when you want progress updates. - Idempotency — use
request_idas your idempotency key. Network retries can deliver the same callback more than once; your handler must tolerate duplicates. - Response — respond
200 OKwithin 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_image | Yes | string | — | public URL or data:image/...;base64,… | Starting frame to animate. |
| prompt | No | string | — | ≤ 5000 chars | Optional text guiding the motion / scene. |
| duration | No | integer | 5 | 1–16 (seconds) | Video length in seconds. Billed per second. |
| resolution | No | string | "720p" | "540p", "720p", "1080p" | Output resolution. Billed per second by resolution. |
| audio | No | boolean | true | true, false | Enable audio-video sync. false outputs a silent video. |
Content Item Types & Limits
| Type | Max | Format / Size | Description |
|---|---|---|---|
| image | 1 | JPG, PNG, WEBP · < 50 MB | Start 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-Type | application/json |
| Cache-Control | no-cache |
| Ocp-Apim-Subscription-Key | YOUR_SUBSCRIPTION_KEY |
Response Handling
Common status codes.
| Code | Meaning |
|---|---|
| 202 | Accepted — Request queued |
| 400 | Bad Request |
| 401 | Unauthorized |
| 402 | Insufficient Balance |
| 403 | Forbidden |
| 429 | 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-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
| Field | Type | Description |
|---|---|---|
| request_id | string | Unique request identifier |
| status | string | QUEUED, PROCESSING, COMPLETED, FAILED, or ERROR |
| model_id | string | Model that processed the request |
| error | string|null | Error message if failed |
| output.media_url | array | URLs to generated media (R2 CDN) |
| output.media_type | string | MIME type of the output |
| created_at | string | When request was created |
| completed_at | string|null | When request completed |
| polling_url | string | Status URL (initial response only) |
Status Values
| Status | Description |
|---|---|
| QUEUED | Request accepted, waiting to be processed |
| PROCESSING | Being processed by the model |
| COMPLETED | Done — output contains the result |
| FAILED | Failed — check error field |
| ERROR | System error — not charged |
Status Flow
QUEUED → PROCESSING → COMPLETED
→ FAILED
→ ERROR
Typical Workflow
- Send a generate request to the API endpoint
- Save the
request_idfrom the response - Poll every 5-10 seconds:
GET /v2/requests/status/{request_id} - When
statusis"COMPLETED", download fromoutput.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
| Resolution | Price (USD) |
|---|---|
| 540p (per second of video) | $0.05 |
| 720p (per second of video) | $0.125 |
| 1080p (per second of video) | $0.15 |
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.
| Header | Type | Required | Description |
|---|---|---|---|
| Ocp-Apim-Subscription-Key | string | Yes | Your 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
| Header | Required | Default | Description |
|---|---|---|---|
X-Webhook-URL | Yes (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-Mode | No | terminal | terminal — 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
POSTwhen the request reaches a terminal status. No callback duringPROCESSING. - sync mode —
POSTon every status poll (with delay capped at ~15s) plus a finalPOSTat terminal status. Use when you want progress updates. - Idempotency — use
request_idas your idempotency key. Network retries can deliver the same callback more than once; your handler must tolerate duplicates. - Response — respond
200 OKwithin 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_image | Yes | string | — | public URL or data:image/...;base64,… | First frame of the video. |
| end_image | Yes | string | — | public URL or data:image/...;base64,… | Last frame. Must be used together with start_image. |
| prompt | No | string | — | ≤ 5000 chars | Optional text guiding the motion / scene. |
| duration | No | integer | 5 | 1–16 (seconds) | Video length in seconds. Billed per second. |
| resolution | No | string | "720p" | "540p", "720p", "1080p" | Output resolution. Billed per second by resolution. |
| audio | No | boolean | true | true, false | Enable audio-video sync. false outputs a silent video. |
Content Item Types & Limits
| Type | Max | Format / Size | Description |
|---|---|---|---|
| image | 1 | JPG, PNG, WEBP · < 50 MB | Start / 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-Type | application/json |
| Cache-Control | no-cache |
| Ocp-Apim-Subscription-Key | YOUR_SUBSCRIPTION_KEY |
Response Handling
Common status codes.
| Code | Meaning |
|---|---|
| 202 | Accepted — Request queued |
| 400 | Bad Request |
| 401 | Unauthorized |
| 402 | Insufficient Balance |
| 403 | Forbidden |
| 429 | 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-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
| Field | Type | Description |
|---|---|---|
| request_id | string | Unique request identifier |
| status | string | QUEUED, PROCESSING, COMPLETED, FAILED, or ERROR |
| model_id | string | Model that processed the request |
| error | string|null | Error message if failed |
| output.media_url | array | URLs to generated media (R2 CDN) |
| output.media_type | string | MIME type of the output |
| created_at | string | When request was created |
| completed_at | string|null | When request completed |
| polling_url | string | Status URL (initial response only) |
Status Values
| Status | Description |
|---|---|
| QUEUED | Request accepted, waiting to be processed |
| PROCESSING | Being processed by the model |
| COMPLETED | Done — output contains the result |
| FAILED | Failed — check error field |
| ERROR | System error — not charged |
Status Flow
QUEUED → PROCESSING → COMPLETED
→ FAILED
→ ERROR
Typical Workflow
- Send a generate request to the API endpoint
- Save the
request_idfrom the response - Poll every 5-10 seconds:
GET /v2/requests/status/{request_id} - When
statusis"COMPLETED", download fromoutput.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
| Resolution | Price (USD) |
|---|---|
| 540p (per second of video) | $0.05 |
| 720p (per second of video) | $0.125 |
| 1080p (per second of video) | $0.15 |
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.
| Header | Type | Required | Description |
|---|---|---|---|
| Ocp-Apim-Subscription-Key | string | Yes | Your 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
| Header | Required | Default | Description |
|---|---|---|---|
X-Webhook-URL | Yes (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-Mode | No | terminal | terminal — 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
POSTwhen the request reaches a terminal status. No callback duringPROCESSING. - sync mode —
POSTon every status poll (with delay capped at ~15s) plus a finalPOSTat terminal status. Use when you want progress updates. - Idempotency — use
request_idas your idempotency key. Network retries can deliver the same callback more than once; your handler must tolerate duplicates. - Response — respond
200 OKwithin 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 |
|---|---|---|---|---|---|
| prompt | Yes | string | — | non-empty; ≤ 5000 chars | Text description of the video to generate. |
| duration | No | integer | 5 | 1–16 (seconds) | Video length in seconds. Billed per second. |
| resolution | No | string | "720p" | "540p", "720p", "1080p" | Output resolution. Billed per second by resolution. |
| aspect_ratio | No | string | "16:9" | "16:9", "9:16", "3:4", "4:3", "1:1" | Output aspect ratio (text-to-video only). |
| audio | No | boolean | true | true, false | Enable 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-Type | application/json |
| Cache-Control | no-cache |
| Ocp-Apim-Subscription-Key | YOUR_SUBSCRIPTION_KEY |
Response Handling
Common status codes.
| Code | Meaning |
|---|---|
| 202 | Accepted — Request queued |
| 400 | Bad Request |
| 401 | Unauthorized |
| 402 | Insufficient Balance |
| 403 | Forbidden |
| 429 | 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-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
| Field | Type | Description |
|---|---|---|
| request_id | string | Unique request identifier |
| status | string | QUEUED, PROCESSING, COMPLETED, FAILED, or ERROR |
| model_id | string | Model that processed the request |
| error | string|null | Error message if failed |
| output.media_url | array | URLs to generated media (R2 CDN) |
| output.media_type | string | MIME type of the output |
| created_at | string | When request was created |
| completed_at | string|null | When request completed |
| polling_url | string | Status URL (initial response only) |
Status Values
| Status | Description |
|---|---|
| QUEUED | Request accepted, waiting to be processed |
| PROCESSING | Being processed by the model |
| COMPLETED | Done — output contains the result |
| FAILED | Failed — check error field |
| ERROR | System error — not charged |
Status Flow
QUEUED → PROCESSING → COMPLETED
→ FAILED
→ ERROR
Typical Workflow
- Send a generate request to the API endpoint
- Save the
request_idfrom the response - Poll every 5-10 seconds:
GET /v2/requests/status/{request_id} - When
statusis"COMPLETED", download fromoutput.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
| Resolution | Price (USD) |
|---|---|
| 540p (per second of video) | $0.04 |
| 720p (per second of video) | $0.06 |
| 1080p (per second of video) | $0.07 |
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.
| Header | Type | Required | Description |
|---|---|---|---|
| Ocp-Apim-Subscription-Key | string | Yes | Your 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
| Header | Required | Default | Description |
|---|---|---|---|
X-Webhook-URL | Yes (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-Mode | No | terminal | terminal — 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
POSTwhen the request reaches a terminal status. No callback duringPROCESSING. - sync mode —
POSTon every status poll (with delay capped at ~15s) plus a finalPOSTat terminal status. Use when you want progress updates. - Idempotency — use
request_idas your idempotency key. Network retries can deliver the same callback more than once; your handler must tolerate duplicates. - Response — respond
200 OKwithin 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_image | Yes | string | — | public URL or data:image/...;base64,… | Starting frame to animate. |
| prompt | No | string | — | ≤ 5000 chars | Optional text guiding the motion / scene. |
| duration | No | integer | 5 | 1–16 (seconds) | Video length in seconds. Billed per second. |
| resolution | No | string | "720p" | "540p", "720p", "1080p" | Output resolution. Billed per second by resolution. |
| audio | No | boolean | true | true, false | Enable audio-video sync. false outputs a silent video. |
Content Item Types & Limits
| Type | Max | Format / Size | Description |
|---|---|---|---|
| image | 1 | JPG, PNG, WEBP · < 50 MB | Start 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-Type | application/json |
| Cache-Control | no-cache |
| Ocp-Apim-Subscription-Key | YOUR_SUBSCRIPTION_KEY |
Response Handling
Common status codes.
| Code | Meaning |
|---|---|
| 202 | Accepted — Request queued |
| 400 | Bad Request |
| 401 | Unauthorized |
| 402 | Insufficient Balance |
| 403 | Forbidden |
| 429 | 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-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
| Field | Type | Description |
|---|---|---|
| request_id | string | Unique request identifier |
| status | string | QUEUED, PROCESSING, COMPLETED, FAILED, or ERROR |
| model_id | string | Model that processed the request |
| error | string|null | Error message if failed |
| output.media_url | array | URLs to generated media (R2 CDN) |
| output.media_type | string | MIME type of the output |
| created_at | string | When request was created |
| completed_at | string|null | When request completed |
| polling_url | string | Status URL (initial response only) |
Status Values
| Status | Description |
|---|---|
| QUEUED | Request accepted, waiting to be processed |
| PROCESSING | Being processed by the model |
| COMPLETED | Done — output contains the result |
| FAILED | Failed — check error field |
| ERROR | System error — not charged |
Status Flow
QUEUED → PROCESSING → COMPLETED
→ FAILED
→ ERROR
Typical Workflow
- Send a generate request to the API endpoint
- Save the
request_idfrom the response - Poll every 5-10 seconds:
GET /v2/requests/status/{request_id} - When
statusis"COMPLETED", download fromoutput.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
| Resolution | Price (USD) |
|---|---|
| 540p (per second of video) | $0.04 |
| 720p (per second of video) | $0.06 |
| 1080p (per second of video) | $0.07 |
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.
| Header | Type | Required | Description |
|---|---|---|---|
| Ocp-Apim-Subscription-Key | string | Yes | Your 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
| Header | Required | Default | Description |
|---|---|---|---|
X-Webhook-URL | Yes (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-Mode | No | terminal | terminal — 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
POSTwhen the request reaches a terminal status. No callback duringPROCESSING. - sync mode —
POSTon every status poll (with delay capped at ~15s) plus a finalPOSTat terminal status. Use when you want progress updates. - Idempotency — use
request_idas your idempotency key. Network retries can deliver the same callback more than once; your handler must tolerate duplicates. - Response — respond
200 OKwithin 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_image | Yes | string | — | public URL or data:image/...;base64,… | First frame of the video. |
| end_image | Yes | string | — | public URL or data:image/...;base64,… | Last frame. Must be used together with start_image. |
| prompt | No | string | — | ≤ 5000 chars | Optional text guiding the motion / scene. |
| duration | No | integer | 5 | 1–16 (seconds) | Video length in seconds. Billed per second. |
| resolution | No | string | "720p" | "540p", "720p", "1080p" | Output resolution. Billed per second by resolution. |
| audio | No | boolean | true | true, false | Enable audio-video sync. false outputs a silent video. |
Content Item Types & Limits
| Type | Max | Format / Size | Description |
|---|---|---|---|
| image | 1 | JPG, PNG, WEBP · < 50 MB | Start / 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-Type | application/json |
| Cache-Control | no-cache |
| Ocp-Apim-Subscription-Key | YOUR_SUBSCRIPTION_KEY |
Response Handling
Common status codes.
| Code | Meaning |
|---|---|
| 202 | Accepted — Request queued |
| 400 | Bad Request |
| 401 | Unauthorized |
| 402 | Insufficient Balance |
| 403 | Forbidden |
| 429 | 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-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
| Field | Type | Description |
|---|---|---|
| request_id | string | Unique request identifier |
| status | string | QUEUED, PROCESSING, COMPLETED, FAILED, or ERROR |
| model_id | string | Model that processed the request |
| error | string|null | Error message if failed |
| output.media_url | array | URLs to generated media (R2 CDN) |
| output.media_type | string | MIME type of the output |
| created_at | string | When request was created |
| completed_at | string|null | When request completed |
| polling_url | string | Status URL (initial response only) |
Status Values
| Status | Description |
|---|---|
| QUEUED | Request accepted, waiting to be processed |
| PROCESSING | Being processed by the model |
| COMPLETED | Done — output contains the result |
| FAILED | Failed — check error field |
| ERROR | System error — not charged |
Status Flow
QUEUED → PROCESSING → COMPLETED
→ FAILED
→ ERROR
Typical Workflow
- Send a generate request to the API endpoint
- Save the
request_idfrom the response - Poll every 5-10 seconds:
GET /v2/requests/status/{request_id} - When
statusis"COMPLETED", download fromoutput.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
| Resolution | Price (USD) |
|---|---|
| 540p (per second of video) | $0.04 |
| 720p (per second of video) | $0.06 |
| 1080p (per second of video) | $0.07 |
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
| Header | Required | Default | Description |
|---|---|---|---|
X-Webhook-URL | Yes (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-Mode | No | terminal | terminal — 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
POSTwhen the request reaches a terminal status. No callback duringPROCESSING. - sync mode —
POSTon every status poll (with delay capped at ~15s) plus a finalPOSTat terminal status. Use when you want progress updates. - Idempotency — use
request_idas your idempotency key. Network retries can deliver the same callback more than once; your handler must tolerate duplicates. - Response — respond
200 OKwithin 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
| Parameter | Required | Type | Default | Allowed values / range | Description |
|---|---|---|---|---|---|
| prompt | Yes | string | — | non-empty; ≤ 2000 chars | Text prompt describing the video to generate. |
| duration | No | integer | 5 | 1–16 (seconds) | Length of the generated video in seconds. |
| seed | No | integer | — | any integer | Random seed for reproducible results. Omit for a random seed. |
| aspect_ratio | No | string | "16:9" | "16:9", "9:16", "4:3", "3:4", "1:1" | Aspect ratio of the output video. |
| resolution | No | string | "720p" | "360p", "540p", "720p", "1080p" | Output resolution of the generated video. |
| audio | No | boolean | true | true, false | Whether 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 |
| 400 | Bad Request |
| 401 | Unauthorized |
| 403 | Forbidden |
| 404 | Not Found |
| 429 | 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
| Field | Type | Description |
|---|---|---|
| request_id | string | Unique request identifier |
| status | string | QUEUED, PROCESSING, COMPLETED, FAILED, or ERROR |
| model_id | string | Model that processed the request |
| error | string|null | Error message if failed |
| output.media_url | array | URLs to generated media (R2 CDN) |
| output.media_type | string | MIME type of the output |
| created_at | string | When request was created |
| completed_at | string|null | When request completed |
| polling_url | string | Status URL (initial response only) |
Status Values
| Status | Description |
|---|---|
| QUEUED | Request accepted, waiting to be processed |
| PROCESSING | Being processed by the model |
| COMPLETED | Done — output contains the result |
| FAILED | Failed — check error field |
| ERROR | System error — not charged |
Status Flow
QUEUED → PROCESSING → COMPLETED
→ FAILED
→ ERROR
Typical Workflow
- Send a generate request to the API endpoint
- Save the
request_idfrom the response - Poll every 5-10 seconds:
GET /v2/requests/status/{request_id} - When
statusis"COMPLETED", download fromoutput.media_url
Tip: Use X-Webhook-URL header to get a callback instead of polling.
Vidu Q3 API Pricing
| Resolution | Price (USD) |
|---|---|
| 360p / per second | $0.07 |
| 540p / per second | $0.07 |
| 720p / per second | $0.154 |
| 1080p / per second | $0.154 |
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.
| Header | Type | Required | Description |
|---|---|---|---|
| Ocp-Apim-Subscription-Key | string | Yes | Your 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
| Header | Required | Default | Description |
|---|---|---|---|
X-Webhook-URL | Yes (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-Mode | No | terminal | terminal — 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
POSTwhen the request reaches a terminal status. No callback duringPROCESSING. - sync mode —
POSTon every status poll (with delay capped at ~15s) plus a finalPOSTat terminal status. Use when you want progress updates. - Idempotency — use
request_idas your idempotency key. Network retries can deliver the same callback more than once; your handler must tolerate duplicates. - Response — respond
200 OKwithin 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
| Parameter | Required | Type | Default | Allowed values / range | Description |
|---|---|---|---|---|---|
| prompt | Yes | string | — | ≤ 2000 characters | Text prompt for video generation (maximum 2000 characters). |
| reference_image_urls | No | array 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_urls | No | array of strings | [] | up to 2 | HTTPS URLs of reference videos for video editing or motion reference. Supports up to 2 videos (MP4). |
| seed | No | integer | — | — | 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. |
| duration | No | integer | 4 | 0 (automatic), or 1–8 | Duration of the output video in seconds. Accepts 1–8 seconds, or 0 to let the model choose the duration automatically. |
| resolution | No | string | 720p | "540p", "720p", "1080p" | Output video resolution. Supported values: "540p", "720p", "1080p". |
| aspect_ratio | No | string | 16:9 | "auto", "16:9", "9:16", "1:1", or any W:H | Aspect ratio of the output video. |
| movement_amplitude | No | string | auto | "auto", "small", "medium", "large" | The movement amplitude of objects in the frame. |
| bgm | No | boolean | false | true, false | Whether to add background music to the generated video. |
Content Item Types & Limits
| Type | Max | Format / Size | Description |
|---|---|---|---|
| reference_image_urls | 4 | JPG, PNG, WEBP · < 50 MB | Reference image(s), up to 4. |
| reference_video_urls | 2 | MP4 · < 100 MB | Reference 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-Type | application/json |
| Cache-Control | no-cache |
| Ocp-Apim-Subscription-Key | YOUR_SUBSCRIPTION_KEY |
Response Handling
Common status codes.
| Code | Meaning |
|---|---|
| 202 | Accepted — Request queued |
| 400 | Bad Request |
| 401 | Unauthorized |
| 402 | Insufficient Balance |
| 403 | Forbidden |
| 429 | 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-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
| Field | Type | Description |
|---|---|---|
| request_id | string | Unique request identifier |
| status | string | QUEUED, PROCESSING, COMPLETED, FAILED, or ERROR |
| model_id | string | Model that processed the request |
| error | string|null | Error message if failed |
| output.media_url | array | URLs to generated media (R2 CDN) |
| output.media_type | string | MIME type of the output |
| created_at | string | When request was created |
| completed_at | string|null | When request completed |
| polling_url | string | Status URL (initial response only) |
Status Values
| Status | Description |
|---|---|
| QUEUED | Request accepted, waiting to be processed |
| PROCESSING | Being processed by the model |
| COMPLETED | Done — output contains the result |
| FAILED | Failed — check error field |
| ERROR | System error — not charged |
Status Flow
QUEUED → PROCESSING → COMPLETED
→ FAILED
→ ERROR
Typical Workflow
- Send a generate request to the API endpoint
- Save the
request_idfrom the response - Poll every 5-10 seconds:
GET /v2/requests/status/{request_id} - When
statusis"COMPLETED", download fromoutput.media_url
Tip: Use X-Webhook-URL header to get a callback instead of polling.
Vidu Q2 API Pricing
| Resolution | Price (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).
〰 Uptime
Percent of generations that succeeded over the selected period, per model version.