Todos los artículos
how-tos16 min de lectura

Guía de la API MiniMax H3: integración con PoYo, precios y prompts

Usa MiniMax H3 con PoYo: parámetros de vídeo 2K, tres modos de entrada y precios. Envía y consulta tareas con cURL, Python o Node.js y explora prompts para vídeos de productos y personajes.

Con la API MiniMax H3 de PoYo puedes generar vídeos 2K de 5–15 segundos a partir de texto, fotogramas iniciales y finales o material de referencia. Sin referencias, un vídeo de 5 segundos tiene un coste estimado de 105 créditos ($0.525).

Esta guía comienza con tu primera solicitud y después explica los precios, los modos de entrada, los ejemplos en Python y Node.js y los prompts para distintas escenas. Todos los endpoints y precios de esta guía corresponden a PoYo.

Inicio rápido: envía una tarea y obtén el vídeo

1. Envía una tarea de vídeo de 5 segundos

Obtén una clave API en la consola de PoYo, sustituye YOUR_POYO_API_KEY y ejecuta el comando en un terminal o en tu servidor. Conserva la clave en el servidor; no la incluyas en código del navegador ni en repositorios públicos.

En las solicitudes a PoYo, el valor de model para MiniMax H3 es hailuo-03. El siguiente ejemplo envía una tarea de generación de pago.

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"
    }
  }'

Tras un envío correcto, obtén el ID de la tarea de data.task_id. Este ejemplo muestra la estructura de la respuesta con un ID de tarea de muestra:

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

2. Consulta el resultado de la tarea

Asigna a TASK_ID el ID recibido y utiliza la misma clave 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}"

Un envío correcto significa que la tarea se ha aceptado; aún debes esperar a que termine la generación. El campo data.status de la respuesta de consulta puede tener cuatro valores:

Estado Significado Siguiente paso
not_started En espera de procesamiento Volver a consultar más tarde
running Generación en curso Volver a consultar más tarde
finished Generación completada Leer data.files[].file_url
failed Generación fallida Revisar data.error_message y detener las consultas periódicas

Este es un ejemplo de respuesta al finalizar. La URL y la fecha son ilustrativas:

{
  "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
  }
}

Consulta las definiciones de campos y los ejemplos de otros estados en la documentación de consulta de tareas de PoYo. Si una consulta falla temporalmente o se agota el tiempo de espera, conserva el ID y vuelve a consultar más tarde; no envíes automáticamente otra generación de pago.

Cómo se factura MiniMax H3 en PoYo

Los siguientes precios se comprobaron el 21 de septiembre de 2026. Todos los importes están en USD, con una equivalencia de 1 crédito = $0.005. Antes de generar en lote, confirma los precios vigentes en la página del modelo.

Concepto facturable Créditos USD
Duración del vídeo generado 21 créditos/segundo $0.105/segundo
Duración del vídeo de referencia de entrada 21 créditos/segundo $0.105/segundo
Primeras 5 imágenes de referencia por generación 0 $0
Cada imagen de referencia a partir de la 6.ª 6.4 créditos $0.032

Créditos estimados = 21 × (segundos de salida + segundos facturables de vídeo de referencia) + 6.4 × número de imágenes de referencia que excedan de 5. Con 5 imágenes o menos, el cargo adicional por imágenes es 0. Multiplica los créditos estimados por $0.005 para obtener el coste en USD. Si el vídeo de referencia contiene fracciones de segundo, se factura la duración que determine el servidor.

Ejemplo Créditos estimados USD estimados
Generar 5 segundos sin referencias 105 $0.525
Generar 10 segundos sin referencias 210 $1.05
Generar 15 segundos sin referencias 315 $1.575
Generar 10 segundos + 5 segundos de vídeo de referencia + 7 imágenes de referencia 327.8 $1.639

El último ejemplo se calcula con 21 × (10 + 5) + 6.4 × (7 − 5). Estos costes corresponden a una generación; si una toma requiere varios intentos, incluye cada generación en el presupuesto.

Elige el modo de entrada y las referencias

Los campos multimedia que envíes determinan el modo de entrada. El ejemplo de inicio rápido usa texto a vídeo. Añade los campos correspondientes cuando necesites indicar fotogramas iniciales y finales o usar referencias.

