how-tos

Guide de l’API MiniMax H3 : intégration avec PoYo, tarifs et prompts

Poyo.ai Team
Updated
16 min read
Share:

Avec l’API MiniMax H3 de PoYo, vous pouvez générer des vidéos 2K de 5–15 secondes à partir de texte, d’images de début et de fin, ou de médias de référence. Sans média de référence, une vidéo de 5 secondes coûte environ 105 crédits ($0.525).

Ce guide commence par une première requête, puis présente les tarifs, les modes d’entrée, des exemples Python et Node.js, et des prompts pour différentes scènes. Tous les endpoints et tarifs indiqués concernent PoYo.

Démarrage rapide : soumettre une tâche et récupérer la vidéo

1. Soumettre une tâche vidéo de 5 secondes

Obtenez une clé API dans la console PoYo, remplacez YOUR_POYO_API_KEY ci-dessous, puis exécutez la commande dans un terminal ou sur votre serveur. Conservez la clé côté serveur ; ne l’intégrez ni au code du navigateur ni à un dépôt public.

Dans les requêtes PoYo, la valeur de model pour MiniMax H3 est hailuo-03. L’exemple suivant soumet une tâche de génération payante.

export POYO_API_KEY="YOUR_POYO_API_KEY"

curl --fail-with-body --max-time 30 \
  --request POST 'https://api.poyo.ai/api/generate/submit' \
  --header "Authorization: Bearer ${POYO_API_KEY}" \
  --header 'Content-Type: application/json' \
  --data '{
    "model": "hailuo-03",
    "input": {
      "prompt": "A golden retriever walks through a sunlit autumn park. One slow tracking shot, natural movement, warm afternoon light.",
      "duration": 5,
      "resolution": "2K",
      "aspect_ratio": "16:9"
    }
  }'

Après une soumission réussie, récupérez l’identifiant de tâche dans data.task_id. Cet exemple présente la structure de réponse avec un identifiant fictif :

{
  "code": 200,
  "message": "success",
  "data": {
    "task_id": "YOUR_TASK_ID"
  }
}

2. Consulter le résultat de la tâche

Affectez l’identifiant reçu à TASK_ID et utilisez la même clé API :

TASK_ID="YOUR_TASK_ID"

curl --fail-with-body --max-time 30 \
  --request GET "https://api.poyo.ai/api/generate/status/${TASK_ID}" \
  --header "Authorization: Bearer ${POYO_API_KEY}"

Une soumission réussie signifie que la tâche a été acceptée ; il faut encore attendre la fin de la génération. Le champ data.status de la réponse de consultation peut prendre quatre valeurs :

StatutSignificationÉtape suivante
not_startedEn attente de traitementConsulter de nouveau plus tard
runningGénération en coursConsulter de nouveau plus tard
finishedGénération terminéeLire data.files[].file_url
failedÉchec de la générationConsulter data.error_message et arrêter les requêtes périodiques

Voici un exemple de réponse après traitement. L’URL et l’horodatage sont fictifs :

{
  "code": 200,
  "data": {
    "task_id": "YOUR_TASK_ID",
    "status": "finished",
    "credits_amount": 105,
    "files": [
      {
        "file_url": "https://example.com/generated/video.mp4",
        "file_type": "video"
      }
    ],
    "created_time": "2026-09-22T08:30:00",
    "progress": 100,
    "error_message": null
  }
}

Consultez la documentation de suivi des tâches PoYo pour les définitions des champs et les réponses correspondant aux autres statuts. Si une consultation échoue temporairement ou si votre délai d’attente expire, conservez l’identifiant et réessayez plus tard ; ne soumettez pas automatiquement une nouvelle génération payante.

Comment MiniMax H3 est facturé sur PoYo

Les tarifs ci-dessous ont été vérifiés le 21 septembre 2026. Tous les montants sont en USD, à raison de 1 crédit = $0.005. Avant de générer en volume, vérifiez les tarifs actuels sur la page du modèle.

Élément facturéCréditsUSD
Durée de la vidéo générée21 crédits/seconde$0.105/seconde
Durée de la vidéo de référence fournie21 crédits/seconde$0.105/seconde
5 premières images de référence par génération0$0
Chaque image de référence à partir de la 6e6.4 crédits$0.032

