HiAPI
Blog

Tutoriel

API vidu-q3-ad reference-to-video : curl, Python et une requête exécutable

Oct 20, 2026
API vidu-q3-ad reference-to-video : curl, Python et une requête exécutable

Ce que vous allez construire

Lancez un appel reference-to-video sur l'API asynchrone /v1/tasks de hiapi pour transformer 1 à 7 images produit statiques en une courte publicité vidéo avec audio natif. vidu-q3-ad/reference-to-video est le palier de Vidu Q3 destiné à la publicité : vous téléversez des images produit de référence, écrivez une description de plan, et le modèle renvoie un MP4 de 3 à 15 secondes, avec montage intelligent, mouvements de caméra et effets sonores générés — aucune piste audio séparée à fournir.

Il vous suffit de soumettre un seul POST, puis d'interroger (ou de recevoir un callback) jusqu'à ce que la tâche soit terminée, avant de télécharger le MP4. Commencez par récupérer votre clé depuis la console hiapi ; chaque requête ci-dessous utilise Authorization: Bearer sk-....

Trois éléments à recopier à l'identique :

  • Point de terminaison de soumission : POST https://api.hiapi.ai/v1/tasks
  • Point de terminaison d'interrogation : GET https://api.hiapi.ai/v1/tasks/{taskId}
  • ID du modèle : vidu-q3-ad/reference-to-video — la barre oblique et le suffixe -ad ne peuvent être omis ; vidu-q3-mix et vidu-q4-preview sont des points de terminaison différents.

Schéma d'entrée (obtenu par sondage en temps réel)

Champ Obligatoire Type Description
prompt Oui string Description du plan ; désignez les produits par leur numéro, par exemple « la montre de l'image de référence 1 »
reference_image_urls Oui array, 1–7 URL publiques des images produit statiques (récupérées côté serveur)
duration Oui integer, 3–15 Nombre de secondes ; doit être un entier (4.5 sera rejeté)
size Non enum (10 valeurs) Détermine à la fois le rapport d'aspect et le palier 720/1080 ; par défaut 1280*720

Le validateur est très strict — tout champ hors de la liste ci-dessus est directement rejeté. Deux types de rejet méritent d'être signalés, car ils piègent tous ceux qui migrent depuis d'autres modèles vidéo hiapi :

  • aspect_ratio et resolution sont tous deux rejetés. Presque tous les autres points de terminaison vidéo hiapi utilisent ces deux champs ; q3-ad non. Les dimensions ne se contrôlent que via size.
  • reference_audio_urls est également rejeté. Contrairement au palier reference-to-video de Vidu Q4 (qui accepte des extraits vocaux), q3-ad n'a aucune entrée audio — sa bande-son est générée nativement. (Voir la section de vérification ci-dessous pour savoir comment je l'ai confirmé.)

Comment choisir size

size est une chaîne width*height issue d'un ensemble fixe. On peut la lire comme une grille de cinq rapports d'aspect × deux paliers de qualité :

Rapport d'aspect Palier 720 Palier 1080
16:9 paysage 1280*720 1920*1080
9:16 portrait 720*1280 1080*1920
1:1 carré 1280*1280 1808*1808
4:3 1280*960 1920*1440
3:4 960*1280 1440*1920

Choisissez la ligne selon le support de diffusion (portrait 720*1280 / 1080*1920 pour Reels et TikTok, ligne paysage pour les annonces in-stream YouTube), et la colonne selon le compromis qualité/budget. La facturation se fait au nombre de secondes produites, et le palier détermine le prix par seconde — voir la tarification ; la facturation minimale correspond à un clip de 3 secondes.

Requête minimale (curl)

Deux étapes : soumettre, puis interroger.

# 1) Soumettre — renvoie un taskId
curl -s -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer sk-your-key" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "vidu-q3-ad/reference-to-video",
    "input": {
      "prompt": "Publicité produit de la montre connectée en titane de l'image de référence 1 : elle tourne lentement sur un socle sombre et réfléchissant tandis qu'une bande de lumière dure balaie le boîtier brossé de gauche à droite, l'écran reste éteint, la caméra garde un angle héroïque bas. Éclairage publicitaire, fort contraste, détail macro.",
      "reference_image_urls": [
        "https://your-cdn.com/watch-front.png",
        "https://your-cdn.com/watch-side.png"
      ],
      "duration": 5,
      "size": "1280*720"
    }
  }'
# -> {"data":{"taskId":"..."}}

# 2) Interroger jusqu'à ce que data.status vaille "success" ou "fail"
curl -s https://api.hiapi.ai/v1/tasks/THE_TASK_ID \
  -H "Authorization: Bearer sk-your-key"
# Succès -> data.status == "success", et data.output[0].url est le MP4

Les URL des images de référence doivent être accessibles publiquement — les tâches les récupèrent côté serveur, donc localhost ou une URL signée qui expire au bout de quelques secondes ne fonctionnera pas.

Python : soumettre, interroger, télécharger

import time
import requests  # ou utiliser urllib/subprocess pour rester sans dépendance

API = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": "Bearer sk-your-key", "Content-Type": "application/json"}

def submit():
    payload = {
        "model": "vidu-q3-ad/reference-to-video",
        "input": {
            "prompt": "Plan publicitaire de la basket de l'image de référence 1 tournant sur un plateau éclairé, "
                      "travelling avant lent, lumière de contour douce, cadrage produit héros.",
            "reference_image_urls": ["https://your-cdn.com/sneaker.png"],
            "duration": 5,
            "size": "1080*1920",   # portrait 1080p, pour Reels / TikTok
        },
    }
    body = requests.post(API, headers=HEADERS, json=payload, timeout=60).json()
    task_id = (body.get("data") or {}).get("taskId")
    if not task_id:
        raise RuntimeError(f"soumission rejetée : {body}")   # un 400 arrive ici
    return task_id

