- Generate a new video with consistent style, characters, and scenes based on one or more reference images/videos
- Supports character consistency, style transfer, and multi-asset combination
- Supports reference voice (reference_voice) to control character voice
Request example
curl --request POST \
--url https://api.openveer.com/v1/videos/generations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"model": "wan2.7-r2v",
"prompt": "This person walks down the street surrounded by heavy traffic",
"image_with_roles": [{"url": "https://cdn.example.com/character.jpg", "role": "reference_image"}],
"resolution": "1080P",
"duration": 8
}'import requests
url = "https://api.openveer.com/v1/videos/generations"
payload = {
"model": "wan2.7-r2v",
"prompt": "This person walks down the street surrounded by heavy traffic",
"image_with_roles": [{"url": "https://cdn.example.com/character.jpg", "role": "reference_image"}],
"resolution": "1080P",
"duration": 8
}
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: "wan2.7-r2v",
prompt: "This person walks down the street surrounded by heavy traffic",
image_with_roles: [{ url: "https://cdn.example.com/character.jpg", role: "reference_image" }],
resolution: "1080P",
duration: 8
};
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": "wan2.7-r2v",
"prompt": "This person walks down the street surrounded by heavy traffic",
"image_with_roles": []map[string]string{
{"url": "https://cdn.example.com/character.jpg", "role": "reference_image"},
},
"resolution": "1080P",
"duration": 8,
}
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": "wan2.7-r2v",
"prompt": "This person walks down the street surrounded by heavy traffic",
"image_with_roles": [{"url": "https://cdn.example.com/character.jpg", "role": "reference_image"}],
"resolution": "1080P",
"duration": 8
}
""";
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" => "wan2.7-r2v",
"prompt" => "This person walks down the street surrounded by heavy traffic",
"image_with_roles" => [["url" => "https://cdn.example.com/character.jpg", "role" => "reference_image"]],
"resolution" => "1080P",
"duration" => 8
];
$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: "wan2.7-r2v",
prompt: "This person walks down the street surrounded by heavy traffic",
image_with_roles: [{ url: "https://cdn.example.com/character.jpg", role: "reference_image" }],
resolution: "1080P",
duration: 8
}
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": "wan2.7-r2v",
"prompt": "This person walks down the street surrounded by heavy traffic",
"image_with_roles": [["url": "https://cdn.example.com/character.jpg", "role": "reference_image"]],
"resolution": "1080P",
"duration": 8
]
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"": ""wan2.7-r2v"",
""prompt"": ""This person walks down the street surrounded by heavy traffic"",
""image_with_roles"": [{""url"": ""https://cdn.example.com/character.jpg"", ""role"": ""reference_image""}],
""resolution"": ""1080P"",
""duration"": 8
}";
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_01J9HA7JPQ9A0Z6JZ3V8M9W6PZ"
}
]
}{
"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, fixed as wan2.7-r2v
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 stringVideo content description, up to 5000 characters
For multiple images/videos, use "image 1", "image 2", "video 1", etc. to reference the corresponding reference assets (in order of input)
Example: "The character in image 1 enters the scene in image 2 and looks around"
image_with_roles string">
Image array with roles; at least one of this and video_urls must be provided
Fields for each object:
url(string): image URLrole(string): image rolereference_image- reference image (default)first_frame- specified first frame (when provided,sizeis ignored and the aspect ratio follows the first-frame image)
reference_voice(string, optional): voice sample audio URL for that reference character, used to control the character's voice in the generated video
Example:
[
{
"url": "https://cdn.example.com/character.jpg",
"role": "reference_image",
"reference_voice": "https://cdn.example.com/voice_sample.mp3"
},
{ "url": "https://cdn.example.com/start.jpg", "role": "first_frame" }
]video_urls string">
Reference video URL array, up to 5 videos (total images + videos ≤ 5)
At least one of this and image_with_roles must be provided
Video constraints:
* Format: mp4, mov
* Duration: 1–30s
* Resolution: width and height in the range \[240, 4096] pixels
* Aspect ratio: 1:8 – 8:1
* File size: up to 100MB
negative_prompt stringNegative prompt describing unwanted content, up to 500 characters
resolution stringVideo resolution
Options:
720P- Standard1080P- High definition (default)
duration integerVideo duration (seconds)
Supported range: 2 \~ 15 seconds
Default: 5
When the reference assets include a video: an integer between [2, 10].
When the reference assets do not include a video: an integer between \[2, 15].
size stringAspect ratio
Supported formats:
16:9- Landscape widescreen (default)9:16- Portrait1:1- Square4:3- Landscape3:4- Portrait
When first_frame is provided via image_with_roles, this parameter is ignored and the aspect ratio follows the first-frame image
prompt_extend booleanWhether to enable intelligent prompt rewriting
Significantly improves results for short prompts, but increases processing time
Default: true
watermark booleanWhether to add "AI Generated" watermark to the generated video
true: add watermarkfalse: no watermark (default)
seed integerSeed integer used to control the randomness of generated content
Value range: integer ≥0
* For identical requests, the model generates different results when receiving different seed values (e.g., omitting seed)
* For identical requests, the model generates similar results when receiving the same seed value, but exact consistency is not guaranteed
Response
code integerResponse status code, 200 on success
data arraystatus stringTask status, submitted when initially submitted
task_id stringUnique task identifier
Use Cases
Case 1: Single Reference Image (Simplest)
{
"model": "wan2.7-r2v",
"prompt": "This person walks down the street surrounded by heavy traffic",
"image_with_roles": [
{ "url": "https://cdn.example.com/character.jpg", "role": "reference_image" }
]
}Case 2: Multiple Reference Images
{
"model": "wan2.7-r2v",
"prompt": "The character in image 1 enters the scene in image 2 and mimics the pose in image 3",
"image_with_roles": [
{ "url": "https://cdn.example.com/person.jpg", "role": "reference_image" },
{ "url": "https://cdn.example.com/background.jpg", "role": "reference_image" },
{ "url": "https://cdn.example.com/pose.jpg", "role": "reference_image" }
],
"resolution": "1080P",
"duration": 8,
"size": "16:9"
}Case 3: Generation Based on Reference Video
{
"model": "wan2.7-r2v",
"prompt": "Generate a beach sunset scene in the style of the reference video",
"video_urls": ["https://cdn.example.com/style_reference.mp4"],
"resolution": "720P",
"duration": 8
}Case 4: Specified First Frame + Reference Image
{
"model": "wan2.7-r2v",
"prompt": "The reference character starts from this position and walks forward",
"image_with_roles": [
{ "url": "https://cdn.example.com/character.jpg", "role": "reference_image" },
{ "url": "https://cdn.example.com/start.jpg", "role": "first_frame" }
],
"resolution": "1080P",
"duration": 8
}Case 5: Reference Image + Reference Voice (Precise)
{
"model": "wan2.7-r2v",
"prompt": "This person walks down the street while speaking",
"image_with_roles": [
{
"url": "https://cdn.example.com/character.jpg",
"role": "reference_image",
"reference_voice": "https://cdn.example.com/voice_sample.mp3"
}
],
"resolution": "1080P",
"duration": 10
}Image Reference Rules
With multiple reference images, use numeric indices in the prompt to refer to them:
- 1st image → "image 1" or "the first image"
- 1st video → "video 1" or "the first video"
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.