Crédits estimés = 21 × (secondes de sortie + secondes facturables de vidéo de référence) + 6.4 × nombre d’images de référence au-delà de 5. Avec 5 images ou moins, le supplément pour les images est de 0. Multipliez les crédits estimés par $0.005 pour obtenir le coût en USD. Si la vidéo de référence contient des fractions de seconde, la facturation utilise la durée retenue par le serveur.

ExempleCrédits estimésUSD estimés
Générer 5 secondes sans média de référence105$0.525
Générer 10 secondes sans média de référence210$1.05
Générer 15 secondes sans média de référence315$1.575
Générer 10 secondes + 5 secondes de vidéo de référence + 7 images de référence327.8$1.639

Le dernier exemple utilise 21 × (10 + 5) + 6.4 × (7 − 5). Il s’agit de coûts par génération ; si un plan nécessite plusieurs essais, prévoyez chaque génération dans votre budget.

Choisir le mode d’entrée et les médias de référence

Les champs multimédias envoyés déterminent le mode d’entrée. L’exemple de démarrage rapide utilise la génération à partir de texte. Ajoutez les champs appropriés pour définir des images de début et de fin ou utiliser des références.

ModeChamps d’entréeUtilisation
Texte vers vidéoprompt, sans URL de médiaDécrire la scène, l’action et le mouvement de caméra avec des mots
Génération avec images de début et de finimage_urlsLa première image définit le début ; la seconde, facultative, définit la fin. Omettre aspect_ratio : le ratio est celui de la première image
Génération avec références multimodalesreference_image_urls, reference_video_urls, reference_audio_urlsCombiner images, vidéo et audio ; une référence audio nécessite une image ou une vidéo de référence

Ne combinez pas image_urls avec un champ reference_*_urls. Toutes les URL de médias doivent être accessibles publiquement et permettre un téléchargement direct.

Limites des paramètres et des médias

Les limites suivantes proviennent de la documentation de l’API MiniMax H3 de PoYo :

  • prompt est obligatoire et accepte jusqu’à 2000 caractères.
  • duration est un entier de 5–15 secondes, avec 5 par défaut ; resolution accepte uniquement 2K.
  • Le mode texte vers vidéo accepte 21:9, 16:9, 4:3, 1:1, 3:4 et 9:16, avec 16:9 par défaut. Le mode référence accepte aussi adaptive et l’utilise par défaut.
  • Vous pouvez fournir jusqu’à 9 images, 3 vidéos et 3 extraits audio de référence. Chaque vidéo ou extrait audio doit durer 2–15 secondes ; la durée totale des vidéos et celle des extraits audio ne doivent pas dépasser 15 secondes chacune.

Exemple de requête avec images de début et de fin

Utilisez le JSON ci-dessous comme corps de POST /api/generate/submit. Les URL sous example.com sont des valeurs fictives : remplacez-les par vos propres médias téléchargeables avant l’envoi. Pour utiliser uniquement une image de début, supprimez la seconde URL du tableau.

{
  "model": "hailuo-03",
  "input": {
    "prompt": "The camera slowly moves through the temple doorway, starting at the entrance and ending inside the hall. Dust floats in the sunlight.",
    "duration": 6,
    "resolution": "2K",
    "image_urls": [
      "https://example.com/assets/temple-entrance.jpg",
      "https://example.com/assets/temple-interior.jpg"
    ]
  }
}

Exemple combinant des références image et vidéo

Utilisez Image 1 pour l’apparence du personnage et Video 1 pour le mouvement de caméra souhaité. Ces noms désignent respectivement le premier élément du tableau d’images et du tableau de vidéos. Remplacez les URL et vérifiez la durée de la vidéo de référence avant l’envoi.

{
  "model": "hailuo-03",
  "input": {
    "prompt": "Use Image 1 for the character appearance and outfit. The character turns and walks toward the window. Use Video 1 as the camera movement reference.",
    "duration": 8,
    "resolution": "2K",
    "aspect_ratio": "adaptive",
    "reference_image_urls": [
      "https://example.com/assets/character.png"
    ],
    "reference_video_urls": [
      "https://example.com/assets/camera-motion.mp4"
    ]
  }
}

Exemples d’intégration avec Python et Node.js