def wait(task_id, timeout_s=600, interval=5):
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        data = requests.get(f"{API}/{task_id}", headers=HEADERS, timeout=30).json().get("data") or {}
        status = data.get("status")
        if status == "success":
            return data["output"][0]["url"]
        if status == "fail":
            raise RuntimeError(f"tâche échouée : {data.get('error')}")
        time.sleep(interval)
    raise TimeoutError(task_id)

url = wait(submit())
mp4 = requests.get(url, timeout=120).content   # télécharger immédiatement — l'URL de sortie expire
open("ad.mp4", "wb").write(mp4)

Le rendu Q3-ad se termine généralement en une à deux minutes ; un intervalle d'interrogation de 5 secondes suffit largement. Les URL de sortie sont temporaires (elles portent un expireAt), donc téléchargez les octets immédiatement après le succès de la tâche, au lieu de les lier directement dans une page.

Mode production

Utilisez un callback plutôt que l'interrogation. Dans un contexte serveur, ajoutez un callback de premier niveau pour éviter de maintenir une boucle d'interrogation :

{
  "model": "vidu-q3-ad/reference-to-video",
  "input": { "prompt": "...", "reference_image_urls": ["..."], "duration": 5 },
  "callback": { "url": "https://your-app.com/hooks/hiapi", "when": "final" }
}

when n'accepte que "final" — le hook se déclenche une fois lorsque la tâche atteint un état terminal, et son corps de requête est identique à la charge renvoyée par GET /v1/tasks/{taskId}. Le hook peut être réessayé, donc dédupliquez par taskId et conservez une interrogation lente en secours au cas où une livraison serait perdue.

Branchez-vous sur le corps de la réponse, pas sur le code de statut HTTP. Un échec de rendu renvoie tout de même HTTP 200 ; l'information d'échec se trouve dans data.status == "fail", avec les détails dans data.error. Seuls les rejets au niveau de la requête (champ erroné, clé manquante, non authentifié) utilisent 4xx, avec un retour {"code":400,"error_code":"INVALID_REQUEST","message":"...","data":null}.

Idempotence. Chaque soumission crée une nouvelle tâche facturée, donc sauvegardez le taskId dès sa réception et interrogez à nouveau cet ID lors des retries. Ne soumettez jamais à nouveau à cause d'un simple timeout d'une requête d'interrogation.

Ce que j'ai vérifié

J'ai sondé le point de terminaison en production avec des valeurs invalides, qui sont rejetées gratuitement au stade de la validation — aucune tâche n'est créée et rien n'est facturé (les valeurs invalides échouent avant tout début de rendu, ce qui est plus sûr que d'omettre un champ). La réponse réelle fait office de schéma :

  • Corps de requête presque vide → reference_image_urls: missing required field ...; duration: missing required field .... Donc prompt, reference_image_urls et duration sont tous obligatoires.
  • duration: 99999 → maximum: got 99,999, want 15 ; duration: 1 → minimum: got 1, want 3 ; duration: 4.5 → got number, want integer. Duration est un entier de 3 à 15.
  • reference_image_urls avec 8 entrées → maxItems: got 8, want 7. La limite est de 7.
  • size: "9000p" → value must be one of '1280*720', '1280*960', '1280*1280', '960*1280', '720*1280', '1920*1080', '1920*1440', '1808*1808', '1440*1920', '1080*1920'.
  • aspect_ratio et resolution → les deux renvoient additional properties ... not allowed. Ce ne sont pas des champs de q3-ad ; utilisez size.
  • reference_audio_urls transmis sous forme de tableau correctement formaté → additional properties 'reference_audio_urls' not allowed. (S'il est transmis autrement qu'en tableau, une vérification média distincte se déclenche d'abord — « must be an array » — ce qui est trompeur : le champ n'est vraiment pas dans le schéma.) Ce palier n'a aucune entrée de référence vocale ; l'audio est généré nativement.

Il s'agit d'une référence d'intégration, donc elle ne contient aucune affirmation sur la qualité — je n'ai pas exécuté de rendu payant pour cet article. Pour voir à quoi ressemble un output[0].url réussi, la page modèle ci-dessous héberge l'exemple fourni avec ce point de terminaison : un vrai MP4 avec piste audio.

Guides associés

Questions fréquentes

Comment rendre le clip vertical ou horizontal ? Via size, pas aspect_ratio. Utilisez 720*1280 ou 1080*1920 pour le portrait, 1280*720 ou 1920*1080 pour le paysage.

Puis-je fournir une voix off ou une référence sonore ? Pas avec ce palier — reference_audio_urls est rejeté. Q3-ad génère lui-même son audio natif. Si vous devez piloter l'audio avec un extrait de référence, utilisez le palier reference-to-video de Vidu Q4.

Combien d'images produit puis-je envoyer ? De une à sept, dans reference_image_urls, en les désignant dans le prompt par leur numéro (« le flacon de l'image de référence 2 »).

Ma tâche renvoie 200 mais sans vidéo — pourquoi ? Regardez data.status. "fail" renvoie HTTP 200, la cause se trouve dans data.error ; seules les requêtes mal formées obtiennent un 4xx.

Combien cela coûte-t-il ? La facturation se fait au nombre de secondes produites, et le palier size (720 ou 1080) détermine le prix par seconde. Minimum : un clip de 3 secondes. Voir la tarification pour les tarifs actuels.

Articles similaires

Voir tous les articles →

Commencez avec des artefacts IA persistants

Obtenez votre clé API et appelez des modèles d'image, de vidéo et d'audio via une API unique basée sur les tasks.

Lire la documentation de l'API