Tutorial
Chamando a API de texto para vídeo do HappyHorse 1.1 via HiAPI: um tutorial curl + Python que funciona
- Modelo
- happyhorse-1.1
O HappyHorse 1.1 é o modelo de texto para vídeo da Alibaba: suporta clipes de vídeo em 720p / 1080p, com duração de 3 a 15 segundos, gerando áudio nativo em uma única chamada (sem necessidade de uma etapa separada de trilha sonora). A HiAPI expõe esse modelo pelo mesmo endpoint assíncrono unificado de todos os outros modelos generativos, portanto, se você já chamou modelos de imagem em /v1/tasks, a única mudança é o id do modelo e alguns campos de input.
Esta página traz o mínimo necessário para entregar uma integração funcional: o schema exato, o curl pronto para copiar, um cliente de polling em Python e o padrão de callback para produção. Também aponta explicitamente duas coisas pouco óbvias que o modelo não aceita (um interruptor audio e um seed), para você não desperdiçar uma requisição por causa de um 400.
Pré-requisitos. Obtenha uma chave no Console da HiAPI e exporte-a como
HIAPI_API_KEY. Toda requisição é autenticada viaAuthorization: Bearer sk-…; para revisar, consulte Authentication.
Endpoint e estrutura da requisição
Tudo passa pelo mesmo endpoint:
POST https://api.hiapi.ai/v1/tasks
Authorization: Bearer sk-<your-key>
Content-Type: application/json
O corpo da requisição tem três chaves de nível superior:
model—happyhorse-1.1/text-to-video(o id literal do modelo — a barra deve ser mantida).input— campos específicos do modelo. Para o HappyHorse 1.1 T2V:prompt(string, obrigatório) — descreve o clipe de vídeo.resolution(720p|1080p, padrão1080p).aspect_ratio(16:9|9:16|3:4|4:3|4:5|5:4|1:1|9:21|21:9, padrão16:9).duration(inteiro, 3–15, padrão5). O custo aumenta com a quantidade de segundos.
callback(opcional, objeto) — endpoint HTTPS emcallback.url+callback.when: "final". A HiAPI fará exatamente um POST do resultado final para esse endereço por tarefa.
Duas coisas que parecem funcionar, mas não funcionam:
- ❌ Não existe o campo
audio. O áudio é gerado nativamente junto com o vídeo; não há interruptor. Enviar"audio": trueretornaadditional properties 'audio' not allowed. - ❌ Não existe o campo
seed. Também retorna 400. Se você precisa de determinismo entre lotes agora, gere várias versões e escolha — não há alavanca de seed ajustável.
Um corpo de requisição mínimo válido:
{
"model": "happyhorse-1.1/text-to-video",
"input": {
"prompt": "A golden retriever running on a beach, slow motion, gentle waves, warm sunset tones",
"resolution": "1080p",
"aspect_ratio": "16:9",
"duration": 5
}
}
Exemplo mínimo executável: curl
Crie a tarefa — a resposta retorna imediatamente e contém apenas um taskId:
curl -sS -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "happyhorse-1.1/text-to-video",
"input": {
"prompt": "A snow mountain lake in morning mist, slow camera push-in, warm cinematic light",
"resolution": "1080p",
"aspect_ratio": "16:9",
"duration": 5
}
}'
# => {"code":200,"data":{"taskId":"tk-hiapi-01KW3..."},"message":"success"}
Depois, faça polling até chegar a um estado terminal:
TASK_ID=tk-hiapi-01KW3...
curl -sS "https://api.hiapi.ai/v1/tasks/$TASK_ID" \
-H "Authorization: Bearer $HIAPI_API_KEY"
# while .data.status is "handling", sleep a few seconds and retry.
# On success:
# {
# "code": 200,
# "data": {
# "status": "success",
# "model": "happyhorse-1.1/text-to-video",
# "output": [
# {"type":"video","url":"https://temp.hiapi.ai/.../...-0.mp4","expireAt":1783130616}
# ],
# ...
# }
# }
A URL do mp4 é temporária (expireAt é um timestamp Unix de cerca de 7 dias depois). Baixe e persista imediatamente após a tarefa ter sucesso — não faça hotlink. Se você preferir que a HiAPI gerencie o armazenamento de longo prazo, consulte a documentação de Output Storage para saber como promover a saída do armazenamento temporário para o persistente.
Python: um cliente pequeno e com formato de produção
Um cliente de verdade precisa de três coisas: um create_task que retorna o id, um wait_task que faz polling com prazo limite e uma etapa de download. Este esqueleto contém todos os três e fica próximo do ponto de partida da página do SDK Python da HiAPI — mantenha-o pequeno e expanda a partir daí.
# pip install requests
import os, time, json, requests
API_BASE = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}"}
def create_task(prompt: str, *, resolution="1080p", aspect_ratio="16:9", duration=5) -> str:
body = {
"model": "happyhorse-1.1/text-to-video",
"input": {
"prompt": prompt,
"resolution": resolution,
"aspect_ratio": aspect_ratio,
"duration": duration,
},
}
r = requests.post(API_BASE, headers={**HEADERS, "Content-Type": "application/json"},
data=json.dumps(body), timeout=60)
r.raise_for_status()
data = r.json()
if data.get("code") != 200:
raise RuntimeError(f"create failed: {data}")
return data["data"]["taskId"]
def wait_task(task_id: str, *, timeout_s: int = 600, poll: int = 5) -> dict:
deadline = time.time() + timeout_s
while time.time() < deadline:
r = requests.get(f"{API_BASE}/{task_id}", headers=HEADERS, timeout=30)
r.raise_for_status()
task = r.json().get("data") or {}
status = task.get("status")
if status == "success":
return task
if status == "fail":
raise RuntimeError(f"task {task_id} failed: {task.get('error')}")
time.sleep(poll)
raise TimeoutError(f"task {task_id} did not finish within {timeout_s}s")
def download(url: str, path: str) -> None:
with requests.get(url, stream=True, timeout=120) as r:
r.raise_for_status()
with open(path, "wb") as f:
for chunk in r.iter_content(1 << 14):
f.write(chunk)
if __name__ == "__main__":
task_id = create_task(
"A neon street at night after rain, reflections on the ground, "
"cyberpunk mood, slow pan",
resolution="720p", aspect_ratio="9:16", duration=5,
)
task = wait_task(task_id)
url = task["output"][0]["url"]
download(url, "out.mp4")
print("saved out.mp4")
Algumas observações para produção:
- Campo de status. Trate qualquer valor diferente de
successoufailcomo em andamento (a plataforma atualmente usahandling). raise_for_statusnão basta. Para alguns erros de validação, a HiAPI retorna HTTP 200, mas comcodediferente de 200 — verifique tambémdata["code"]. Para integrações novas, o mais comum é401 permission_denied, o que significa bearer token incorreto ou ausente — reexporteHIAPI_API_KEYe confirme no console.
Produção: prefira callbacks em vez de polling
Para qualquer cenário além do início rápido, dê à HiAPI um webhook para ela te chamar quando a tarefa terminar:
{
"model": "happyhorse-1.1/text-to-video",
"input": {
"prompt": "A snow mountain lake in morning mist, slow camera push-in, warm cinematic light",
"resolution": "1080p",
"aspect_ratio": "16:9",
"duration": 5
},
"callback": {
"url": "https://your-domain.com/hiapi/callback",
"when": "final"
}
}
Garanta que seu handler de callback faça o seguinte:
- Deduplique por
taskId. Tantosuccessquantofailsão terminais — seu serviço deve tratar duas entregas do mesmotaskIdcomo no-op (gravação idempotente com chavetaskId). - Retorne 2xx rapidamente. Coloque o trabalho pesado (baixar o mp4, persistir, notificar o usuário) em uma fila. O handler de webhook deve confirmar em poucos segundos.
- Mantenha
GET /v1/tasks/:idcomo fallback. Se um webhook se perder (deploy, instabilidade de rede), uma tarefa agendada de reconciliação que busca por id as tarefas presas e aplica o mesmo handler é a rede de segurança mais simples.
Se você tiver que escolher um caminho: polling serve para scripts pontuais e depuração local, e qualquer lugar com tráfego real deve usar callbacks.
Escolhendo os parâmetros corretos (resolution × aspect_ratio × duration)
| Necessidade | resolution | aspect_ratio | duration |
|---|---|---|---|
| Vídeo curto vertical para redes sociais, menor custo | 720p |
9:16 |
5 |
| Prévia quadrada / loop de thumbnail | 720p |
1:1 |
3 |
| Narrativa horizontal / cena publicitária | 1080p |
16:9 |
5–8 |
| Clipes de key visual em widescreen | 1080p |
21:9 |
8–12 |
O custo aumenta com a resolução e a duração — consulte os preços exatos por segundo em Preços da HiAPI. Quando não tiver certeza dos valores corretos, não preencha: resolution assume 1080p, aspect_ratio assume 16:9 e duration assume 5.
Perguntas frequentes
O modelo de texto para vídeo HappyHorse 1.1 tem parâmetro seed?
Não. A API rejeita seed com additional properties 'seed' not allowed. Se você precisa de várias opções para escolher, envie várias tarefas com o mesmo prompt — execuções diferentes geram variações naturalmente.
Como ligar ou desligar o áudio?
Você não consegue — o HappyHorse 1.1 gera a faixa de áudio nativamente na mesma chamada. Não há interruptor audio no schema; enviar um retorna 400. Se você precisar de um clipe sem som, remova o áudio na pós-produção.
Quais são as durações válidas?
Um inteiro de 3 a 15 (segundos). Qualquer valor fora desse intervalo retorna duration: minimum: got 0, want 3 ou duration: maximum: got 20, want 15. Decimais também são rejeitados (o tipo do campo é inteiro).
Quais proporções de aspecto ele suporta?
Nove: 16:9, 9:16, 3:4, 4:3, 4:5, 5:4, 1:1, 9:21, 21:9. O padrão é 16:9.
Por quanto tempo output[].url permanece válida?
Cerca de uma semana — a resposta inclui um timestamp Unix expireAt. Baixe o mp4 imediatamente e re-hospede (S3, R2, seu CDN), ou promova-o para armazenamento persistente pela Output Storage API.
E imagem para vídeo?
O HappyHorse 1.1 tem uma variante I2V no mesmo endpoint — consulte HappyHorse 1.1 I2V. Mesma autenticação, mesmo ciclo de vida assíncrono, schema de input diferente.
Onde está a referência completa da API assíncrona? O envelope da requisição está em Create Task, o endpoint de polling em Get Task Detail e o schema canônico de entrada na página do modelo HappyHorse 1.1 T2V. Se você está começando do zero, o Quickstart guia você pela primeira chamada de ponta a ponta.
Artigos relacionados
Ver todos os artigos →-
Tutorial
Como chamar hailuo-2.3-fast/image-to-video pela API HiAPI: curl e Python na prática
A primeira requisição executável do nível rápido e econômico de geração de vídeo a partir de imagem — do ID do modelo ao download do MP4
-
Tutorial
Como chamar hailuo-2.3/text-to-video pela API HiAPI: curl, Python e exemplos de requisição executáveis
-
Tutorial
Usar Kandinsky 6.0 Pro text-to-video na HiAPI: tutorial de curl e Python
Demonstração prática com foco na requisição: montar a chamada de prompt para clipe de vídeo, enviar a requisição, consultar o status de conclusão e baixar o resultado