Les exemples séparent la soumission et la consultation en deux fonctions : obtenez et enregistrez d’abord l’identifiant, puis attendez le résultat. Si la consultation est interrompue, reprenez-la avec l’identifiant initial sans relancer la génération. Seules les consultations de statut réessaient après une erreur de connexion, un délai dépassé, HTTP 429 ou certaines erreurs 5xx ; la soumission n’est pas réessayée automatiquement.

Les deux implémentations attendent 10 secondes entre les consultations, effectuent au plus 60 consultations et fixent un délai de 30 secondes par requête. L’attente totale inclut donc aussi la durée des requêtes. Ces réglages illustrent le fonctionnement de l’application et ne garantissent pas un délai de génération. Adaptez les intervalles et les tentatives aux besoins de votre application.

Python : soumettre une tâche et consulter son résultat

Installez la dépendance avec python -m pip install requests et définissez la variable d’environnement POYO_API_KEY comme indiqué plus haut. Ce script Python synchrone interroge une tâche de génération asynchrone.

import os
import time
import requests

BASE_URL = "https://api.poyo.ai"
API_KEY = os.environ["POYO_API_KEY"]
if not API_KEY.strip():
    raise ValueError("Set POYO_API_KEY")
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
RETRYABLE_HTTP = {429, 500, 502, 503, 504}


def response_data(response):
    response.raise_for_status()
    body = response.json()
    if body.get("code") != 200 or not isinstance(body.get("data"), dict):
        raise RuntimeError(f"Unexpected API response: {body}")
    return body["data"]


def submit_h3(prompt, duration=5):
    response = requests.post(
        f"{BASE_URL}/api/generate/submit",
        headers=HEADERS,
        json={"model": "hailuo-03", "input": {
            "prompt": prompt, "duration": duration,
            "resolution": "2K", "aspect_ratio": "16:9",
        }},
        timeout=30,
    )
    task_id = response_data(response).get("task_id")
    if not isinstance(task_id, str) or not task_id:
        raise RuntimeError("Submission response is missing a task ID; check records instead of resubmitting automatically")
    return task_id


def wait_for_h3(task_id, max_polls=60):
    for _ in range(max_polls):
        time.sleep(10)
        try:
            response = requests.get(
                f"{BASE_URL}/api/generate/status/{task_id}",
                headers=HEADERS, timeout=30,
            )
        except (requests.Timeout, requests.ConnectionError):
            continue
        if response.status_code in RETRYABLE_HTTP:
            continue
        task = response_data(response)
        status = task.get("status")
        if status == "finished":
            for item in task.get("files") or []:
                if item.get("file_type") == "video" and item.get("file_url"):
                    return item["file_url"]
            raise RuntimeError(f"Task {task_id} finished, but the response has no video URL")
        if status == "failed":
            raise RuntimeError(f"Task {task_id} failed: {task.get('error_message')}")
        if status not in {"not_started", "running"}:
            raise RuntimeError(f"Task {task_id} returned an unknown status: {status}")
    raise TimeoutError(f"Query limit reached; keep the task ID and query again later: {task_id}")


if __name__ == "__main__":
    task_id = submit_h3("A golden retriever walks through a sunlit autumn park.")
    # In your application, save task_id to the database here before polling.
    print(f"Task ID: {task_id}", flush=True)
    print(wait_for_h3(task_id))

Pour reprendre la consultation, appelez directement wait_for_h3(saved_task_id). Les erreurs HTTP comme 401 et 403, les erreurs de l’API et les réponses inattendues arrêtent les consultations ; corrigez leur cause avant de continuer.

Node.js : utiliser fetch intégré

Le JavaScript suivant utilise fetch, intégré à Node.js 20 ou ultérieur, sans dépendance de client HTTP. Enregistrez-le dans un fichier .mjs et exécutez-le côté serveur.

const BASE_URL = 'https://api.poyo.ai';
const apiKey = process.env.POYO_API_KEY;
if (!apiKey?.trim()) throw new Error('Set POYO_API_KEY');
const headers = {
  Authorization: `Bearer ${apiKey}`,
  'Content-Type': 'application/json',
};
const retryableHttp = new Set([429, 500, 502, 503, 504]);
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

async function responseData(response) {
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  const body = await response.json();
  if (body.code !== 200 || !body.data || typeof body.data !== 'object') {
    throw new Error(`Unexpected API response: ${JSON.stringify(body)}`);
  }
  return body.data;
}