Modo Campos de entrada Uso
Texto a vídeo prompt, sin URLs multimedia Describe con palabras la escena, la acción y el movimiento de cámara
Generación con fotogramas inicial y final image_urls La primera imagen es el fotograma inicial; la segunda, opcional, es el final. Omite aspect_ratio; el primer fotograma determina la relación de aspecto
Generación con referencias multimodales reference_image_urls, reference_video_urls, reference_audio_urls Combina imágenes, vídeo y audio; el audio de referencia requiere una imagen o un vídeo de referencia

No combines image_urls con ningún campo reference_*_urls. Todas las URLs multimedia deben ser públicas y permitir la descarga directa.

Límites de parámetros y archivos multimedia

Los siguientes límites proceden de la documentación de la API MiniMax H3 de PoYo:

  • prompt es obligatorio y admite hasta 2000 caracteres.
  • duration es un entero de 5–15 segundos, con 5 como valor predeterminado; resolution solo admite 2K.
  • Texto a vídeo admite 21:9, 16:9, 4:3, 1:1, 3:4 y 9:16, con 16:9 como valor predeterminado. El modo de referencia también admite adaptive y lo usa de forma predeterminada.
  • Puedes proporcionar hasta 9 imágenes, 3 vídeos y 3 clips de audio de referencia. Cada vídeo o audio debe durar 2–15 segundos; la duración total de los vídeos y la de los audios no deben superar, por separado, los 15 segundos.

Ejemplo de solicitud con fotogramas inicial y final

Usa el siguiente JSON como cuerpo de POST /api/generate/submit. Las URLs de example.com son marcadores de posición: sustitúyelas por tus propios archivos descargables antes del envío. Para usar solo un fotograma inicial, elimina la segunda URL del array.

{
  "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"
    ]
  }
}

Ejemplo de referencias combinadas de imagen y vídeo

Usa Image 1 para indicar la apariencia del personaje y Video 1 para el movimiento de cámara deseado. Se refieren al primer elemento del array de imágenes y del array de vídeos, respectivamente. Sustituye las URLs y comprueba la duración del vídeo de referencia antes del envío.

{
  "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"
    ]
  }
}

Ejemplos de integración en Python y Node.js

Estos ejemplos separan el envío y la consulta en dos funciones: primero obtén y guarda el ID de la tarea y después espera el resultado. Si se interrumpe la consulta, puedes reanudarla con el ID original sin volver a generar. Solo las consultas de estado reintentan errores de conexión, tiempos de espera agotados, HTTP 429 y determinados errores 5xx; los envíos no se reintentan automáticamente.

Ambas implementaciones esperan 10 segundos entre consultas, realizan hasta 60 consultas y establecen un tiempo de espera de 30 segundos por solicitud. El tiempo total también incluye la duración de las solicitudes. Son ajustes de los ejemplos, no una garantía sobre el tiempo de generación. Adapta los intervalos y los reintentos a tu aplicación.

Python: envía una tarea y consulta periódicamente el resultado

Instala la dependencia con python -m pip install requests y configura la variable de entorno POYO_API_KEY como se indica arriba. Este script síncrono de Python consulta periódicamente una tarea de generación asíncrona.

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))

Para reanudar la consulta, llama directamente a wait_for_h3(saved_task_id). Los errores HTTP como 401 y 403, los errores de la API y las respuestas inesperadas detienen las consultas; resuelve su causa antes de continuar.

Node.js: usa fetch integrado

El siguiente JavaScript utiliza fetch, integrado en Node.js 20 o posterior, sin necesidad de instalar un cliente HTTP. Guárdalo como archivo .mjs y ejecútalo en el servidor.

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));

Para reanudar la consulta, sustituye las llamadas de envío y consulta al final del archivo por waitForH3(savedTaskId). Este ejemplo resulta adecuado para scripts o tareas en segundo plano. En una aplicación web, devuelve el ID al frontend y supervisa la generación en segundo plano, sin mantener una solicitud de página a la espera.

Recibe resultados mediante un webhook

También puedes pasar callback_url en el nivel superior de la solicitud de envío, junto a model e input, por ejemplo https://your-domain.com/webhooks/poyo. PoYo enviará el resultado a esa URL cuando la tarea finalice correctamente o falle.

El receptor debe contrastar el ID con los registros locales y gestionar las notificaciones duplicadas por ID de tarea para evitar repetir operaciones posteriores. La descarga o transcodificación del vídeo puede ejecutarse en segundo plano. Durante la integración de los callbacks, puedes seguir usando las consultas de estado para verificar los resultados.

Prompts y ejemplos de escenas

