curl --request POST \
--url https://api.apimart.ai/v1/videos/generations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"model": "wan3.0-video",
"prompt": "A kitten runs across a moonlit rooftop, neon lights of the city flicker in the distance, cinematic quality, smooth camera move.",
"resolution": "720P",
"size": "16:9",
"duration": 5
}'
import requests
url = "https://api.apimart.ai/v1/videos/generations"
payload = {
"model": "wan3.0-video",
"prompt": "A kitten runs across a moonlit rooftop, neon lights of the city flicker in the distance, cinematic quality, smooth camera move.",
"resolution": "720P",
"size": "16:9",
"duration": 5,
}
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: "wan3.0-video",
prompt: "A kitten runs across a moonlit rooftop, neon lights of the city flicker in the distance, cinematic quality, smooth camera move.",
resolution: "720P",
size: "16:9",
duration: 5,
};
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": "wan3.0-video",
"prompt": "A kitten runs across a moonlit rooftop",
"resolution": "720P",
"size": "16:9",
"duration": 5,
}
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))
}
{
"code": 200,
"data": [
{
"status": "submitted",
"task_id": "task_01J9HA7JPQ9A0Z6JZ3V8M9W6PZ"
}
]
}
{
"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": 429,
"message": "Too many requests, please try again later",
"type": "rate_limit_error"
}
}
Wan3.0
Generasi Video Wan3.0
- Model video referensi all-in-one Alibaba Cloud Wanxiang 3.0
- Teks-ke-video / frame pertama / frame pertama+terakhir / referensi multimodal / referensi file atau tautan
- Resolusi 480P / 720P / 1080P, durasi 2–30 detik
- Mendukung gambar, video, audio, dokumen, dan halaman web publik sebagai referensi
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": "wan3.0-video",
"prompt": "A kitten runs across a moonlit rooftop, neon lights of the city flicker in the distance, cinematic quality, smooth camera move.",
"resolution": "720P",
"size": "16:9",
"duration": 5
}'
import requests
url = "https://api.apimart.ai/v1/videos/generations"
payload = {
"model": "wan3.0-video",
"prompt": "A kitten runs across a moonlit rooftop, neon lights of the city flicker in the distance, cinematic quality, smooth camera move.",
"resolution": "720P",
"size": "16:9",
"duration": 5,
}
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: "wan3.0-video",
prompt: "A kitten runs across a moonlit rooftop, neon lights of the city flicker in the distance, cinematic quality, smooth camera move.",
resolution: "720P",
size: "16:9",
duration: 5,
};
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": "wan3.0-video",
"prompt": "A kitten runs across a moonlit rooftop",
"resolution": "720P",
"size": "16:9",
"duration": 5,
}
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))
}
{
"code": 200,
"data": [
{
"status": "submitted",
"task_id": "task_01J9HA7JPQ9A0Z6JZ3V8M9W6PZ"
}
]
}
{
"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": 429,
"message": "Too many requests, please try again later",
"type": "rate_limit_error"
}
}
curl --request POST \
--url https://api.apimart.ai/v1/videos/generations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"model": "wan3.0-video",
"prompt": "A kitten runs across a moonlit rooftop, neon lights of the city flicker in the distance, cinematic quality, smooth camera move.",
"resolution": "720P",
"size": "16:9",
"duration": 5
}'
import requests
url = "https://api.apimart.ai/v1/videos/generations"
payload = {
"model": "wan3.0-video",
"prompt": "A kitten runs across a moonlit rooftop, neon lights of the city flicker in the distance, cinematic quality, smooth camera move.",
"resolution": "720P",
"size": "16:9",
"duration": 5,
}
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: "wan3.0-video",
prompt: "A kitten runs across a moonlit rooftop, neon lights of the city flicker in the distance, cinematic quality, smooth camera move.",
resolution: "720P",
size: "16:9",
duration: 5,
};
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": "wan3.0-video",
"prompt": "A kitten runs across a moonlit rooftop",
"resolution": "720P",
"size": "16:9",
"duration": 5,
}
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))
}
{
"code": 200,
"data": [
{
"status": "submitted",
"task_id": "task_01J9HA7JPQ9A0Z6JZ3V8M9W6PZ"
}
]
}
{
"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": 429,
"message": "Too many requests, please try again later",
"type": "rate_limit_error"
}
}
Autentikasi
string
wajib
Semua endpoint memerlukan autentikasi Bearer TokenDapatkan API Key Anda dari Halaman Manajemen API Key:
Authorization: Bearer YOUR_API_KEY
Mode Generasi
Nama model adalahwan3.0-video atau wan3.0-video-prime (parameter sama). Mode dipilih melalui field permintaan:
| Mode | Input tipikal |
|---|---|
| Teks-ke-video | hanya prompt |
| Video frame pertama | satu item di image_urls (keluarga frame) |
| Frame pertama + terakhir | dua item di image_urls, atau image_with_roles dengan first_frame / last_frame |
| Video referensi | gambar / video / audio referensi; prompt dapat memakai label gaya “图1 / 视频1 / 音频1” |
| Referensi file / halaman | file_url atau link_url (prompt opsional) |
Parameter Permintaan
Dasar
string
wajib
Nama model pembuatan video. Nilai yang diizinkan:
wan3.0-videowan3.0-video-prime
boolean
default:"false"
Menentukan apakah moderasi konten dijalankan sebelum tugas video dikirim.
true: periksa prompt dan gambar input denganomni-moderation-latestfalseatau dihilangkan: tidak mengirim permintaan moderasi, tanpa biaya atau latensi moderasi tambahan (default)
string
Deskripsi teks. Wajib kecuali field media disediakan (setidaknya salah satu dari prompt atau media).
- Maks 20.000 karakter; kelebihan dipotong otomatis (tanpa error)
- Dalam mode referensi, gunakan “图N / 视频N / 音频N” untuk merujuk aset; indeks mengikuti urutan dalam setiap jenis media
string
default:"1080P"
Resolusi keluaran (tidak peka huruf besar/kecil)
480P720P1080P(default, harga tertinggi)
Menghilangkan
resolution akan ditagih pada 1080P. Kirim 480P atau 720P secara eksplisit bila biaya penting.string
default:"adaptive"
Rasio aspek.
aspect_ratio juga diterima.adaptive(default)16:9/4:3/1:1/3:4/9:16
integer
default:"5"
Durasi dalam detik:
2–30: durasi keluaran tetap (default5)-1: durasi ditentukan model
Jika ada video referensi: total durasi input + output ≤ 30 detik. Dengan
duration: -1, durasi yang dipilih model tetap harus memenuhi batasan ini.boolean
default:"true"
Apakah keluaran menyertakan trek audio. Default
true. Harga sama dengan atau tanpa audio.integer
Seed acak di
[0, 2147483647]boolean
default:"false"
Apakah menambahkan watermark. Default
falsestring
Cara
image_urls tanpa peran eksplisit diklasifikasikan:frame— keluarga frame pertama/terakhirreference— keluarga referensi
Input media
string[]
Array URL gambar. Penugasan peran mengikuti aturan saling eksklusif.Hanya URL publik.
object[]
Gambar dengan peran eksplisit. Setiap item:
url: alamat gambarrole:first_frame/last_frame/reference_image(alias umum diterima)
string[]
Video referensi, hingga 5 klip; masing-masing 1–15 d, total ≤ 15 d
string[]
Audio referensi, hingga 5 klip; masing-masing 1–15 d, total ≤ 15 d
string
Audio referensi tunggal (bentuk nilai tunggal dari
audio_urls)string
URL dokumen referensi, paling banyak 1. Tidak dapat digabungkan dengan
link_url.Format meliputi docx / doc / xlsx / xls / pptx / ppt / pdf / txt / key / pages / numbers / md, ≤100MB, ≤50 halaman.string
URL halaman web publik, paling banyak 1. Hanya halaman tanpa login. Tidak dapat digabungkan dengan
file_url.Saling Eksklusif Keluarga Media
Media termasuk salah satu dari dua keluarga dan tidak boleh digabung (divalidasi sebelum submit → 400, tanpa tugas, tanpa biaya):| Keluarga | Anggota | Arti |
|---|---|---|
| Keluarga frame | first_frame, last_frame | Frame pertama / terakhir ketat dari video |
| Keluarga referensi | reference_image, reference_video, reference_audio, file, link | Model menafsirkan konten secara bebas |
Cara image_urls tanpa peran ditetapkan
- Jika
generation_typedisetel → gunakan itu (frame/reference) - Jika tidak, dan permintaan sudah memiliki input keluarga referensi (
video_urls/audio_urls/audio_url/file_url/link_url) → perlakukan sebagaireference_image - Jika tidak → keluarga frame: item pertama
first_frame, kedualast_frame(sama sepertiwan2.7)
image_with_roles bila Anda membutuhkan kontrol eksplisit.
Batas dan format media
| Jenis | Batas |
|---|---|
| Frame pertama / terakhir | ≤ 1 masing-masing |
| Gambar referensi | ≤ 10 |
| Video referensi | ≤ 5 klip, 1–15 d masing-masing, total ≤15 d; mp4/mov; tepi 240–4096 px, rasio ≤8:1, ≤100MB |
| Audio referensi | ≤ 5 klip, 1–15 d masing-masing, total ≤15 d; wav/mp3; ≤15MB |
| Gambar | JPEG/JPG/PNG (tanpa alpha) / BMP / WEBP; tepi 240–8000 px, rasio ≤8:1, ≤20MB |
| Dokumen | ≤100MB, ≤50 halaman |
| Halaman web | URL publik, tanpa login |
Contoh Permintaan
Teks-ke-video
{
"model": "wan3.0-video",
"prompt": "A kitten runs across a moonlit rooftop, neon lights of the city flicker in the distance, cinematic quality, smooth camera move.",
"resolution": "720P",
"size": "16:9",
"duration": 5
}
Video frame pertama
{
"model": "wan3.0-video",
"prompt": "The person in the frame starts freestyle rapping, camera slowly pushes in",
"image_urls": ["https://example.com/first.png"],
"resolution": "720P",
"duration": 5
}
Frame pertama + terakhir
{
"model": "wan3.0-video",
"prompt": "Smile gradually becomes laughter, background light shifts from cool to warm",
"image_urls": [
"https://example.com/first.png",
"https://example.com/last.jpg"
],
"duration": 5
}
image_with_roles:
{
"model": "wan3.0-video",
"prompt": "Smile gradually becomes laughter",
"image_with_roles": [
{"url": "https://example.com/first.png", "role": "first_frame"},
{"url": "https://example.com/last.jpg", "role": "last_frame"}
],
"duration": 5
}
Referensi multimodal
{
"model": "wan3.0-video",
"prompt": "视频1抱着图1,在图3的椅子上弹奏一支舒缓的乡村民谣,并说道:\"今天的阳光真好。\"",
"generation_type": "reference",
"image_urls": [
"https://example.com/object1.jpg",
"https://example.com/object2.png",
"https://example.com/chair.png"
],
"video_urls": ["https://example.com/role.mp4"],
"resolution": "480P",
"duration": 5
}
Denganvideo_urlshadir,image_urlstanpa peran otomatis diklasifikasikan sebagai gambar referensi; mengaturgeneration_type: "reference"lebih jelas.
Video referensi file
prompt boleh dihilangkan; generasi didorong oleh dokumen:
{
"model": "wan3.0-video",
"file_url": "https://example.com/glass.pptx",
"resolution": "480P",
"duration": 10
}
Video referensi halaman web
{
"model": "wan3.0-video",
"prompt": "Turn this article into a short educational video",
"link_url": "https://example.com/article/123",
"duration": 15
}
Penagihan
Per detik × resolusi (selaras dengan harga resmi). Audio on/off tidak mengubah harga:| Resolusi | Harga satuan | 5 d | 30 d |
|---|---|---|---|
| 480P | ¥0.30 / d | ¥1.50 | ¥9.00 |
| 720P | ¥0.60 / d | ¥3.00 | ¥18.00 |
| 1080P | ¥1.20 / d | ¥6.00 | ¥36.00 |
- Default adalah 1080P (paling mahal); kirim
480P/720Pbila sensitif biaya - Detik yang ditagih: untuk
2–30,durationyang diminta; untuk-1, detik keluaran aktual audio: true/falsetidak memengaruhi harga
Batasan dan Catatan
| Item | Catatan |
|---|---|
| Durasi | Bilangan bulat 2–30, atau -1 (model menentukan durasi) |
| Dengan input video | Total durasi video input + durasi keluaran ≤ 30 d |
| Latensi | Biasanya 1–5 menit; lebih lama untuk klip panjang |
| URL hasil | Dicerminkan ke CDN platform setelah sukses untuk akses jangka panjang |
| Prompt | ≤20.000 karakter; kelebihan dipotong |
Error Umum
Semua adalah 400 sinkron (tanpa tugas, tanpa biaya):| Kasus | Yang harus dilakukan |
|---|---|
| Mencampur keluarga frame dan referensi | Pilih satu keluarga lewat generation_type, atau setel peran dengan image_with_roles |
file_url dan link_url bersamaan | Pilih salah satu |
duration tidak valid | Hanya 2–30 atau -1 |
| Resolusi tidak didukung (mis. 4K) | Hanya 480P / 720P / 1080P |
| Lebih dari 10 gambar referensi | Kurangi menjadi ≤10 |
prompt kosong dan media kosong | Sediakan setidaknya salah satu |
Respons
integer
Kode status; 200 jika sukses
array
Kueri hasilGenerasi video bersifat asinkron. Poll Dapatkan Status Tugas atau
GET /v1/videos/generations/{task_id}.Interval yang direkomendasikan 5–10 detik; generasi biasanya memakan waktu 1–5 menit. Saat sukses, gunakan URL di result.videos.