export async function submitH3(prompt, duration = 5) {
  const response = await fetch(`${BASE_URL}/api/generate/submit`, {
    method: 'POST', headers,
    body: JSON.stringify({
      model: 'hailuo-03',
      input: { prompt, duration, resolution: '2K', aspect_ratio: '16:9' },
    }),
    signal: AbortSignal.timeout(30_000),
  });
  const data = await responseData(response);
  if (typeof data.task_id !== 'string' || !data.task_id) {
    throw new Error('Submission response is missing a task ID; check records instead of resubmitting automatically');
  }
  return data.task_id;
}

export async function waitForH3(taskId, maxPolls = 60) {
  for (let attempt = 0; attempt < maxPolls; attempt++) {
    await sleep(10_000);
    let response;
    try {
      response = await fetch(
        `${BASE_URL}/api/generate/status/${encodeURIComponent(taskId)}`,
        { headers, signal: AbortSignal.timeout(30_000) },
      );
    } catch (error) {
      if (error instanceof Error &&
          (error.name === 'TimeoutError' || error.name === 'TypeError')) {
        continue;
      }
      throw error;
    }
    if (retryableHttp.has(response.status)) {
      await response.body?.cancel();
      continue;
    }
    const task = await responseData(response);
    if (task.status === 'finished') {
      const video = task.files?.find((file) => file.file_type === 'video' && file.file_url);
      if (!video) throw new Error(`Task ${taskId} finished, but the response has no video URL`);
      return video.file_url;
    }
    if (task.status === 'failed') {
      throw new Error(`Task ${taskId} failed: ${task.error_message || 'No error details provided'}`);
    }
    if (!['not_started', 'running'].includes(task.status)) {
      throw new Error(`Task ${taskId} returned an unknown status: ${task.status}`);
    }
  }
  throw new Error(`Query limit reached; keep the task ID and query again later: ${taskId}`);
}

const taskId = await submitH3('A golden retriever walks through a sunlit autumn park.');
// In your application, save taskId to the database here before polling.
console.log(`Task ID: ${taskId}`);
console.log(await waitForH3(taskId));

Pour reprendre la consultation, remplacez les appels de soumission et de consultation à la fin du fichier par waitForH3(savedTaskId). Cet exemple convient aux scripts et aux tâches en arrière-plan. Dans une application web, renvoyez l’identifiant au frontend et suivez la génération en arrière-plan plutôt que de laisser une requête de page en attente.

Recevoir les résultats par webhook

Vous pouvez aussi transmettre callback_url au premier niveau de la requête de soumission, à côté de model et input, par exemple https://your-domain.com/webhooks/poyo. PoYo envoie le résultat à cette URL lorsque la tâche réussit ou échoue.

Le récepteur doit rapprocher l’identifiant des données locales et gérer les notifications en double par identifiant de tâche pour éviter de répéter les opérations suivantes. Les traitements longs, comme le téléchargement ou le transcodage, peuvent s’exécuter en arrière-plan. Les consultations de statut restent disponibles pour vérifier les résultats pendant l’intégration des callbacks.

Prompts et exemples de scènes

Décrivez d’abord le sujet et l’action, puis les mouvements de caméra, le décor, la lumière et le son. Avec des références, précisez le rôle de Image 1, Video 1 ou Audio 1 pour ne pas imposer des exigences contradictoires à un même média.

Les quatre exemples en anglais illustrent la rédaction de prompts ; ils ne sont pas accompagnés de résultats de génération testés. Les termes anglais facilitent leur réutilisation, sans signifier que l’anglais fonctionne nécessairement mieux que le chinois. Les durées et les consignes de préservation de l’apparence décrivent des objectifs ; vérifiez le résultat réel.

Publicité produit : 8 secondes, mode image de référence

Placez l’image du produit en premier dans input.reference_image_urls, définissez duration: 8 et aspect_ratio: "16:9", puis utilisez le texte ci-dessous comme prompt. Reprenez la structure de requête du mode référence présentée plus haut ; supprimez reference_video_urls si vous n’avez pas besoin de vidéo de référence.

