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": "요청 매개변수가 유효하지 않습니다",
"type": "invalid_request_error"
}
}
{
"error": {
"code": 401,
"message": "인증 실패, API 키를 확인해 주세요",
"type": "authentication_error"
}
}
{
"error": {
"code": 402,
"message": "계정 잔액이 부족합니다. 충전 후 다시 시도해 주세요",
"type": "payment_required"
}
}
{
"error": {
"code": 422,
"message": "매개변수가 상호 배타적이거나 유효하지 않은 값입니다 (예: I2V 및 Omni 필드를 동시에 전달)",
"type": "invalid_request_error"
}
}
{
"error": {
"code": 429,
"message": "요청이 너무 빈번합니다. 잠시 후 다시 시도해 주세요",
"type": "rate_limit_error"
}
}
{
"error": {
"code": 500,
"message": "서버 내부 오류. 잠시 후 다시 시도해 주세요",
"type": "server_error"
}
}
SkyReels V4
SkyReels V4 비디오 생성
- Fast(속도 우선)와 Std(품질 우선) 두 단계 모델 제공
- 텍스트-비디오(T2V), 이미지-비디오(I2V), 멀티모달 참조(Omni) 세 가지 모드를 요청 필드에 따라 자동 라우팅
- 480p / 720p / 1080p 해상도, 3 ~ 15초 길이 지원
- 첫/끝/키 프레임, 참조 이미지, 참조 비디오, 그리드 콜라주, 비디오 확장, 음성 동기화 등 고급 기능 지원
- 비동기 처리 모드, 후속 조회를 위한 작업 ID 반환
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": "요청 매개변수가 유효하지 않습니다",
"type": "invalid_request_error"
}
}
{
"error": {
"code": 401,
"message": "인증 실패, API 키를 확인해 주세요",
"type": "authentication_error"
}
}
{
"error": {
"code": 402,
"message": "계정 잔액이 부족합니다. 충전 후 다시 시도해 주세요",
"type": "payment_required"
}
}
{
"error": {
"code": 422,
"message": "매개변수가 상호 배타적이거나 유효하지 않은 값입니다 (예: I2V 및 Omni 필드를 동시에 전달)",
"type": "invalid_request_error"
}
}
{
"error": {
"code": 429,
"message": "요청이 너무 빈번합니다. 잠시 후 다시 시도해 주세요",
"type": "rate_limit_error"
}
}
{
"error": {
"code": 500,
"message": "서버 내부 오류. 잠시 후 다시 시도해 주세요",
"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": "요청 매개변수가 유효하지 않습니다",
"type": "invalid_request_error"
}
}
{
"error": {
"code": 401,
"message": "인증 실패, API 키를 확인해 주세요",
"type": "authentication_error"
}
}
{
"error": {
"code": 402,
"message": "계정 잔액이 부족합니다. 충전 후 다시 시도해 주세요",
"type": "payment_required"
}
}
{
"error": {
"code": 422,
"message": "매개변수가 상호 배타적이거나 유효하지 않은 값입니다 (예: I2V 및 Omni 필드를 동시에 전달)",
"type": "invalid_request_error"
}
}
{
"error": {
"code": 429,
"message": "요청이 너무 빈번합니다. 잠시 후 다시 시도해 주세요",
"type": "rate_limit_error"
}
}
{
"error": {
"code": 500,
"message": "서버 내부 오류. 잠시 후 다시 시도해 주세요",
"type": "server_error"
}
}
인증
모든 API 엔드포인트는 Bearer Token 인증이 필요합니다API 키 받기:API 키 관리 페이지를 방문하여 API 키를 받으세요요청 헤더에 추가하세요:
Authorization: Bearer YOUR_API_KEY
생성 모드
SkyReels V4는 요청 필드에 따라 자동으로 해당 모드로 라우팅됩니다.mode 필드를 지정할 필요가 없습니다:
| 모드 | 트리거 조건 | 기능 |
|---|---|---|
| T2V(텍스트-비디오) | prompt 및 공통 필드만 | 순수 텍스트 기반 생성 |
| I2V(이미지-비디오) | first_frame_image / end_frame_image / mid_frame_images 중 하나 | 첫/끝/키 프레임 제어 |
| Omni(멀티모달 참조) | ref_images / ref_videos 중 하나 | 주체 참조, 그리드 콜라주, 모션 참조, 비디오 확장, 음성 동기화 |
엄격한 상호 배타성: I2V 필드(
first_frame_image / end_frame_image / mid_frame_images)와 Omni 필드(ref_images / ref_videos)는 동시에 사용할 수 없으며, 위반 시 422를 반환합니다.@tag 메커니즘: mid_frame_images / ref_images / ref_videos를 사용할 때 각 요소는 @로 시작하는 tag(예: @image1, @Actor-1, @video1)를 선언해야 하며, 해당 tag는 반드시 prompt에 나타나야 합니다.prompt를 “대본”으로, tag를 구체적인 소재(이미지 / 비디오)를 가리키는 “캐릭터 포인터”로 이해할 수 있습니다. 예를 들어 prompt에 "@Actor-1이 @video1 장면에 들어간다"라고 쓰면, 시스템은 @Actor-1에 해당하는 참조 이미지의 주체와 @video1에 해당하는 모션 참조를 생성 과정에 주입합니다.요청 매개변수
공통 필드
다음 두 가지 등급을 지원합니다:
| 모델 | 포지셔닝 | 사용 사례 |
|---|---|---|
skyreels-v4-fast | 속도 우선 | 빠른 미리보기, 배치 생성, 일상 콘텐츠 |
skyreels-v4-std | 품질 우선 (Fast보다 25~30% 비쌈) | 핵심 장면, 고정밀 요구, 정식 납품 |
model 필드는 명시적으로 전달해야 하며 기본값이 없습니다.요금은 해상도 및
ref_videos 사용 여부와 밀접한 관련이 있습니다: 1080p는 480p / 720p보다 현저히 비싸며, ref_videos(비디오 입력 포함)는 비디오 입력이 없는 경우의 약 1.5 ~ 2배입니다. 오디오와 비디오 동시 출력은 아직 지원되지 않습니다.텍스트 프롬프트, 최대 1280 tokens장면, 주체, 동작, 스타일 등을 자세히 설명하면 더 나은 생성 결과를 얻을 수 있습니다.
ref_images / ref_videos / mid_frame_images를 사용할 때 prompt에는 해당하는 @tag(예: @Actor-1, @video1, @image1)가 반드시 포함되어야 합니다.예시: "@Actor-1 walks through a neon-lit street at night."출력 비디오 길이(초)
- 범위:
[3, 15] - 기본값:
5
ref_videos.type=reference를 전달하면 duration은 참조 비디오 길이로 덮어씌워집니다(상한 10초).비디오 해상도옵션:
480p720p1080p(기본값)
종횡비옵션:
16:9(기본값)4:31:19:163:4
I2V 모드에서는
aspect_ratio가 무시됩니다(출력 비율은 입력 이미지로 결정됨); Omni가 ref_videos를 포함할 때도 무시됩니다.prompt 자동 최적화 여부활성화하면 시스템이 자동으로 프롬프트를 최적화하여 더 나은 생성 결과를 얻을 수 있습니다.
I2V 전용 필드
비디오 시작 프레임 이미지 URL (jpg / jpeg / png / gif / bmp)전달하면 해당 이미지가 비디오의 시작 화면으로 사용됩니다.
비디오 끝 프레임 이미지 URL (jpg / jpeg / png / gif / bmp)전달하면 해당 이미지가 비디오의 끝 화면으로 사용됩니다.
first_frame_image와 결합하여 첫/끝 프레임 제어가 가능합니다.Omni 전용 필드
참조 이미지 목록(모든 요소의
type은 일치해야 함). 각 요소의 구조는 다음과 같습니다:표시 ref_images 요소
표시 ref_images 요소
@로 시작하고 prompt에 나타나야 합니다 (예: @Actor-1)참조 유형:
image- 일반 참조 이미지 (목록 길이 13; 각5)image_urls길이 1grid- 그리드 콜라주, 즉 여러 이미지를 하나로 합친 격자 이미지 (2×2, 3×3 등); 목록 길이는 반드시 = 1,image_urls는 1장 필수
이미지 URL 배열
음성(보이스) 동기화용 오디오 URL (
type=image만 지원, 오디오 길이 ≤ 15초)참조 비디오 목록, 최대 1개. 각 요소의 구조는 다음과 같습니다:
표시 ref_videos 요소
표시 ref_videos 요소
지원 생성 시나리오
다음 시나리오는skyreels-v4-fast와 skyreels-v4-std 모두 지원합니다:
| 시나리오 | 모드 | 필수 매개변수 | 대표 사용 사례 |
|---|---|---|---|
| 텍스트-비디오 | T2V | prompt | 텍스트 기반으로 콘셉트 쇼트 빠르게 생성 |
| 이미지-비디오 - 첫 프레임 | I2V | first_frame_image | 정지 이미지를 비디오로, 시작 화면 지정 |
| 이미지-비디오 - 끝 프레임 | I2V | end_frame_image | 비디오의 종료 화면 지정 |
| 이미지-비디오 - 키프레임 | I2V | mid_frame_images (1~6) | 첫·끝·중간 키프레임으로 샷(컷) 리듬 정밀 제어 |
| Omni 단일/다중 주체 참조 | Omni | ref_images (type=image) | 캐릭터 일관성, 다중 주체 동시 등장 |
| Omni 그리드 콜라주 | Omni | ref_images (type=grid, 1장) | 단계별 프로세스 비디오(튜토리얼, 레시피, 조작 데모) |
| Omni 모션 참조 | Omni | ref_videos (type=reference) | 참조 비디오의 동작, 주체, 스타일을 복제 |
| Omni 비디오 확장 | Omni | ref_videos (type=extend) | 기존 비디오에서 후속 전개 생성 |
| Omni 음성 동기화 | Omni | ref_images (type=image) + audio_url | 디지털 휴먼 내레이션, 오디오 기반 립싱크 |
매개변수 제약
다음 제약 중 하나라도 위반하면 요청이 거부되어 422를 반환하며, 과금되지 않습니다:| 매개변수 | 제약 |
|---|---|
prompt | 최대 1280 tokens |
duration | [3, 15]초; ref_videos.type=reference 시 참조 비디오 길이로 덮어씀(상한 10초) |
resolution | 480p / 720p / 1080p만 |
aspect_ratio | 16:9 / 4:3 / 1:1 / 9:16 / 3:4; I2V에서는 무시; Omni가 ref_videos를 포함할 때도 무시 |
mid_frame_images | 최대 6개; time_stamp는 -1 또는 (0, duration) 범위 내 |
ref_images 전체 | 목록 내 type은 일치해야 함; I2V 필드와 공존 불가 |
ref_images.type=grid | 목록 길이는 반드시 = 1; image_urls는 1장 필수 |
ref_images.type=image | 목록 길이 1image_urls 길이 1 |
ref_images.audio_url | type=image만 지원, 오디오 ≤ 15초 |
ref_videos | 최대 1개; video_url MP4 / MOV, ≤ 15초 |
ref_videos.type=reference | 요청의 duration 덮어씀(최대 10초), ref_images.type=image와 조합 가능, 기본적으로 입력 비디오 오디오를 가져옴 |
ref_videos.type=extend | 요청 duration으로 과금; ref_images와 조합 불가 |
tag 필드 | @로 시작하고 prompt에 나타나야 함 |
| I2V / Omni 배타 | I2V 필드와 Omni 필드는 동시 사용 불가 |
응답
응답 상태 코드, 성공 시 200
요청 예시
케이스 1: 텍스트-비디오 (최소)
{
"model": "skyreels-v4-fast",
"prompt": "A serene forest at sunset with golden light filtering through the trees."
}
케이스 2: 텍스트-비디오 (전체 매개변수)
{
"model": "skyreels-v4-std",
"prompt": "A serene forest at sunset.",
"duration": 5,
"resolution": "720p",
"aspect_ratio": "16:9",
"prompt_optimizer": true
}
케이스 3: 이미지-비디오 - 첫 프레임
{
"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
}
케이스 4: 이미지-비디오 - 첫/끝 프레임 + 중간 키프레임
{
"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 }
]
}
케이스 5: Omni - 단일 주체 참조
{
"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"] }
]
}
케이스 6: Omni - 다중 주체 + 비디오 모션 참조
{
"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" }
]
}
이 케이스는
ref_videos.type=reference를 사용하므로 요청의 duration은 참조 비디오의 실제 길이로 덮어씌워집니다(상한 10초). 여기서 "duration": 5를 전달해도 최종 비디오 길이는 참조 비디오에 따릅니다.케이스 7: Omni - 그리드 콜라주 (grid)
{
"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"] }
]
}
케이스 8: Omni - 비디오 확장 (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" }
]
}
케이스 9: Omni - 보이스 입력 (음향 동기화)
{
"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"
}
]
}
작업 결과 조회비디오 생성은 비동기 작업으로, 제출 후
task_id가 반환됩니다. 작업 상태 가져오기 엔드포인트를 사용하여 생성 진행 상황과 결과를 조회하세요.⌘I