Documentation API HappyHorse
Guide complet pour intégrer l’API de génération vidéo HappyHorse 1.0 dans vos applications.
Démarrage rapide
curl -X POST 'https://happyhorse.app/api/generate' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"model": "happyhorse-1.0/video",
"prompt": "A cinematic shot of mountains at sunrise",
"mode": "pro",
"duration": 5,
"aspect_ratio": "16:9"
}'Authentification
Toutes les requêtes API nécessitent un jeton Bearer dans l’en-tête Authorization.
Obtenir votre clé API: Vous pouvez obtenir votre clé API sur la page API Keys du tableau de bord. → Obtenir votre clé API
Authorization: Bearer YOUR_API_KEYFonctionnement de Generate et Status
Les tâches vidéo HappyHorse sont asynchrones : créez une tâche avec POST /api/generate, conservez la task_id retournée, puis appelez GET /api/status jusqu'à un état final.
Créer une tâche
Envoyez le prompt, le modèle, le mode, la durée et les images optionnelles à /api/generate. Une réponse réussie renvoie immédiatement task_id.
Interroger le statut
Utilisez task_id avec /api/status. Tant que le statut est IN_PROGRESS, la vidéo est encore générée et response reste null.
Lire le résultat
Quand le statut devient SUCCESS, data.response.resultUrls[0] est l'URL vidéo. En cas de FAILED, affichez error_message et arrêtez le polling.
Modèles disponibles
HappyHorse 1.0
Génération vidéo IA de haute qualité avec HappyHorse
| Type | Description | Durée | Crédits |
|---|---|---|---|
pro (text-to-video) | Texte vers vidéo qualité Pro | 3-15s | 54/s (no audio) · 80/s (with audio) |
pro (image-to-video) | Image vers vidéo qualité Pro | 3-15s | 54/s (no audio) · 80/s (with audio) |
std (text-to-video) | Texte vers vidéo qualité standard | 3-15s | 40/s (no audio) · 60/s (with audio) |
std (image-to-video) | Image vers vidéo qualité standard | 3-15s | 40/s (no audio) · 60/s (with audio) |
Points de terminaison API
Crée une tâche de génération vidéo. Le champ model doit être 'happyhorse-1.0/video'.
Corps de la requête
Nom du modèle, doit être 'happyhorse-1.0/video'
Description textuelle de la vidéo (max. 2500 caractères). Non requis si multi_shots est true.
Mode qualité : 'pro' ou 'std' (défaut : std) Defaults to std.
Durée en secondes (3–15). En mode multi-plans, la durée finale est déduite de multi_prompt ; si vous envoyez duration explicitement, elle doit correspondre à la somme des durées des plans. Defaults to 5 / sum(multi_prompt).
Format de sortie (16:9, 9:16, 1:1) Defaults to 16:9.
Tableau d’URLs d’images pour l’image vers vidéo
Activer l’audio natif (défaut : true). Pour les requêtes multi-plans, envoyez explicitement ce champ avec true ou false. Defaults to true.
Adhérence au prompt (0-1, défaut : 0.5). Les valeurs élevées suivent le prompt plus fidèlement. Defaults to 0.5.
Mode multi-plans avec plusieurs prompts Defaults to false.
Tableau d’objets 'prompt, duration' pour le mode multi-plans
Tableau d'objets décrivant chaque élément. Dans le prompt, écrivez @ suivi de la valeur du champ name (ex. : name 'element_dog' → @element_dog). Chaque élément : name, description, element_input_urls (2-4 URLs). Max. 3 éléments par tâche.
Texte vers vidéo
{
"model": "happyhorse-1.0/video",
"prompt": "A majestic eagle soaring through clouds at sunset",
"mode": "pro",
"duration": 5,
"aspect_ratio": "16:9",
"sound": true
}Image vers vidéo
{
"model": "happyhorse-1.0/video",
"prompt": "The character slowly turns and smiles",
"mode": "pro",
"image_urls": ["https://example.com/my-image.jpg"],
"duration": 5
}Vidéo multi-plans
{
"model": "happyhorse-1.0/video",
"mode": "pro",
"multi_shots": true,
"sound": true,
"duration": 10,
"multi_prompt": [
{ "prompt": "A woman walks into a coffee shop", "duration": 3 },
{ "prompt": "She orders a latte and sits by the window", "duration": 4 },
{ "prompt": "She looks outside and smiles", "duration": 3 }
],
"aspect_ratio": "16:9"
}Réponses
Task created successfully
{
"code": 200,
"message": "success",
"data": {
"task_id": "n92abc123hh10",
"status": "IN_PROGRESS"
}
}Vérifie le statut d’une génération vidéo avec le task_id renvoyé par l’endpoint generate.
Paramètres de requête
Identifiant unique renvoyé par generate (préfixe n92)
Exemple de requête
curl -X GET 'https://happyhorse.app/api/status?task_id=n92abc123hh10' \
-H 'Authorization: Bearer YOUR_API_KEY'Astuce: Le champ response contient un tableau resultUrls. Utilisez data.response.resultUrls[0] pour l’URL de la vidéo.
// Extract video URL after the task is complete
const task = payload.data;
const videoUrl = task.status === "SUCCESS"
? task.response?.resultUrls?.[0]
: null;Réponses
{
"code": 200,
"message": "success",
"data": {
"task_id": "n92abc123hh10",
"status": "SUCCESS",
"consumed_credits": 400,
"created_at": "2026-04-08T10:30:00Z",
"type": "text-to-video",
"request": {
"model": "happyhorse-1.0/video",
"prompt": "A majestic eagle soaring through clouds at sunset",
"mode": "pro",
"duration": 5,
"aspect_ratio": "16:9"
},
"response": {
"resultUrls": [
"https://cdn.example.com/videos/abc123.mp4"
]
},
"error_message": null
}
}Bonnes pratiques de polling
La génération vidéo peut prendre un peu de temps : traitez les vérifications de statut comme une tâche de fond calme, pas comme une boucle serrée.
Commencer avec un court délai
Attendez environ 8-10 secondes avant le premier contrôle, puis interrogez toutes les 10-20 secondes. Des requêtes plus fréquentes n'accélèrent pas la génération.
S'arrêter aux états finaux
SUCCESS et FAILED sont finaux. Arrêtez le polling dès que l'un apparaît, et conservez task_id pour le support ou une recherche ultérieure.
Utiliser un timeout client
Après 10-15 minutes, arrêtez l'attente active et laissez l'utilisateur relancer manuellement la vérification. Ne laissez pas un onglet interroger sans fin.
Ralentir en cas d'erreur
Si vous recevez 429 ou une erreur réseau temporaire, ralentissez avant la prochaine requête. Pour 401 ou 402, demandez à l'utilisateur de corriger la clé API ou les crédits.
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
async function waitForHappyHorseVideo(taskId) {
const deadline = Date.now() + 15 * 60 * 1000;
let delayMs = 8000;
while (Date.now() < deadline) {
const res = await fetch(
`${BASE_URL}/api/status?task_id=${encodeURIComponent(taskId)}`,
{ headers: { Authorization: `Bearer ${API_KEY}` } }
);
if (res.status === 429) {
await sleep(Math.min(delayMs * 2, 30000));
continue;
}
const payload = await res.json();
if (!res.ok) {
throw new Error(payload.message || `Status request failed: ${res.status}`);
}
const task = payload.data;
if (task.status === "SUCCESS") {
return task.response?.resultUrls?.[0];
}
if (task.status === "FAILED") {
throw new Error(task.error_message || "Generation failed");
}
await sleep(delayMs);
delayMs = Math.min(delayMs + 2000, 20000);
}
throw new Error("Timed out. Keep the task_id and check again later.");
}Bac à sable API
Testez l’API directement dans le navigateur. Remplacez YOUR_API_KEY par votre clé réelle.
Codes d’erreur
| Statut HTTP | Code | Description |
|---|---|---|
| 400 Requête incorrecte | INVALID_PROMPT | Le prompt est invalide ou vide |
| 400 Requête incorrecte | INVALID_DURATION | Durée hors plage prise en charge (3–15 s) |
| 400 Requête incorrecte | INVALID_MODEL | Le modèle doit être 'happyhorse-1.0/video' |
| 401 Non autorisé | INVALID_API_KEY | Clé API manquante ou invalide |
| 402 Paiement requis | INSUFFICIENT_CREDITS | Crédits insuffisants pour cette opération |
| 429 Trop de requêtes | RATE_LIMITED | Trop de requêtes, veuillez ralentir |
| 500 Erreur interne du serveur | INTERNAL_ERROR | Erreur serveur, réessayez plus tard |