- Supports text-to-video, image-to-video, first-last frame video generation
- Supports 540p / 720p / 1080p resolution
- Duration range 1-16 seconds, audio enabled by default
Request example
curl --request POST \
--url https://api.openveer.com/v1/videos/generations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"model": "viduq3-pro",
"prompt": "A cat playing piano, camera slowly zooms in",
"duration": 8,
"resolution": "1080p",
"aspect_ratio": "16:9"
}'import requests
url = "https://api.openveer.com/v1/videos/generations"
payload = {
"model": "viduq3-pro",
"prompt": "A cat playing piano, camera slowly zooms in",
"duration": 8,
"resolution": "1080p",
"aspect_ratio": "16:9"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())const url = "https://api.openveer.com/v1/videos/generations";
const payload = {
model: "viduq3-pro",
prompt: "A cat playing piano, camera slowly zooms in",
duration: 8,
resolution: "1080p",
aspect_ratio: "16:9"
};
const headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
};
fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(payload)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
func main() {
url := "https://api.openveer.com/v1/videos/generations"
payload := map[string]interface{}{
"model": "viduq3-pro",
"prompt": "A cat playing piano, camera slowly zooms in",
"duration": 8,
"resolution": "1080p",
"aspect_ratio": "16:9",
}
jsonData, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class Main {
public static void main(String[] args) throws Exception {
String url = "https://api.openveer.com/v1/videos/generations";
String payload = """
{
"model": "viduq3-pro",
"prompt": "A cat playing piano, camera slowly zooms in",
"duration": 8,
"resolution": "1080p",
"aspect_ratio": "16:9"
}
""";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(payload))
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}<?php
$url = "https://api.openveer.com/v1/videos/generations";
$payload = [
"model" => "viduq3-pro",
"prompt" => "A cat playing piano, camera slowly zooms in",
"duration" => 8,
"resolution" => "1080p",
"aspect_ratio" => "16:9"
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer <token>",
"Content-Type: application/json"
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
?>require 'net/http'
require 'json'
require 'uri'
url = URI("https://api.openveer.com/v1/videos/generations")
payload = {
model: "viduq3-pro",
prompt: "A cat playing piano, camera slowly zooms in",
duration: 8,
resolution: "1080p",
aspect_ratio: "16:9"
}
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = "Bearer <token>"
request["Content-Type"] = "application/json"
request.body = payload.to_json
response = http.request(request)
puts response.bodyimport Foundation
let url = URL(string: "https://api.openveer.com/v1/videos/generations")!
let payload: [String: Any] = [
"model": "viduq3-pro",
"prompt": "A cat playing piano, camera slowly zooms in",
"duration": 8,
"resolution": "1080p",
"aspect_ratio": "16:9"
]
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("Bearer <token>", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try? JSONSerialization.data(withJSONObject: payload)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
print("Error: \(error)")
return
}
if let data = data, let responseString = String(data: data, encoding: .utf8) {
print(responseString)
}
}
task.resume()using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
var url = "https://api.openveer.com/v1/videos/generations";
var payload = @"{
""model"": ""viduq3-pro"",
""prompt"": ""A cat playing piano, camera slowly zooms in"",
""duration"": 8,
""resolution"": ""1080p"",
""aspect_ratio"": ""16:9""
}";
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer <token>");
var content = new StringContent(payload, Encoding.UTF8, "application/json");
var response = await client.PostAsync(url, content);
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
}
}Response example
{
"code": 200,
"data": [
{
"status": "submitted",
"task_id": "task_xxxxxxxxxx"
}
]
}{
"error": {
"code": 400,
"message": "Invalid request parameters",
"type": "invalid_request_error"
}
}{
"error": {
"code": 401,
"message": "Invalid authentication credentials",
"type": "authentication_error"
}
}{
"error": {
"code": 402,
"message": "Insufficient balance. Please top up your account",
"type": "payment_required"
}
}{
"error": {
"code": 429,
"message": "Rate limit exceeded. Please try again later",
"type": "rate_limit_error"
}
}{
"error": {
"code": 500,
"message": "Internal server error. Please try again later",
"type": "server_error"
}
}Authorization
Authorization stringAll API endpoints require Bearer Token authentication
Get your API Key:
Visit the API Key Management Page to get your API Key
Add it to the request header:
Authorization: Bearer YOUR_API_KEYRequest Parameters
model stringVideo generation model name
Supported models:
viduq3-pro- Vidu Q3 Providuq3-turbo- Vidu Q3 Turbo
nsfw_check booleanWhether to run content moderation before submitting the video task.
true: useomni-moderation-latestto review prompts and input imagesfalseor omitted: do not send a moderation request, adding no moderation cost or latency (default)
prompt stringText prompt, maximum 2000 characters
Required for text-to-video. Optional for image-to-video and first-last frame modes.
Example: "A cat playing piano, camera slowly zooms in"
duration integerVideo duration (seconds)
Range: 1 to 16
Default: 5
resolution stringVideo resolution
Options:
540p- Standard definition720p- HD (default)1080p- Full HD
Default: 720p
aspect_ratio stringVideo aspect ratio (only for text-to-video mode)
Options:
16:9- Landscape9:16- Portrait4:3- Traditional3:4- Portrait traditional1:1- Square
This parameter is only available in text-to-video mode (when image_urls is not provided).
image_urls string">
Image URL array for image-to-video generation
The system automatically determines the generation mode based on the number of images:
- 0 images (not provided): Text-to-video mode
- 1 image: Image-to-video mode (image used as starting frame)
- 2 images: First-last frame mode (first image = first frame, second image = last frame)
Example: ["https://example.com/photo.jpg"]
* Maximum 2 images supported
* For first-last frame mode, exactly 2 images must be provided
* When image_urls is provided (whether 1 or 2 images), the aspect_ratio parameter cannot be used — the video aspect ratio will be automatically determined by the image
audio booleanWhether to generate audio (dialogue, sound effects)
Default: true
Set to false if you need a silent video.
seed integerSeed integer used to control randomness in generated content
Range: integer between -1 and 2^32-1
* With the same request, different seed values (including unspecified or -1, which uses a random number instead) will produce different results
* With the same request, the same seed value will produce similar results, but exact reproducibility is not guaranteed
Auto Routing
The system automatically determines the generation mode based on the number of images in image_urls:
| Images Count | Mode | Description |
|---|---|---|
| 0 (not provided) | Text-to-Video | Generate from text description only |
| 1 | Image-to-Video | Use the image as starting frame |
| 2 | First-Last Frame | First image = first frame, second image = last frame |
Parameter Support Matrix
| Parameter | Text-to-Video | Image-to-Video | First-Last Frame |
|---|---|---|---|
model |
✅ Required | ✅ Required | ✅ Required |
prompt |
✅ Required | Optional | Optional |
image_urls |
- | ✅ 1 image | ✅ 2 images |
duration |
✅ 1-16s | ✅ 1-16s | ✅ 1-16s |
resolution |
✅ | ✅ | ✅ |
aspect_ratio |
✅ | - | - |
audio |
✅ | ✅ | ✅ |
seed |
✅ | ✅ | ✅ |
Response
code integerResponse status code, 200 on success
data arraystatus stringTask status, submitted when initially submitted
task_id stringUnique task identifier for querying task status and results
Use Cases
Case 1: Text-to-Video
{
"model": "viduq3-pro",
"prompt": "A cat playing piano, camera slowly zooms in",
"duration": 8,
"resolution": "1080p",
"aspect_ratio": "16:9"
}Case 2: Image-to-Video (Single Image)
{
"model": "viduq3-pro",
"prompt": "The person slowly turns and smiles",
"image_urls": ["https://example.com/photo.jpg"],
"duration": 5,
"resolution": "720p"
}Case 3: First-Last Frame Video
{
"model": "viduq3-pro",
"prompt": "The person gradually sits down from standing",
"image_urls": [
"https://example.com/first.jpg",
"https://example.com/last.jpg"
],
"duration": 8
}Case 4: Silent Video (Audio Disabled)
{
"model": "viduq3-pro",
"prompt": "Sunset seascape timelapse photography",
"duration": 10,
"resolution": "1080p",
"audio": false
}Query Task Results
Video generation is an async task that returns a task_id upon submission. Use the Get Task Status endpoint to query generation progress and results.
This documentation is built and hosted on Mintlify, a developer documentation platform.