Use Image 1 as the product reference. A clear glass perfume bottle rests on
wet black stone after rain. Preserve the bottle shape, cap, and label placement.
One continuous 8-second shot: begin close to the water droplets, then slowly
pull back to reveal the bottle in warm rim light. Realistic glass reflections,
no added text. Soft rain ambience.

Commencez par un plan simple pour vérifier la stabilité du flacon et de l’étiquette, puis essayez des mouvements orbitaux plus complexes.

Dialogue de personnage : 8 secondes, mode image de référence

Placez l’image du personnage en premier dans input.reference_image_urls et définissez duration: 8 et aspect_ratio: "16:9". Une réplique courte facilite la vérification de la synchronisation labiale, du débit de parole et de l’apparence.

Use Image 1 as the character reference. An 8-second medium close-up of a pastry
chef in a quiet kitchen at sunrise. She looks into the camera and says:
"Every detail matters in baking." Natural breathing, a subtle smile,
soft window light. Preserve her face, hairstyle, and apron. A steady camera,
clear speech, quiet room tone.

Publicité verticale pour un jeu : 10 secondes, texte vers vidéo

Définissez duration: 10 et aspect_ratio: "9:16". Les segments temporels expriment l’ordre souhaité des actions ; si la scène est trop chargée, réduisez d’abord le nombre d’actions et de personnages.

A 10-second vertical fantasy game trailer.
0-3s: An armored knight walks through a ruined stone gate.
3-6s: One creature charges; the knight blocks once with a shield.
6-9s: The camera rises to reveal the fortress walls.
9-10s: Hold the final composition.
Readable action, consistent armor, wind and impact sounds, no UI or captions.

Travelling continu : 10 secondes, texte vers vidéo

Définissez duration: 10 et aspect_ratio: "16:9". Organisez le plan autour d’un seul sujet et d’un seul trajet, puis recherchez les coupes, les changements du sujet ou les mouvements discontinus.

One unbroken 10-second tracking shot follows a cyclist through a night market.
Begin behind the rear wheel, rise to shoulder height, then move alongside
without cutting. Wet pavement reflections, a clear path between stalls,
consistent bicycle geometry, no speed ramps or scene transitions.
Natural street ambience and bicycle tires rolling on wet pavement.

Questions fréquentes et dépannage

Puis-je utiliser directement le format de requête de l’API MiniMax ?

Ces exemples utilisent POST /api/generate/submit et GET /api/generate/status/{task_id} de PoYo. Les endpoints, identifiants de modèle et structures de champs peuvent varier selon la plateforme ; suivez sa documentation.

Faut-il soumettre de nouveau une tâche qui reste en not_started ?

not_started indique une attente de traitement, pas un échec en soi. Conservez l’identifiant et poursuivez les consultations. Si le délai d’attente de votre application expire, enregistrez la tâche et vérifiez-la plus tard. Contactez le support avec son identifiant si nécessaire.

Que faire si la soumission expire avant la réception de l’identifiant ?

Un délai dépassé ne prouve pas que le serveur n’a pas accepté la tâche. Vérifiez d’abord les enregistrements ; au besoin, contactez le support en précisant notamment l’heure d’envoi. L’identifiant est nécessaire pour consulter le statut. Ne remplacez pas une consultation échouée par une nouvelle soumission.

Puis-je combiner images, vidéo et audio comme références ?

Oui, en mode référence, dans les limites de nombre et de durée indiquées. Une référence audio nécessite une image ou une vidéo de référence. Ces champs ne peuvent pas être combinés avec image_urls du mode images de début et de fin.

Combien coûte une vidéo de 10 secondes ?

Aux tarifs indiqués, sans média de référence, le coût est de 10 × 21 = 210 crédits, soit $1.05. Les vidéos de référence et les images au-delà des 5 premières augmentent le coût.

Avant l’intégration, vérifiez que les URL permettent le téléchargement direct, enregistrez les identifiants et fixez des limites adaptées de génération et de simultanéité par utilisateur. Avant publication, vérifiez que l’apparence des personnages, la forme des produits, le texte, les mouvements et le son conviennent à l’usage prévu.

Essayez la génération sur la page du modèle MiniMax H3, ou rendez-vous sur la page des clés API pour commencer l’intégration. Pour en savoir plus, consultez l’évaluation de MiniMax H3 et le comparatif MiniMax H3 et Seedance 2.5.

Share: