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
Génération vidéo Wan3.0
- Modèle vidéo de référence tout-en-un Alibaba Cloud Wanxiang 3.0
- Texte-vers-vidéo / première image / première+dernière image / référence multimodale / référence fichier ou lien
- Résolution 480P / 720P / 1080P, durée 2–30 secondes
- Prend en charge images, vidéo, audio, documents et pages web publiques comme références
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"
}
}
Authentification
string
requis
Tous les endpoints exigent une authentification Bearer TokenObtenez votre API Key depuis la page de gestion des API Keys :
Authorization: Bearer YOUR_API_KEY
Modes de génération
Le nom du modèle est fixé àwan3.0-video. Les modes sont sélectionnés via les champs de la requête :
| Mode | Entrées typiques |
|---|---|
| Texte-vers-vidéo | prompt uniquement |
| Vidéo à partir de la première image | un élément dans image_urls (famille frame) |
| Première + dernière image | deux éléments dans image_urls, ou image_with_roles avec first_frame / last_frame |
| Vidéo de référence | images / vidéos / audio de référence ; le prompt peut utiliser des libellés du style « 图1 / 视频1 / 音频1 » |
| Référence fichier / page | file_url ou link_url (prompt optionnel) |
Paramètres de la requête
Bases
string
requis
Valeur fixe :
wan3.0-videoboolean
défaut:"false"
Indique s’il faut modérer le contenu avant d’envoyer la tâche vidéo.
true: vérifier les prompts et les images d’entrée avecomni-moderation-latestfalseou omis : ne pas envoyer de requête de modération, sans coût ni latence de modération supplémentaires (par défaut)
string
Description textuelle. Obligatoire sauf si des champs média sont fournis (au moins un parmi prompt ou média).
- Max 20 000 caractères ; le dépassement est tronqué automatiquement (sans erreur)
- En mode référence, utilisez « 图N / 视频N / 音频N » pour désigner les assets ; les indices suivent l’ordre au sein de chaque type de média
string
défaut:"1080P"
Résolution de sortie (insensible à la casse)
480P720P1080P(par défaut, prix le plus élevé)
Omettre
resolution facture au tarif 1080P. Passez explicitement 480P ou 720P lorsque le coût compte.string
défaut:"adaptive"
Rapport d’aspect.
aspect_ratio est également accepté.adaptive(par défaut)16:9/4:3/1:1/3:4/9:16
integer
défaut:"5"
Durée en secondes :
2–30: durée de sortie fixée (défaut5)-1: la durée est choisie par le modèle
Avec des vidéos de référence : durée totale en entrée + sortie ≤ 30 s. Avec
duration: -1, la durée choisie par le modèle doit aussi respecter cette contrainte.boolean
défaut:"true"
Indique si la sortie inclut une piste audio. Par défaut
true. Le prix est le même avec ou sans audio.integer
Graine aléatoire dans
[0, 2147483647]boolean
défaut:"false"
Indique s’il faut ajouter un filigrane. Par défaut
falsestring
Comment les
image_urls brutes sont classées :frame— famille première/dernière imagereference— famille de référence
Entrées média
string[]
Tableau d’URL d’images. L’attribution des rôles suit les règles d’exclusion mutuelle.URL publique ou Base64 (
data:image/png;base64,...).object[]
Images avec rôles explicites. Chaque élément :
url: adresse de l’imagerole:first_frame/last_frame/reference_image(alias courants acceptés)
string[]
Vidéos de référence, jusqu’à 5 clips ; chacun 1–15 s, total ≤ 15 s
string[]
Audio de référence, jusqu’à 5 clips ; chacun 1–15 s, total ≤ 15 s
string
Audio de référence unique (forme monovaleur de
audio_urls)string
URL de document de référence, au plus 1. Ne peut pas être combiné avec
link_url.Formats : docx / doc / xlsx / xls / pptx / ppt / pdf / txt / key / pages / numbers / md, ≤100 Mo, ≤50 pages.string
URL de page web publique, au plus 1. Pages sans connexion uniquement. Ne peut pas être combiné avec
file_url.Exclusion mutuelle des familles de médias
Les médias appartiennent à l’une des deux familles et ne doivent pas être mélangés (validé avant soumission → 400, pas de tâche, pas de facturation) :| Famille | Membres | Signification |
|---|---|---|
| Famille frame | first_frame, last_frame | Première / dernière image stricte de la vidéo |
| Famille de référence | reference_image, reference_video, reference_audio, file, link | Le modèle interprète le contenu librement |
Comment les image_urls brutes sont assignées
- Si
generation_typeest défini → l’utiliser (frame/reference) - Sinon, si la requête contient déjà des entrées de la famille de référence (
video_urls/audio_urls/audio_url/file_url/link_url) → traiter commereference_image - Sinon → famille frame : premier élément
first_frame, secondlast_frame(identique àwan2.7)
image_with_roles lorsque vous avez besoin d’un contrôle explicite.
Limites et formats des médias
| Type | Limites |
|---|---|
| Première / dernière image | ≤ 1 chacune |
| Images de référence | ≤ 10 |
| Vidéo de référence | ≤ 5 clips, 1–15 s chacun, total ≤15 s ; mp4/mov ; bord 240–4096 px, ratio ≤8:1, ≤100 Mo |
| Audio de référence | ≤ 5 clips, 1–15 s chacun, total ≤15 s ; wav/mp3 ; ≤15 Mo |
| Images | JPEG/JPG/PNG (sans alpha) / BMP / WEBP ; bord 240–8000 px, ratio ≤8:1, ≤20 Mo |
| Documents | ≤100 Mo, ≤50 pages |
| Pages web | URL publiques, sans connexion |
Exemples de requête
Texte-vers-vidéo
{
"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
}
Vidéo à partir de la première image
{
"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
}
Première + dernière image
{
"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
}
Référence multimodale
{
"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
}
Avecvideo_urlsprésent, lesimage_urlsbrutes se classent automatiquement comme images de référence ; définirgeneration_type: "reference"est plus clair.
Vidéo de référence par fichier
prompt peut être omis ; la génération est pilotée par le document :
{
"model": "wan3.0-video",
"file_url": "https://example.com/glass.pptx",
"resolution": "480P",
"duration": 10
}
Vidéo de référence par page web
{
"model": "wan3.0-video",
"prompt": "Turn this article into a short educational video",
"link_url": "https://example.com/article/123",
"duration": 15
}
Facturation
Par seconde × résolution (aligné sur le tarif officiel). Audio activé/désactivé ne change pas le prix :| Résolution | Prix unitaire | 5 s | 30 s |
|---|---|---|---|
| 480P | ¥0.30 / s | ¥1.50 | ¥9.00 |
| 720P | ¥0.60 / s | ¥3.00 | ¥18.00 |
| 1080P | ¥1.20 / s | ¥6.00 | ¥36.00 |
- Par défaut 1080P (le plus cher) ; passez
480P/720Plorsque le coût est sensible - Secondes facturables : pour
2–30, ladurationdemandée ; pour-1, les secondes réelles de sortie audio: true/falsen’affecte pas le prix
Limites et notes
| Élément | Notes |
|---|---|
| Durée | Entier 2–30, ou -1 (le modèle choisit la durée) |
| Avec entrée vidéo | Durée totale des vidéos d’entrée + durée de sortie ≤ 30 s |
| Latence | Typiquement 1–5 minutes ; plus long pour les clips longs |
| URL du résultat | Miroirée sur le CDN de la plateforme après succès pour un accès durable |
| Prompt | ≤20 000 caractères ; dépassement tronqué |
Erreurs courantes
Toutes sont des 400 synchrones (pas de tâche, pas de facturation) :| Cas | Que faire |
|---|---|
| Mélange des familles frame et référence | Choisir une famille via generation_type, ou définir les rôles avec image_with_roles |
file_url et link_url ensemble | En choisir un seul |
duration invalide | Uniquement 2–30 ou -1 |
| Résolution non prise en charge (ex. 4K) | Uniquement 480P / 720P / 1080P |
| Plus de 10 images de référence | Réduire à ≤10 |
prompt vide et médias vides | Fournir au moins l’un des deux |
Réponse
integer
Code de statut ; 200 en cas de succès
array
Consulter les résultatsLa génération vidéo est asynchrone. Interrogez Obtenir le statut de la tâche ou
GET /v1/videos/generations/{task_id}.Intervalle recommandé 5–10 secondes ; la génération prend généralement 1–5 minutes. En cas de succès, utilisez les URL dans result.videos.