Documentación de la API HappyHorse

Guía completa para integrar la API de generación de vídeo HappyHorse 1.0 en tus aplicaciones.

API v1.0 Base URL: https://happyhorse.app

Inicio rápido

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

Autenticación

Todas las solicitudes requieren un token Bearer en el encabezado Authorization.

Obtener tu clave API: Puedes obtener tu clave en la página API Keys del panel. → Obtener tu clave API

http
Authorization: Bearer YOUR_API_KEY

Cómo funcionan Generate y Status

Las tareas de vídeo de HappyHorse son asíncronas: crea una tarea con POST /api/generate, guarda el task_id devuelto y consulta GET /api/status hasta llegar a un estado final.

1

Crear una tarea

Envía prompt, model, mode, duration e imágenes opcionales a /api/generate. Una respuesta correcta devuelve task_id de inmediato.

2

Consultar el estado

Usa task_id con /api/status. Mientras status sea IN_PROGRESS, el vídeo sigue renderizándose y response permanece null.

3

Leer el resultado

Cuando status sea SUCCESS, data.response.resultUrls[0] es la URL del vídeo. Si pasa a FAILED, muestra error_message y detén el polling.

Modelos disponibles

HappyHorse 1.0

HappyHorse 1.0

Generación de vídeo con IA de alta calidad con HappyHorse

TipoDescripciónDuraciónCréditos
pro (text-to-video)Texto a vídeo calidad Pro3-15s54/s (no audio) · 80/s (with audio)
pro (image-to-video)Imagen a vídeo calidad Pro3-15s54/s (no audio) · 80/s (with audio)
std (text-to-video)Texto a vídeo calidad estándar3-15s40/s (no audio) · 60/s (with audio)
std (image-to-video)Imagen a vídeo calidad estándar3-15s40/s (no audio) · 60/s (with audio)

Endpoints de la API

Crea una tarea de generación de vídeo. El campo model debe ser 'happyhorse-1.0/video'.

Cuerpo de la solicitud

Parámetros del cuerpoJSON
model:string

Nombre del modelo; debe ser 'happyhorse-1.0/video'

prompt:optional string

Descripción en texto del vídeo (máx. 2500 caracteres). No es obligatorio si multi_shots es true.

mode:optional string

Modo de calidad: 'pro' o 'std' (predeterminado: std) Defaults to std.

duration:optional number

Duración en segundos (3–15). En modo multi-plano, la duración final se deriva de multi_prompt; si envías duration explícitamente, debe coincidir con la suma de las duraciones de los planos. Defaults to 5 / sum(multi_prompt).

aspect_ratio:optional string

Relación de aspecto de salida (16:9, 9:16, 1:1) Defaults to 16:9.

image_urls:optional string[]

Array de URLs de imagen para imagen a vídeo

sound:optional boolean

Activar audio nativo (predeterminado: true). En solicitudes multi-plano, envía este campo explícitamente como true o false. Defaults to true.

cfg_scale:optional number

Adherencia al prompt (0-1, predeterminado: 0.5). Valores más altos siguen el prompt con más fidelidad. Defaults to 0.5.

multi_shots:optional boolean

Modo multi-plano con varios prompts Defaults to false.

multi_prompt:optional array

Array de objetos 'prompt, duration' para multi-plano

happyhorse_elements:optional array

Array de objetos de elemento. En el prompt, escribe @ seguido del valor de name (p. ej. name 'element_dog' → @element_dog). Cada elemento: name, description, element_input_urls (2-4 URLs de imagen). Max 3 por tarea.

Texto a vídeo

json
{
  "model": "happyhorse-1.0/video",
  "prompt": "A majestic eagle soaring through clouds at sunset",
  "mode": "pro",
  "duration": 5,
  "aspect_ratio": "16:9",
  "sound": true
}

Imagen a vídeo

json
{
  "model": "happyhorse-1.0/video",
  "prompt": "The character slowly turns and smiles",
  "mode": "pro",
  "image_urls": ["https://example.com/my-image.jpg"],
  "duration": 5
}

Vídeo multi-plano

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

Respuestas

Task created successfully

{
  "code": 200,
  "message": "success",
  "data": {
    "task_id": "n92abc123hh10",
    "status": "IN_PROGRESS"
  }
}

Comprueba el estado con el task_id devuelto por el endpoint generate.

Parámetros de consulta

Parámetros de consulta
task_id:string

ID único devuelto por generate (prefijo n92)

Ejemplo de solicitud

bash
curl -X GET 'https://happyhorse.app/api/status?task_id=n92abc123hh10' \
  -H 'Authorization: Bearer YOUR_API_KEY'

Consejo: El campo response contiene el array resultUrls. Usa data.response.resultUrls[0] para la URL del vídeo.

javascript
// Extract video URL after the task is complete
const task = payload.data;
const videoUrl = task.status === "SUCCESS"
  ? task.response?.resultUrls?.[0]
  : null;

Respuestas

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

Buenas prácticas de polling

La generación de vídeo puede tardar un poco, así que trata las consultas de estado como una tarea de fondo tranquila, no como un bucle apretado.

Empieza con una breve espera

Espera unos 8-10 segundos antes de la primera consulta y luego consulta cada 10-20 segundos. Consultar más rápido no hará que el vídeo termine antes.

Detente en estados finales

SUCCESS y FAILED son finales. Detén el polling en cuanto veas cualquiera de ellos y guarda el task_id para soporte o consultas posteriores.

Usa un timeout del cliente

Después de 10-15 minutos, detén la espera activa y permite que el usuario vuelva a consultar el estado manualmente. No dejes una pestaña del navegador consultando para siempre.

Reduce el ritmo ante errores

Si recibes 429 o un error temporal de red, espera más antes de la siguiente solicitud. Para 401 o 402, pide al usuario que corrija la clave API o los créditos.

javascript
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.");
}

Zona de pruebas API

Prueba la API en el navegador. Sustituye YOUR_API_KEY por tu clave real.

Zona de pruebas APIPOST

Códigos de error

Estado HTTPCódigoDescripción
400 Solicitud incorrectaINVALID_PROMPTEl prompt no es válido o está vacío
400 Solicitud incorrectaINVALID_DURATIONDuración fuera del rango admitido (3–15 s)
400 Solicitud incorrectaINVALID_MODELEl modelo debe ser 'happyhorse-1.0/video'
401 No autorizadoINVALID_API_KEYFalta la clave API o no es válida
402 Pago requeridoINSUFFICIENT_CREDITSCréditos insuficientes para esta operación
429 Demasiadas solicitudesRATE_LIMITEDDemasiadas solicitudes; reduce la frecuencia
500 Error interno del servidorINTERNAL_ERRORError del servidor; inténtalo más tarde