Documentação da API HappyHorse
Guia completo para integrar a API de geração de vídeo HappyHorse 1.0 aos seus aplicativos.
Início rápido
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"
}'Autenticação
Todas as requisições exigem um token Bearer no cabeçalho Authorization.
Obter sua chave de API: Você pode obter sua chave na página API Keys do painel. → Obter sua chave de API
Authorization: Bearer YOUR_API_KEYComo Generate e Status funcionam
As tarefas de vídeo do HappyHorse são assíncronas: crie uma tarefa com POST /api/generate, guarde o task_id retornado e consulte GET /api/status até chegar a um estado final.
Criar uma tarefa
Envie prompt, model, mode, duration e imagens opcionais para /api/generate. Uma resposta bem-sucedida retorna task_id imediatamente.
Consultar status
Use task_id com /api/status. Enquanto o status for IN_PROGRESS, o vídeo ainda está sendo renderizado e response fica null.
Ler o resultado
Quando o status virar SUCCESS, data.response.resultUrls[0] é a URL do vídeo. Se virar FAILED, mostre error_message e pare o polling.
Modelos disponíveis
HappyHorse 1.0
Geração de vídeo com IA de alta qualidade com HappyHorse
| Tipo | Descrição | Duração | Créditos |
|---|---|---|---|
pro (text-to-video) | Texto para vídeo em qualidade Pro | 3-15s | 54/s (no audio) · 80/s (with audio) |
pro (image-to-video) | Imagem para vídeo em qualidade Pro | 3-15s | 54/s (no audio) · 80/s (with audio) |
std (text-to-video) | Texto para vídeo em qualidade padrão | 3-15s | 40/s (no audio) · 60/s (with audio) |
std (image-to-video) | Imagem para vídeo em qualidade padrão | 3-15s | 40/s (no audio) · 60/s (with audio) |
Endpoints da API
Cria uma nova tarefa de geração de vídeo. O campo model deve ser 'happyhorse-1.0/video'.
Corpo da requisição
Nome do modelo; deve ser 'happyhorse-1.0/video'
Descrição em texto do vídeo (máx. 2500 caracteres). Não obrigatório se multi_shots for true.
Modo de qualidade: 'pro' ou 'std' (padrão: std) Defaults to std.
Duração em segundos (3–15). No modo multi-shot, a duração final é derivada de multi_prompt; se você enviar duration explicitamente, mantenha-o igual à soma das durações dos shots. Defaults to 5 / sum(multi_prompt).
Proporção de saída (16:9, 9:16, 1:1) Defaults to 16:9.
Array de URLs de imagem para imagem para vídeo
Ativar áudio nativo (padrão: true). Em requisições multi-shot, envie este campo explicitamente como true ou false. Defaults to true.
Aderência ao prompt (0-1, padrão: 0.5). Valores maiores seguem o prompt mais fielmente. Defaults to 0.5.
Modo multi-shot com vários prompts Defaults to false.
Array de objetos 'prompt, duration' para multi-shot
Array de objetos de elemento. No prompt, escreva @ seguido do valor de name (ex.: name 'element_dog' → @element_dog). Cada elemento: name, description, element_input_urls (2-4 URLs de imagem). Max 3 por tarefa.
Texto para vídeo
{
"model": "happyhorse-1.0/video",
"prompt": "A majestic eagle soaring through clouds at sunset",
"mode": "pro",
"duration": 5,
"aspect_ratio": "16:9",
"sound": true
}Imagem para vídeo
{
"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-shot
{
"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"
}Respostas
Task created successfully
{
"code": 200,
"message": "success",
"data": {
"task_id": "n92abc123hh10",
"status": "IN_PROGRESS"
}
}Verifica o status da geração usando o task_id retornado pelo endpoint generate.
Parâmetros de consulta
ID único retornado por generate (prefixo n92)
Exemplo de requisição
curl -X GET 'https://happyhorse.app/api/status?task_id=n92abc123hh10' \
-H 'Authorization: Bearer YOUR_API_KEY'Dica: O campo response contém o array resultUrls. Use data.response.resultUrls[0] para a URL do vídeo.
// Extract video URL after the task is complete
const task = payload.data;
const videoUrl = task.status === "SUCCESS"
? task.response?.resultUrls?.[0]
: null;Respostas
{
"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
}
}Boas práticas de polling
A geração de vídeo pode levar um tempo, então trate as consultas de status como uma tarefa de fundo tranquila, não como um loop agressivo.
Comece com uma pequena espera
Espere cerca de 8-10 segundos antes da primeira consulta e depois consulte a cada 10-20 segundos. Consultar mais rápido não acelera o vídeo.
Pare em estados finais
SUCCESS e FAILED são finais. Pare assim que vir qualquer um deles e guarde o task_id para suporte ou consulta posterior.
Use timeout no cliente
Após 10-15 minutos, pare a espera ativa e permita que o usuário consulte o status manualmente depois. Não deixe uma aba do navegador consultando para sempre.
Reduza o ritmo em erros
Se receber 429 ou um erro temporário de rede, espere mais antes da próxima requisição. Para 401 ou 402, peça ao usuário para corrigir a chave API ou os créditos.
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.");
}Playground da API
Teste a API direto no navegador. Substitua YOUR_API_KEY pela sua chave real.
Códigos de erro
| Status HTTP | Código | Descrição |
|---|---|---|
| 400 Requisição inválida | INVALID_PROMPT | O prompt é inválido ou está vazio |
| 400 Requisição inválida | INVALID_DURATION | Duração fora do intervalo suportado (3–15 s) |
| 400 Requisição inválida | INVALID_MODEL | O modelo deve ser 'happyhorse-1.0/video' |
| 401 Não autorizado | INVALID_API_KEY | Chave de API ausente ou inválida |
| 402 Pagamento necessário | INSUFFICIENT_CREDITS | Créditos insuficientes para esta operação |
| 429 Muitas requisições | RATE_LIMITED | Muitas requisições; reduza a frequência |
| 500 Erro interno do servidor | INTERNAL_ERROR | Erro no servidor; tente novamente mais tarde |