curl --request POST \
--url https://api.apimart.ai/v1/videos/generations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"model": "skyreels-v4-fast",
"prompt": "A serene forest at sunset with golden light filtering through the trees.",
"duration": 5,
"resolution": "1080p",
"aspect_ratio": "16:9",
"prompt_optimizer": true
}'
import requests
url = "https://api.apimart.ai/v1/videos/generations"
payload = {
"model": "skyreels-v4-fast",
"prompt": "A serene forest at sunset with golden light filtering through the trees.",
"duration": 5,
"resolution": "1080p",
"aspect_ratio": "16:9",
"prompt_optimizer": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())
const url = "https://api.apimart.ai/v1/videos/generations";
const payload = {
model: "skyreels-v4-fast",
prompt: "A serene forest at sunset with golden light filtering through the trees.",
duration: 5,
resolution: "1080p",
aspect_ratio: "16:9",
prompt_optimizer: true
};
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.apimart.ai/v1/videos/generations"
payload := map[string]interface{}{
"model": "skyreels-v4-fast",
"prompt": "A serene forest at sunset with golden light filtering through the trees.",
"duration": 5,
"resolution": "1080p",
"aspect_ratio": "16:9",
"prompt_optimizer": true,
}
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.apimart.ai/v1/videos/generations";
String payload = """
{
"model": "skyreels-v4-fast",
"prompt": "A serene forest at sunset with golden light filtering through the trees.",
"duration": 5,
"resolution": "1080p",
"aspect_ratio": "16:9",
"prompt_optimizer": true
}
""";
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.apimart.ai/v1/videos/generations";
$payload = [
"model" => "skyreels-v4-fast",
"prompt" => "A serene forest at sunset with golden light filtering through the trees.",
"duration" => 5,
"resolution" => "1080p",
"aspect_ratio" => "16:9",
"prompt_optimizer" => true
];
$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.apimart.ai/v1/videos/generations")
payload = {
model: "skyreels-v4-fast",
prompt: "A serene forest at sunset with golden light filtering through the trees.",
duration: 5,
resolution: "1080p",
aspect_ratio: "16:9",
prompt_optimizer: true
}
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.body
import Foundation
let url = URL(string: "https://api.apimart.ai/v1/videos/generations")!
let payload: [String: Any] = [
"model": "skyreels-v4-fast",
"prompt": "A serene forest at sunset with golden light filtering through the trees.",
"duration": 5,
"resolution": "1080p",
"aspect_ratio": "16:9",
"prompt_optimizer": true
]
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.apimart.ai/v1/videos/generations";
var payload = @"{
""model"": ""skyreels-v4-fast"",
""prompt"": ""A serene forest at sunset with golden light filtering through the trees."",
""duration"": 5,
""resolution"": ""1080p"",
""aspect_ratio"": ""16:9"",
""prompt_optimizer"": true
}";
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);
}
}
{
"code": 200,
"data": [
{
"status": "submitted",
"task_id": "task_01KPEY5H3NQ2W8D7T6VB3F9GR4"
}
]
}
{
"error": {
"code": 400,
"message": "Invalid request parameters",
"type": "invalid_request_error"
}
}
{
"error": {
"code": 401,
"message": "Authentication failed, please check your API key",
"type": "authentication_error"
}
}
{
"error": {
"code": 402,
"message": "Insufficient account balance, please top up and try again",
"type": "payment_required"
}
}
{
"error": {
"code": 422,
"message": "Parameter conflict or invalid value (e.g. I2V and Omni fields passed simultaneously)",
"type": "invalid_request_error"
}
}
{
"error": {
"code": 429,
"message": "Too many requests, please try again later",
"type": "rate_limit_error"
}
}
{
"error": {
"code": 500,
"message": "Internal server error, please retry later",
"type": "server_error"
}
}
SkyReels V4
SkyReels V4 Video Generation
- Two model tiers: Fast (speed-optimized) and Std (quality-optimized)
- Three modes auto-routed by request fields: Text-to-Video (T2V), Image-to-Video (I2V), Multimodal Reference (Omni)
- 480p / 720p / 1080p resolution, 3 ~ 15 seconds duration
- Advanced features: first/end/key frame, reference images, reference videos, grid collage, video extension, audio sync
- Async processing mode, returns a task ID for later query
POST
/
v1
/
videos
/
generations
curl --request POST \
--url https://api.apimart.ai/v1/videos/generations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"model": "skyreels-v4-fast",
"prompt": "A serene forest at sunset with golden light filtering through the trees.",
"duration": 5,
"resolution": "1080p",
"aspect_ratio": "16:9",
"prompt_optimizer": true
}'
import requests
url = "https://api.apimart.ai/v1/videos/generations"
payload = {
"model": "skyreels-v4-fast",
"prompt": "A serene forest at sunset with golden light filtering through the trees.",
"duration": 5,
"resolution": "1080p",
"aspect_ratio": "16:9",
"prompt_optimizer": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())
const url = "https://api.apimart.ai/v1/videos/generations";
const payload = {
model: "skyreels-v4-fast",
prompt: "A serene forest at sunset with golden light filtering through the trees.",
duration: 5,
resolution: "1080p",
aspect_ratio: "16:9",
prompt_optimizer: true
};
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.apimart.ai/v1/videos/generations"
payload := map[string]interface{}{
"model": "skyreels-v4-fast",
"prompt": "A serene forest at sunset with golden light filtering through the trees.",
"duration": 5,
"resolution": "1080p",
"aspect_ratio": "16:9",
"prompt_optimizer": true,
}
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.apimart.ai/v1/videos/generations";
String payload = """
{
"model": "skyreels-v4-fast",
"prompt": "A serene forest at sunset with golden light filtering through the trees.",
"duration": 5,
"resolution": "1080p",
"aspect_ratio": "16:9",
"prompt_optimizer": true
}
""";
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.apimart.ai/v1/videos/generations";
$payload = [
"model" => "skyreels-v4-fast",
"prompt" => "A serene forest at sunset with golden light filtering through the trees.",
"duration" => 5,
"resolution" => "1080p",
"aspect_ratio" => "16:9",
"prompt_optimizer" => true
];
$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.apimart.ai/v1/videos/generations")
payload = {
model: "skyreels-v4-fast",
prompt: "A serene forest at sunset with golden light filtering through the trees.",
duration: 5,
resolution: "1080p",
aspect_ratio: "16:9",
prompt_optimizer: true
}
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.body
import Foundation
let url = URL(string: "https://api.apimart.ai/v1/videos/generations")!
let payload: [String: Any] = [
"model": "skyreels-v4-fast",
"prompt": "A serene forest at sunset with golden light filtering through the trees.",
"duration": 5,
"resolution": "1080p",
"aspect_ratio": "16:9",
"prompt_optimizer": true
]
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.apimart.ai/v1/videos/generations";
var payload = @"{
""model"": ""skyreels-v4-fast"",
""prompt"": ""A serene forest at sunset with golden light filtering through the trees."",
""duration"": 5,
""resolution"": ""1080p"",
""aspect_ratio"": ""16:9"",
""prompt_optimizer"": true
}";
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);
}
}
{
"code": 200,
"data": [
{
"status": "submitted",
"task_id": "task_01KPEY5H3NQ2W8D7T6VB3F9GR4"
}
]
}
{
"error": {
"code": 400,
"message": "Invalid request parameters",
"type": "invalid_request_error"
}
}
{
"error": {
"code": 401,
"message": "Authentication failed, please check your API key",
"type": "authentication_error"
}
}
{
"error": {
"code": 402,
"message": "Insufficient account balance, please top up and try again",
"type": "payment_required"
}
}
{
"error": {
"code": 422,
"message": "Parameter conflict or invalid value (e.g. I2V and Omni fields passed simultaneously)",
"type": "invalid_request_error"
}
}
{
"error": {
"code": 429,
"message": "Too many requests, please try again later",
"type": "rate_limit_error"
}
}
{
"error": {
"code": 500,
"message": "Internal server error, please retry later",
"type": "server_error"
}
}
curl --request POST \
--url https://api.apimart.ai/v1/videos/generations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"model": "skyreels-v4-fast",
"prompt": "A serene forest at sunset with golden light filtering through the trees.",
"duration": 5,
"resolution": "1080p",
"aspect_ratio": "16:9",
"prompt_optimizer": true
}'
import requests
url = "https://api.apimart.ai/v1/videos/generations"
payload = {
"model": "skyreels-v4-fast",
"prompt": "A serene forest at sunset with golden light filtering through the trees.",
"duration": 5,
"resolution": "1080p",
"aspect_ratio": "16:9",
"prompt_optimizer": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())
const url = "https://api.apimart.ai/v1/videos/generations";
const payload = {
model: "skyreels-v4-fast",
prompt: "A serene forest at sunset with golden light filtering through the trees.",
duration: 5,
resolution: "1080p",
aspect_ratio: "16:9",
prompt_optimizer: true
};
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.apimart.ai/v1/videos/generations"
payload := map[string]interface{}{
"model": "skyreels-v4-fast",
"prompt": "A serene forest at sunset with golden light filtering through the trees.",
"duration": 5,
"resolution": "1080p",
"aspect_ratio": "16:9",
"prompt_optimizer": true,
}
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.apimart.ai/v1/videos/generations";
String payload = """
{
"model": "skyreels-v4-fast",
"prompt": "A serene forest at sunset with golden light filtering through the trees.",
"duration": 5,
"resolution": "1080p",
"aspect_ratio": "16:9",
"prompt_optimizer": true
}
""";
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.apimart.ai/v1/videos/generations";
$payload = [
"model" => "skyreels-v4-fast",
"prompt" => "A serene forest at sunset with golden light filtering through the trees.",
"duration" => 5,
"resolution" => "1080p",
"aspect_ratio" => "16:9",
"prompt_optimizer" => true
];
$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.apimart.ai/v1/videos/generations")
payload = {
model: "skyreels-v4-fast",
prompt: "A serene forest at sunset with golden light filtering through the trees.",
duration: 5,
resolution: "1080p",
aspect_ratio: "16:9",
prompt_optimizer: true
}
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.body
import Foundation
let url = URL(string: "https://api.apimart.ai/v1/videos/generations")!
let payload: [String: Any] = [
"model": "skyreels-v4-fast",
"prompt": "A serene forest at sunset with golden light filtering through the trees.",
"duration": 5,
"resolution": "1080p",
"aspect_ratio": "16:9",
"prompt_optimizer": true
]
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.apimart.ai/v1/videos/generations";
var payload = @"{
""model"": ""skyreels-v4-fast"",
""prompt"": ""A serene forest at sunset with golden light filtering through the trees."",
""duration"": 5,
""resolution"": ""1080p"",
""aspect_ratio"": ""16:9"",
""prompt_optimizer"": true
}";
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);
}
}
{
"code": 200,
"data": [
{
"status": "submitted",
"task_id": "task_01KPEY5H3NQ2W8D7T6VB3F9GR4"
}
]
}
{
"error": {
"code": 400,
"message": "Invalid request parameters",
"type": "invalid_request_error"
}
}
{
"error": {
"code": 401,
"message": "Authentication failed, please check your API key",
"type": "authentication_error"
}
}
{
"error": {
"code": 402,
"message": "Insufficient account balance, please top up and try again",
"type": "payment_required"
}
}
{
"error": {
"code": 422,
"message": "Parameter conflict or invalid value (e.g. I2V and Omni fields passed simultaneously)",
"type": "invalid_request_error"
}
}
{
"error": {
"code": 429,
"message": "Too many requests, please try again later",
"type": "rate_limit_error"
}
}
{
"error": {
"code": 500,
"message": "Internal server error, please retry later",
"type": "server_error"
}
}
Authorization
string
required
All API endpoints require Bearer Token authenticationGet your API Key:Visit the API Key Management Page to get your API KeyAdd to the request header:
Authorization: Bearer YOUR_API_KEY
Generation Modes
SkyReels V4 auto-routes to the correct mode based on request fields — nomode field needed:
| Mode | Trigger | Capability |
|---|---|---|
| T2V (Text-to-Video) | Only prompt + general fields | Pure text-driven generation |
| I2V (Image-to-Video) | Any of first_frame_image / end_frame_image / mid_frame_images | First/end/key frame control |
| Omni (Multimodal Reference) | Any of ref_images / ref_videos | Subject reference, grid collage, motion reference, video extension, audio sync |
Strict mutual exclusion: I2V fields (
first_frame_image / end_frame_image / mid_frame_images) and Omni fields (ref_images / ref_videos) cannot be used together, otherwise returns 422.@tag mechanism: When using mid_frame_images / ref_images / ref_videos, each element must declare a tag starting with @ (e.g., @image1, @Actor-1, @video1), and the tag must appear in the prompt.Think of prompt as the “script” and tag as a “character pointer” to specific assets (images / videos). For example, a prompt like "@Actor-1 walks into the scene of @video1" instructs the system to inject the reference image subject tied to @Actor-1 and the motion reference tied to @video1 into the generation process.Request Parameters
General Fields
string
required
Two model tiers are available:
| Model | Positioning | Use Cases |
|---|---|---|
skyreels-v4-fast | Speed-first | Quick previews, batch generation, daily content |
skyreels-v4-std | Quality-first (25~30% higher price than Fast) | Key shots, high-detail requirements, formal delivery |
The
model field must be explicitly provided — no default value.Pricing is strongly tied to resolution and whether
ref_videos is used: 1080p is significantly more expensive than 480p / 720p; tiers with ref_videos (video input) cost ~1.5 ~ 2× compared to those without. Simultaneous audio and video output is not yet supported.string
required
Text prompt, max 1280 tokensDescribe scenes, subjects, actions, styles in detail for better generation results.When using
ref_images / ref_videos / mid_frame_images, the prompt must contain the corresponding @tag (e.g., @Actor-1, @video1, @image1).Example: "@Actor-1 walks through a neon-lit street at night."integer
default:"5"
Output video duration (seconds)
- Range:
[3, 15] - Default:
5
When
ref_videos.type=reference is provided, duration is overridden by the reference video length (max 10 seconds).string
default:"1080p"
Video resolutionOptions:
480p720p1080p(default)
string
default:"16:9"
Aspect ratioOptions:
16:9(default)4:31:19:163:4
aspect_ratio is ignored in I2V mode (output ratio is determined by the input image); also ignored when Omni is combined with ref_videos.boolean
default:"true"
Whether to auto-optimize the promptWhen enabled, the system automatically optimizes your prompt for better generation results.
I2V-Specific Fields
string
First frame image URL (jpg / jpeg / png / gif / bmp)When provided, this image is used as the starting frame of the video.
string
End frame image URL (jpg / jpeg / png / gif / bmp)When provided, this image is used as the ending frame of the video. Can be combined with
first_frame_image for first-and-last-frame control.object[]
Mid keyframe list, up to 6. Each element has the following structure:
Omni-Specific Fields
object[]
Reference image list (all elements must share the same
type). Each element has the following structure:Show ref_images element
Show ref_images element
string
required
Must start with
@ and appear in the prompt, e.g., @Actor-1string
required
Reference type:
image- Regular reference image (list length 13; each5)image_urlslength 1grid- Grid collage, i.e., a single image composed of multiple tiles (e.g., 2×2, 3×3); list length must = 1,image_urlsmust be 1 image
string[]
required
Array of image URLs
string
Voice audio URL (only supported when
type=image, audio duration ≤ 15 seconds)object[]
Reference video list, up to 1. Each element has the following structure:
Show ref_videos element
Show ref_videos element
string
required
Must start with
@ and appear in the prompt, e.g., @video1string
required
Reference type:
reference- Motion / subject reference, overridesduration(follows the reference video length, max 10 seconds), carries input video audio by default; can be combined withref_images.type=imageextend- Video extension, billed by the requestedduration; cannot be combined withref_images
string
required
Video URL (MP4 / MOV, duration ≤ 15 seconds)
Supported Scenarios
The following scenarios are supported by bothskyreels-v4-fast and skyreels-v4-std:
| Scenario | Mode | Required Fields | Typical Use Case |
|---|---|---|---|
| Text-to-Video | T2V | prompt | Pure text-driven, rapid concept shots |
| Image-to-Video - First Frame | I2V | first_frame_image | Still-to-video with a specified starting frame |
| Image-to-Video - End Frame | I2V | end_frame_image | Specifies the closing frame |
| Image-to-Video - Keyframes | I2V | mid_frame_images (1 ~ 6) | First + end + mid keyframes for precise pacing |
| Omni Single/Multi-Subject | Omni | ref_images (type=image) | Character consistency, multi-subject framing |
| Omni Grid Collage | Omni | ref_images (type=grid, 1 image) | Step-by-step process videos (tutorials, recipes, demos) |
| Omni Motion Reference | Omni | ref_videos (type=reference) | Replicate the motion, subject, or style of a reference video |
| Omni Video Extension | Omni | ref_videos (type=extend) | Continue an existing video with new content |
| Omni Audio Sync | Omni | ref_images (type=image) + audio_url | Digital human narration, audio-driven lip-sync |
Parameter Constraints
Violating any of the following will cause the request to be rejected with a 422 response, no billing occurs:| Parameter | Constraint |
|---|---|
prompt | Max 1280 tokens |
duration | [3, 15] seconds; overridden by reference video length (max 10s) when ref_videos.type=reference |
resolution | Only 480p / 720p / 1080p |
aspect_ratio | 16:9 / 4:3 / 1:1 / 9:16 / 3:4; ignored in I2V; ignored when Omni carries ref_videos |
mid_frame_images | Up to 6; time_stamp must be -1 or within (0, duration) |
ref_images overall | All elements must share the same type; cannot coexist with I2V fields |
ref_images.type=grid | List length must = 1; image_urls must be 1 image |
ref_images.type=image | List length 1 ~ 3; each image_urls length 1 ~ 5 |
ref_images.audio_url | Only supported when type=image, audio ≤ 15 seconds |
ref_videos | Up to 1; video_url MP4 / MOV, ≤ 15 seconds |
ref_videos.type=reference | Overrides requested duration (max 10s), can combine with ref_images.type=image, carries input video audio by default |
ref_videos.type=extend | Billed by requested duration; cannot combine with ref_images |
tag field | Must start with @ and appear in the prompt |
| I2V / Omni exclusion | I2V fields and Omni fields cannot be used together |
Response
integer
Response status code, 200 on success
array
Request Examples
Case 1: Text-to-Video (Minimal)
{
"model": "skyreels-v4-fast",
"prompt": "A serene forest at sunset with golden light filtering through the trees."
}
Case 2: Text-to-Video (Full Parameters)
{
"model": "skyreels-v4-std",
"prompt": "A serene forest at sunset.",
"duration": 5,
"resolution": "720p",
"aspect_ratio": "16:9",
"prompt_optimizer": true
}
Case 3: Image-to-Video - First Frame
{
"model": "skyreels-v4-fast",
"prompt": "Slowly pull the camera back to reveal the entire scene.",
"first_frame_image": "https://example.com/start.png",
"duration": 5
}
Case 4: Image-to-Video - First/End Frame + Mid Keyframes
{
"model": "skyreels-v4-std",
"prompt": "The King summons a flying dragon. @image1 The dragon lowers. The King mounts and flies away.",
"duration": 8,
"resolution": "1080p",
"first_frame_image": "https://example.com/k2v_0.png",
"end_frame_image": "https://example.com/k2v_2.png",
"mid_frame_images": [
{ "tag": "@image1", "image_url": "https://example.com/k2v_1.png", "time_stamp": 3 }
]
}
Case 5: Omni - Single Subject Reference
{
"model": "skyreels-v4-fast",
"prompt": "@Actor-1 walks through a neon-lit street at night.",
"ref_images": [
{ "tag": "@Actor-1", "type": "image", "image_urls": ["https://example.com/actor.jpg"] }
]
}
Case 6: Omni - Multi-Subject + Video Motion Reference
{
"model": "skyreels-v4-fast",
"prompt": "The man from @image_1 imitates the move on the left in @video_1. The woman from @image_2 imitates the right side.",
"duration": 5,
"ref_images": [
{ "tag": "@image_1", "type": "image", "image_urls": ["https://example.com/a.png"] },
{ "tag": "@image_2", "type": "image", "image_urls": ["https://example.com/b.png"] }
],
"ref_videos": [
{ "tag": "@video_1", "type": "reference", "video_url": "https://example.com/motion.mp4" }
]
}
This case uses
ref_videos.type=reference, so the requested duration will be overridden by the actual reference video length (max 10 seconds). Even though "duration": 5 is passed here, the final video length follows the reference video.Case 7: Omni - Grid Collage
{
"model": "skyreels-v4-fast",
"prompt": "Create a video showing how to make tomato and egg noodles based on @image1.",
"ref_images": [
{ "tag": "@image1", "type": "grid", "image_urls": ["https://example.com/recipe_grid.png"] }
]
}
Case 8: Omni - Video Extension (extend)
{
"model": "skyreels-v4-fast",
"prompt": "Video extended @video1, someone walks over and sits on the sofa.",
"duration": 8,
"ref_videos": [
{ "tag": "@video1", "type": "extend", "video_url": "https://example.com/source.mp4" }
]
}
Case 9: Omni - Audio Sync (Voice-Driven)
{
"model": "skyreels-v4-std",
"prompt": "@Actor-1 speaks with a calm tone.",
"ref_images": [
{
"tag": "@Actor-1",
"type": "image",
"image_urls": ["https://example.com/actor.jpg"],
"audio_url": "https://example.com/voice.mp3"
}
]
}
Query Task ResultsVideo generation is an async task that returns a
task_id upon submission. Use the Get Task Status endpoint to query generation progress and results.⌘I