Tutorial
Como usar a API de texto para vídeo Ray 3.2: curl, Python e uma requisição pronta para executar
Ray 3.2 é um modelo de texto para vídeo no catálogo de modelos da hiapi e, como todos os outros modelos de vídeo, é chamado por meio da API unificada de tarefas assíncronas — o id do modelo é ray-3.2/text-to-video, enviado para POST /v1/tasks. Diferentemente de alguns modelos de vídeo cujo único ajuste é o prompt, o Ray 3.2 oferece três controles de saída realmente utilizáveis — duration, resolution e aspect_ratio — e cada um deles é rigorosamente validado no servidor.
Este guia faz você enviar requisições bem-sucedidas logo na primeira tentativa: o schema de entrada exato (validado em 2026-10-19 contra a API em produção), uma chamada curl pronta para copiar e colar, um script Python completo de envio/consulta/download e os detalhes de produção — callbacks, repetições idempotentes e as respostas de erro que você realmente verá.
O que você vai construir e o que precisa preparar
Objetivo: enviar um prompt de texto, consultar a tarefa e baixar um clipe .mp4 sem áudio (5 ou 10 segundos).
Pré-requisitos:
- Uma chave de API da hiapi — obtenha no seu console. A chave tem o formato
sk-...e vai no cabeçalhoAuthorization: Bearer. É novo na API de tarefas? Comece pelo Início Rápido. - Qualquer cliente HTTP. Mostraremos
curle Python (requests).
A saída do Ray 3.2 é cobrada por clipe, e o preço sobe bastante conforme suas escolhas — consulte as tarifas atuais na página de preços. Enquanto itera nos prompts, comece com 540p / 5 segundos; um clipe de 1080p e 10 segundos pode custar muitas vezes mais que uma renderização de imagem de orçamento modesto, então não deixe seu ciclo de desenvolvimento rodando sempre nas configurações máximas.
O schema de entrada exato (um campo obrigatório, três enums estritos)
Tudo vai dentro de um objeto input. Validado campo a campo contra a API em produção:
| Campo | Tipo | Obrigatório | Valores permitidos | Valor padrão |
|---|---|---|---|---|
prompt |
string | Sim | Descrição da cena, até 6000 caracteres | — |
duration |
integer | Não | 5 ou 10 |
5 |
resolution |
string | Não | 540p, 720p, 1080p |
540p |
aspect_ratio |
string | Não | 16:9, 9:16, 1:1, 4:3, 3:4, 21:9 |
16:9 |
Antes de escrever código, três coisas merecem atenção:
durationé um inteiro, não uma string. Envie o número puro —"duration": 5. Isso é o oposto de alguns outros modelos de vídeo da API de tarefas (por exemplo, o hailuo-2.3 exige"duration": "6"como string). Se você portar o corpo da requisição de um modelo para outro, recheque esse campo; é o erro entre modelos mais comum.- Os enums são validados, não truncados. Valores fora da faixa são rejeitados com
400, não silenciosamente arredondados. Não existe2k, nem480p, nem2:1. - Não há
prompt_optimizer,seednemnegative_prompt. A composição é controlada inteiramente poraspect_ratiomais o prompt. Se você enviar campos que o schema não reconhece, espere um 400 — o schema de entrada de/v1/tasksvaria por modelo, então não presuma que chaves válidas em outro lugar funcionarão aqui.
O que a validação realmente retorna
A seguir, respostas reais do endpoint em produção (valores inválidos enviados de propósito, sem criação de tarefa e sem cobrança):
// POST with "resolution": "2k"
{"code":400,"data":null,"error_code":"INVALID_REQUEST",
"message":"invalid input: resolution: value must be one of '540p', '720p', '1080p'"}
// POST with "duration": 7
{"code":400,"data":null,"error_code":"INVALID_REQUEST",
"message":"invalid input: duration: value must be one of 5, 10"}
// POST with "aspect_ratio": "2:1"
{"code":400,"data":null,"error_code":"INVALID_REQUEST",
"message":"invalid input: aspect_ratio: value must be one of '16:9', '9:16', '1:1', '4:3', '3:4', '21:9'"}
O message indica o campo exato e o conjunto exato de valores permitidos — então, se você esquecer um valor de enum, a API avisa. Observe que os 5, 10 de duration não têm aspas (números), enquanto '540p' de resolution é uma string entre aspas: essa diferença de aspas é a pista de qual campo é inteiro.
Exemplo mínimo executável: curl
Criar a tarefa:
curl -s -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer sk-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "ray-3.2/text-to-video",
"input": {
"prompt": "Em uma noite chuvosa, uma dançarina de rua gira sob os letreiros de neon, poças refletindo luzes rosa e azul, sua jaqueta ondulando enquanto ela gira, câmera em ângulo baixo circulando ao redor dela, estilo cinematográfico",
"duration": 5,
"resolution": "540p",
"aspect_ratio": "9:16"
}
}'
A resposta de criação traz um id de tarefa (truncado):
{ "data": { "taskId": "task_01k..." } }
Consulte até chegar a um estado terminal:
curl -s https://api.hiapi.ai/v1/tasks/task_01k... \
-H "Authorization: Bearer sk-YOUR_KEY"
Enquanto a tarefa está em execução, data.status reporta um estado em andamento. Os dois estados terminais são success e fail. Em caso de sucesso (truncado):
{
"data": {
"taskId": "task_01k...",
"status": "success",
"output": [ { "url": "https://.../clip.mp4" } ]
}
}
Baixe data.output[0].url imediatamente. As URLs de saída são assinadas e expiram — salve os bytes no seu próprio armazenamento em vez de fazer hotlink direto na URL da tarefa. O Ray 3.2 retorna um MP4 sem áudio (sem faixa de áudio), então não espere um fluxo de áudio que nunca virá.
Script Python completo (enviar → consultar → baixar)
import time
import requests
API_BASE = "https://api.hiapi.ai/v1"
API_KEY = "sk-YOUR_KEY"
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
def create_task(prompt: str, duration: int = 5,
resolution: str = "540p", aspect_ratio: str = "9:16") -> str:
resp = requests.post(
f"{API_BASE}/tasks",
headers=HEADERS,
json={
"model": "ray-3.2/text-to-video",
"input": {
"prompt": prompt,
"duration": duration, # 5 or 10 — an INTEGER, not a string
"resolution": resolution, # "540p" | "720p" | "1080p"
"aspect_ratio": aspect_ratio, # "16:9" | "9:16" | "1:1" | "4:3" | "3:4" | "21:9"
},
},
timeout=30,
)
resp.raise_for_status()
return resp.json()["data"]["taskId"]
def wait_task(task_id: str, timeout_s: int = 900, poll_interval: int = 5) -> dict:
deadline = time.time() + timeout_s
while time.time() < deadline:
resp = requests.get(f"{API_BASE}/tasks/{task_id}", headers=HEADERS, timeout=30)
resp.raise_for_status()
task = resp.json()["data"]
if task["status"] == "success":
return task
if task["status"] == "fail":
err = task.get("error") or {}
raise RuntimeError(f"task failed: {err.get('code')}: {err.get('message')}")
time.sleep(poll_interval) # any non-terminal status = still running
raise TimeoutError(f"task {task_id} not finished after {timeout_s}s")
task_id = create_task(
"Um barquinho de papel desce flutuando por uma sarjeta cheia de água da chuva, gotas criam ondulações na superfície, "
"folhas de outono rodopiam à deriva, câmera baixa rente à água, luz suave de dia nublado"
)
print("task created:", task_id)
task = wait_task(task_id)
video_url = task["output"][0]["url"]
# Output URLs expire — download right away and store the bytes yourself.
video = requests.get(video_url, timeout=120).content
with open("ray32-clip.mp4", "wb") as f:
f.write(video)
print(f"saved ray32-clip.mp4 ({len(video) / 1e6:.1f} MB)")
Instale a dependência com pip install requests, troque a chave e, quando a tarefa terminar, você terá um .mp4 no disco. Tarefas de vídeo levam minutos, não segundos — dê ao seu loop de consulta um prazo generoso (15 minutos no exemplo acima) em vez de presumir que retornará rápido.
Considerações de produção: callbacks, idempotência, erros
Prefira callbacks à consulta por polling
Para qualquer uso além de scripts, registre um webhook na criação da tarefa em vez de fazer polling:
{
"model": "ray-3.2/text-to-video",
"input": { "prompt": "...", "duration": 10, "resolution": "720p" },
"callback": { "url": "https://your-app.example.com/hooks/hiapi", "when": "final" }
}
Com "when": "final", a hiapi chama seu endpoint uma vez quando a tarefa atinge o estado terminal — sem tráfego de polling e sem perder a notificação de conclusão entre dois intervalos. Seu handler então faz GET /v1/tasks/<id> (ou lê o corpo entregue) para obter output[0].url. O polling continua válido para CLIs e notebooks que não conseguem expor um endpoint HTTPS.
Torne as repetições idempotentes
Persista o taskId no momento em que a chamada de criação retorna. Se seu processo cair no meio da geração, retome consultando o id já armazenado — não recrie a tarefa, ou você pagará por uma segunda renderização. Só recrie se a requisição de criação original em si falhar antes de retornar um id de tarefa. Como o Ray 3.2 é cobrado por clipe e clipes em alta resolução não são baratos, recriar duplicado é um erro de custo concreto, não apenas perda de tempo.
Os erros que você realmente verá
Cada linha abaixo é um formato de resposta em produção validado:
| Sintoma | Resposta | Correção |
|---|---|---|
| Chave ausente/inválida | 401, aninhado {"error":{"code":"permission_denied","type":"hiapi_error","request_id":"..."}} |
Verifique o cabeçalho Authorization: Bearer sk-... e se a chave tem permissão de acesso. Informe o request_id ao contatar o suporte. |
| Valor de enum inválido | 400 INVALID_REQUEST, plano {"code":400,"error_code":"INVALID_REQUEST","message":"invalid input: <field>: value must be one of ..."} |
Leia o campo indicado no message; ele lista o conjunto exato de valores permitidos. |
duration enviado como string |
400 INVALID_REQUEST |
Envie o inteiro puro 5 ou 10, não "5". |
| Id de modelo desconhecido | 400, error_code: "MODEL_UNAVAILABLE", "model not available via /v1/tasks" |
Use estritamente ray-3.2/text-to-video — confira o id canônico na página do modelo. |
| Id de tarefa errado na consulta | 404, plano {"code":404,"data":null,"message":"task not found"} (atenção: não há error_code no 404) |
O id está errado, ou você consultou com a chave de outra conta. |
status: "fail" na consulta |
Estado terminal da tarefa, detalhes em data.error |
Leia data.error.code / data.error.message. Tarefas com falha são reembolsadas; sinalizações de política de conteúdo e problemas de capacidade da origem aparecem aqui — para sinalização de conteúdo, tente novamente com um prompt reformulado. |
Recursos relacionados
- Página do modelo Ray 3.2 de texto para vídeo — experimente online, status em tempo real e tabela de preços completa
- API de imagem para vídeo Ray 3.2 — mesma família de modelos, mas anima um quadro de referência em vez de partir de texto (o schema de entrada é diferente — investigue antes de reutilizar o corpo desta requisição)
- Como usar a API de texto para vídeo Hailuo 2.3 — uma receita semelhante cujo
durationé uma string, um contraste útil com o inteiro do Ray - Preços da hiapi — tarifas de vídeo por clipe listadas por resolução e duração
Perguntas frequentes
Qual é o id do modelo e qual endpoint devo chamar?
ray-3.2/text-to-video, enviado como model de nível superior para POST https://api.hiapi.ai/v1/tasks, com os parâmetros em input. É assíncrono — você recebe um taskId e depois consulta GET /v1/tasks/<id> (ou registra um callback).
duration é em segundos e por que "5" falha?
Os clipes têm 5 ou 10 segundos e o campo é um inteiro: envie 5 ou 10. Uma string entre aspas, ou qualquer outro número como 7, falha com 400 INVALID_REQUEST: duration: value must be one of 5, 10.
Posso definir resolução e proporção?
Sim — é exatamente nisso que o Ray 3.2 se diferencia de modelos de vídeo só com prompt. resolution aceita 540p, 720p ou 1080p; aspect_ratio aceita um de 16:9, 9:16, 1:1, 4:3, 3:4, 21:9. Ambos são opcionais (padrões 540p e 16:9) e ambos rejeitam valores fora da faixa com 400.
Quanto custa um clipe?
O Ray 3.2 é cobrado por clipe, e a resolução é a maior alavanca — com a mesma duração, um clipe 1080p custa várias vezes o de 540p, e um clipe de 10 segundos custa cerca de três vezes o de 5 segundos. As tarifas mudam, então consulte a página de preços em vez de codificar um número fixo, e faça o protótipo em 540p/5 segundos.
O clipe tem áudio? Não — o texto para vídeo do Ray 3.2 retorna um MP4 sem áudio. Se precisar de som, adicione na pós-produção ou use um modelo de áudio separado.
O Ray 3.2 suporta imagem para vídeo?
Sim, como um id de modelo separado na mesma API de tarefas: ray-3.2/image-to-video. O schema de entrada dele é diferente (recebe uma imagem de referência), então investigue antes de reutilizar o corpo desta requisição — veja a página do modelo de imagem para vídeo.
Minha geração está lenta ou parece travada. O que é normal?
Tarefas de vídeo levam alguns minutos. Trate data.status não terminal no seu loop de consulta como "continue esperando" — reserve um prazo de 10–15 minutos, ou use callback com "when": "final" para a hiapi notificar você no estado terminal em vez de você adivinhar um intervalo.
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