Describe primero el sujeto y la acción; añade después el movimiento de cámara, el entorno, la iluminación y el sonido. Si usas referencias, especifica la función de Image 1, Video 1 o Audio 1 para no asignar requisitos contradictorios a un mismo recurso.

Los cuatro ejemplos en inglés ilustran cómo redactar prompts; no incluyen resultados de generación probados. Los términos en inglés facilitan su reutilización, pero no implican que el inglés funcione necesariamente mejor que el chino. Los tiempos y las instrucciones para conservar la apariencia son objetivos; revisa el resultado real.

Anuncio de producto: 8 segundos, modo de imagen de referencia

Coloca la imagen del producto en la primera posición de input.reference_image_urls, configura duration: 8 y aspect_ratio: "16:9", y usa el siguiente texto como prompt. Sigue la estructura de solicitud del modo de referencia anterior; elimina reference_video_urls si no necesitas un vídeo de referencia.

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.

Empieza con una toma sencilla para comprobar si el frasco y la etiqueta se mantienen coherentes; después prueba movimientos orbitales más complejos.

Diálogo de personaje: 8 segundos, modo de imagen de referencia

Coloca la imagen del personaje en la primera posición de input.reference_image_urls y configura duration: 8 y aspect_ratio: "16:9". Una frase breve facilita comprobar la sincronización labial, la velocidad del habla y la apariencia.

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.

Anuncio vertical de videojuego: 10 segundos, texto a vídeo

Configura duration: 10 y aspect_ratio: "9:16". Los segmentos temporales expresan la secuencia deseada; si la escena está demasiado cargada, reduce primero el número de acciones y personajes.

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.

Toma de seguimiento continua: 10 segundos, texto a vídeo

Configura duration: 10 y aspect_ratio: "16:9". Organiza la toma en torno a un sujeto y un recorrido, y comprueba si aparecen cortes, cambios en el sujeto o movimientos discontinuos.

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.

Preguntas frecuentes y resolución de problemas

¿Puedo usar directamente el formato de solicitudes de la API de MiniMax?

Estos ejemplos utilizan POST /api/generate/submit y GET /api/generate/status/{task_id} de PoYo. Las direcciones, los identificadores de modelo y las estructuras de campos pueden variar entre plataformas; sigue la documentación de la que utilices.

¿Debo reenviar una tarea que permanece en not_started?

not_started indica que la tarea espera procesamiento; no es un fallo por sí mismo. Conserva el ID y sigue consultando. Si se agota el límite de espera de tu aplicación, registra la tarea y compruébala más tarde. Si es necesario, contacta con soporte indicando el ID.

¿Qué hago si el envío agota el tiempo de espera antes de recibir un ID?

Que se agote el tiempo de espera no demuestra que el servidor no haya aceptado la tarea. Revisa primero los registros; si es necesario, contacta con soporte y proporciona datos como la hora de envío. Necesitas un ID de tarea para consultar el estado. No uses el reenvío como solución a una consulta fallida.

¿Puedo combinar imágenes, vídeo y audio como referencias?

Sí, combínalos en el modo de referencia dentro de los límites de cantidad y duración indicados. El audio de referencia requiere una imagen o un vídeo de referencia. Estos campos no pueden combinarse con image_urls del modo de fotogramas inicial y final.

¿Cuánto cuesta un vídeo de 10 segundos?

Con los precios indicados, sin referencias, el coste es de 10 × 21 = 210 créditos, es decir, $1.05. Los vídeos de referencia y las imágenes que excedan de las primeras 5 aumentan el coste.

Antes de integrar la API, confirma que las URLs permiten descargas directas, guarda los IDs de tarea y establece límites de generación y concurrencia por usuario. Antes de publicar un vídeo, revisa la apariencia de los personajes, la forma del producto, el texto, el movimiento y el sonido según el uso previsto.

Prueba la generación en la página del modelo MiniMax H3 o visita la página de claves API para comenzar la integración. Para conocer mejor los modelos, consulta la reseña de MiniMax H3 y la comparativa de MiniMax H3 y Seedance 2.5.

Blog · PoYo.aiTodos los artículos
HABLEMOS

¿Tienes un proyecto?

Cuéntanos qué estás creando. Nuestro equipo te ayudará a elegir la API de IA adecuada.

Usaremos tus datos solo para responder a esta consulta.

PoYo AI

¿Listo para explorar modelos?

Descubre modelos de imagen, vídeo, audio y lenguaje en PoYo.

Ver modelos de IA