HiAPI
Blog

Tutoriel

Appeler l'API texte-vers-vidéo HappyHorse 1.1 via HiAPI : un tutoriel curl + Python fonctionnel

Jun 27, 2026
Appeler l'API texte-vers-vidéo HappyHorse 1.1 via HiAPI : un tutoriel curl + Python fonctionnel
Modèle
happyhorse-1.1

HappyHorse 1.1 est le modèle texte-vers-vidéo d'Alibaba : il prend en charge des clips vidéo en 720p / 1080p, d'une durée de 3 à 15 secondes, et génère nativement l'audio en un seul appel (aucune étape séparée de bande sonore n'est nécessaire). HiAPI expose ce modèle via le même endpoint asynchrone unifié que tous les autres modèles génératifs ; ainsi, si vous avez déjà appelé des modèles d'image sur /v1/tasks, seuls l'id du modèle et quelques champs input changent.

Cette page fournit le minimum nécessaire pour livrer une intégration fonctionnelle : le schéma exact, un curl directement copiable, un client de polling en Python, et le mode de callback pour la production. Elle signale également deux choses peu évidentes que le modèle n'accepte pas (un commutateur audio et un seed), pour que vous ne gaspilliez pas une requête à cause d'une erreur 400.

Prérequis. Récupérez une clé depuis la console HiAPI et exportez-la sous HIAPI_API_KEY. Chaque requête s'authentifie via Authorization: Bearer sk-… ; pour un rappel, consultez Authentication.

Endpoint et structure de la requête

Tout passe par le même endpoint :

POST https://api.hiapi.ai/v1/tasks
Authorization: Bearer sk-<your-key>
Content-Type: application/json

Le corps de la requête comporte trois clés de premier niveau :

  • model — happyhorse-1.1/text-to-video (l'id littéral du modèle — conservez la barre oblique).
  • input — champs spécifiques au modèle. Pour HappyHorse 1.1 T2V :
    • prompt (chaîne, obligatoire) — décrit le clip vidéo.
    • resolution (720p | 1080p, par défaut 1080p).
    • aspect_ratio (16:9 | 9:16 | 3:4 | 4:3 | 4:5 | 5:4 | 1:1 | 9:21 | 21:9, par défaut 16:9).
    • duration (entier, 3–15, par défaut 5). Le coût augmente avec le nombre de secondes.
  • callback (facultatif, objet) — endpoint HTTPS callback.url + callback.when: "final". HiAPI envoie exactement une fois le résultat final à cette adresse pour chaque tâche.

Deux choses qui semblent devoir fonctionner mais qui ne fonctionnent pas :

  • ❌ Pas de champ audio. L'audio est généré nativement avec la vidéo ; il n'y a pas de commutateur. Envoyer "audio": true renvoie additional properties 'audio' not allowed.
  • ❌ Pas de champ seed. Renvoie également un 400. Si vous avez besoin de déterminisme par lot dès maintenant, générez plusieurs versions puis choisissez — il n'y a pas de levier seed ajustable.

Un corps de requête minimal valide :

{
  "model": "happyhorse-1.1/text-to-video",
  "input": {
    "prompt": "A golden retriever running on a beach, slow motion, gentle waves, warm sunset tones",
    "resolution": "1080p",
    "aspect_ratio": "16:9",
    "duration": 5
  }
}

Exemple minimal exécutable : curl

Créer une tâche — la réponse revient immédiatement et ne contient qu'un taskId :

curl -sS -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "happyhorse-1.1/text-to-video",
    "input": {
      "prompt": "A snow mountain lake in morning mist, slow camera push-in, warm cinematic light",
      "resolution": "1080p",
      "aspect_ratio": "16:9",
      "duration": 5
    }
  }'
# => {"code":200,"data":{"taskId":"tk-hiapi-01KW3..."},"message":"success"}

Puis interrogez en boucle jusqu'à atteindre un état terminal :

TASK_ID=tk-hiapi-01KW3...

curl -sS "https://api.hiapi.ai/v1/tasks/$TASK_ID" \
  -H "Authorization: Bearer $HIAPI_API_KEY"
# while .data.status is "handling", sleep a few seconds and retry.
# On success:
# {
#   "code": 200,
#   "data": {
#     "status": "success",
#     "model": "happyhorse-1.1/text-to-video",
#     "output": [
#       {"type":"video","url":"https://temp.hiapi.ai/.../...-0.mp4","expireAt":1783130616}
#     ],
#     ...
#   }
# }

L'URL du mp4 est temporaire (expireAt est un horodatage Unix situé environ 7 jours plus tard). Téléchargez et persistez immédiatement après le succès de la tâche — ne faites pas de hotlink. Si vous préférez que HiAPI gère le stockage à long terme, consultez la documentation Output Storage pour savoir comment promouvoir les sorties du stockage temporaire vers le stockage persistant.

Python : un client compact, prêt pour la production

Un vrai client a besoin de trois choses : un create_task qui renvoie un id, un wait_task qui interroge avec une échéance, et une étape de téléchargement. Ce squelette contient les trois et reste proche du point de départ de la page Python SDK de HiAPI — gardez-le compact, puis étendez-le.

# pip install requests
import os, time, json, requests

API_BASE = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}"}


def create_task(prompt: str, *, resolution="1080p", aspect_ratio="16:9", duration=5) -> str:
    body = {
        "model": "happyhorse-1.1/text-to-video",
        "input": {
            "prompt": prompt,
            "resolution": resolution,
            "aspect_ratio": aspect_ratio,
            "duration": duration,
        },
    }
    r = requests.post(API_BASE, headers={**HEADERS, "Content-Type": "application/json"},
                      data=json.dumps(body), timeout=60)
    r.raise_for_status()
    data = r.json()
    if data.get("code") != 200:
        raise RuntimeError(f"create failed: {data}")
    return data["data"]["taskId"]


def wait_task(task_id: str, *, timeout_s: int = 600, poll: int = 5) -> dict:
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        r = requests.get(f"{API_BASE}/{task_id}", headers=HEADERS, timeout=30)
        r.raise_for_status()
        task = r.json().get("data") or {}
        status = task.get("status")
        if status == "success":
            return task
        if status == "fail":
            raise RuntimeError(f"task {task_id} failed: {task.get('error')}")
        time.sleep(poll)
    raise TimeoutError(f"task {task_id} did not finish within {timeout_s}s")


def download(url: str, path: str) -> None:
    with requests.get(url, stream=True, timeout=120) as r:
        r.raise_for_status()
        with open(path, "wb") as f:
            for chunk in r.iter_content(1 << 14):
                f.write(chunk)


if __name__ == "__main__":
    task_id = create_task(
        "A neon street at night after rain, reflections on the ground, "
        "cyberpunk mood, slow pan",
        resolution="720p", aspect_ratio="9:16", duration=5,
    )
    task = wait_task(task_id)
    url = task["output"][0]["url"]
    download(url, "out.mp4")
    print("saved out.mp4")

Quelques points d'attention pour la production :

  • Champ de statut. Considérez toute valeur autre que success ou fail comme en cours (la plateforme utilise actuellement handling).
  • raise_for_status ne suffit pas. Pour certaines erreurs de validation, HiAPI renvoie HTTP 200 mais code n'est pas 200 — vérifiez aussi data["code"]. Pour une nouvelle intégration, le plus courant est 401 permission_denied, ce qui signifie que le token bearer est incorrect ou manquant — réexportez HIAPI_API_KEY et confirmez dans la console.

Production : préférez les callbacks au polling

Pour tout ce qui dépasse le démarrage rapide, fournissez à HiAPI un webhook qu'il appellera à la fin de la tâche :

{
  "model": "happyhorse-1.1/text-to-video",
  "input": {
    "prompt": "A snow mountain lake in morning mist, slow camera push-in, warm cinematic light",
    "resolution": "1080p",
    "aspect_ratio": "16:9",
    "duration": 5
  },
  "callback": {
    "url": "https://your-domain.com/hiapi/callback",
    "when": "final"
  }
}

Assurez-vous que votre gestionnaire de callback fait ce qui suit :

  • Dédupliquez par taskId. success et fail sont des états terminaux — votre service doit traiter deux réceptions du même taskId comme une opération vide (écriture idempotente indexée par taskId).
  • Renvoyez rapidement un 2xx. Placez le travail lourd (télécharger le mp4, persister, notifier l'utilisateur) dans une file d'attente. Le gestionnaire de webhook doit accuser réception en quelques secondes.
  • Conservez GET /v1/tasks/:id comme solution de repli. Si le webhook est perdu (déploiement, coupure réseau), une tâche périodique de réconciliation qui récupère par id les tâches bloquées et applique le même gestionnaire est le filet de sécurité le plus simple.

Si vous devez choisir une seule voie : le polling convient aux scripts ponctuels et au débogage local, tandis que tout ce qui a du trafic réel devrait utiliser les callbacks.

Choisir les bons paramètres (resolution × aspect_ratio × duration)

Besoin resolution aspect_ratio duration
Clip vertical court pour les réseaux sociaux, coût le plus bas 720p 9:16 5
Aperçu carré / boucle de vignette 720p 1:1 3
Narration horizontale / plan publicitaire 1080p 16:9 5–8
Clip de visuel principal au format large 1080p 21:9 8–12

Le coût augmente avec la résolution et la durée — consultez la tarification HiAPI pour le prix exact par seconde. En cas de doute sur la bonne valeur, ne la renseignez pas : resolution vaut par défaut 1080p, aspect_ratio vaut par défaut 16:9, et duration vaut par défaut 5.

Questions fréquentes

Le texte-vers-vidéo HappyHorse 1.1 a-t-il un paramètre seed ? Non. L'API rejette seed avec additional properties 'seed' not allowed. Si vous avez besoin de plusieurs options pour choisir, soumettez plusieurs tâches avec le même prompt — des exécutions différentes produisent naturellement des variations.

Comment activer ou désactiver l'audio ? Vous ne pouvez pas — HappyHorse 1.1 génère la piste audio nativement dans le même appel. Il n'y a pas de commutateur audio dans le schéma ; en envoyer un renvoie un 400. Si vous avez besoin d'un clip muet, retirez l'audio en post-production.

Quelles sont les durées valides ? Un entier de 3 à 15 (secondes). Toute valeur hors de cette plage renvoie duration: minimum: got 0, want 3 ou duration: maximum: got 20, want 15. Les décimales sont également rejetées (le type du champ est entier).

Quels ratios d'image sont pris en charge ? Neuf : 16:9, 9:16, 3:4, 4:3, 4:5, 5:4, 1:1, 9:21, 21:9. Par défaut 16:9.

Combien de temps output[].url reste-t-il valide ? Environ une semaine — la réponse contient un horodatage Unix expireAt. Téléchargez immédiatement le mp4 et réhébergez-le (S3, R2, votre CDN), ou promouvez-le en stockage persistant via l'Output Storage API.

Et le image-vers-vidéo ? HappyHorse 1.1 dispose d'une variante I2V sur le même endpoint — consultez HappyHorse 1.1 I2V. Même authentification, même cycle de vie asynchrone, schéma input différent.

Où se trouve la référence complète de l'API asynchrone ? L'enveloppe de requête est décrite dans Create Task, l'endpoint de polling dans Get Task Detail, et le schéma d'entrée canonique dans la page du modèle HappyHorse 1.1 T2V. Si vous partez de zéro, le Quickstart vous guide de bout en bout pour votre premier appel.

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