HiAPI
Blogue

Tutorial

API FLUX 3 Max: geração de vídeo a partir de texto, de imagem para vídeo e keyframes no hiapi

Três IDs de modelo, um fluxo /v1/tasks: curl, script auxiliar em Python, regras da linha do tempo de keyframes e erros de validação reais.

Oct 23, 2026
API FLUX 3 Max: geração de vídeo a partir de texto, de imagem para vídeo e keyframes no hiapi

Resumo

  • O FLUX 3 Max no hiapi são três IDs de modelo independentes no mesmo endpoint POST /v1/tasks: flux-3-max/text-to-video, flux-3-max/image-to-video e flux-3-max/keyframes-to-video. Alternar de modo exige apenas trocar model e um campo de entrada.
  • Os três geram clipes de 5–20 segundos em 720p ou 1080p, cobrados por segundo de saída e por resolução. Consulte os preços em tempo real em /en/pricing.
  • As regras de numeração de frames dos keyframes não são verificadas no momento do envio. Com uma linha do tempo incorreta, a API ainda retorna HTTP 200 e taskId, mas a tarefa falha após cerca de 2 segundos. Valide localmente antes de enviar.

Este guia é específico para o nível Max. Para o modelo base flux-3, com modo rascunho e continuação de vídeo, veja o guia da API de vídeo FLUX.3; para editar material existente, veja edição de vídeo com flux-3.

Pré-requisitos

Crie uma chave no console do hiapi e exporte-a:

export HIAPI_KEY=sk-your-key

O fluxo de requisição é igual para todos os modos: POST /v1/tasks retorna um taskId; em seguida, faça polling em GET /v1/tasks/<taskId> (ou use callback) até que status seja success e baixe data.output[0].url.

Qual ID de modelo usar para cada entrada

Você tem como entrada ID do modelo Campo de entrada a alterar
Apenas um prompt de texto flux-3-max/text-to-video prompt
Uma imagem estática (opcionalmente, mais uma imagem de quadro final) flux-3-max/image-to-video image_url, opcionalmente end_image_url
1–10 imagens que devem aparecer em momentos específicos flux-3-max/keyframes-to-video keyframes: [{image_url, frame_index}]

Campos opcionais compartilhados pelos três: duration (segundos inteiros, 5–20, padrão 5), resolution (720p ou 1080p), aspect_ratio (auto, 21:9, 2:1, 16:9, 4:3, 1:1, 3:4, 9:16), generate_audio (booleano, ativado por padrão) e reasoning_level (low ou high, padrão high). Páginas dos modelos: texto para vídeo, imagem para vídeo, keyframes para vídeo.

Exemplo mínimo: texto para vídeo com curl

curl -X POST "https://api.hiapi.ai/v1/tasks" \
  -H "Authorization: Bearer $HIAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "flux-3-max/text-to-video",
    "input": {
      "prompt": "a slow aerial shot of ocean waves at sunrise, photorealistic",
      "duration": 5,
      "resolution": "720p",
      "generate_audio": false,
      "reasoning_level": "low"
    }
  }'

Quando a requisição é válida, retorna {"code":200,"data":{"taskId":"tk-hiapi-..."},"message":"success"}. Em seguida:

curl https://api.hiapi.ai/v1/tasks/tk-hiapi-... -H "Authorization: Bearer $HIAPI_KEY"

A configuração com generate_audio desativado e 5 segundos de raciocínio low é uma forma barata de testar prompts; a página do modelo indica que o áudio não altera o preço.

Um script auxiliar em Python para os três modos

# pip install requests
import os, time, requests

KEY = os.environ["HIAPI_KEY"]
H = {"Authorization": f"Bearer {KEY}"}
BASE = "https://api.hiapi.ai/v1/tasks"

def submit(mode: str, **inp) -> str:
    """mode: text-to-video | image-to-video | keyframes-to-video"""
    body = {"model": f"flux-3-max/{mode}", "input": inp}
    res = requests.post(BASE, json=body, headers=H, timeout=30).json()
    if res.get("code") != 200:
        # sync 400s look like {"code":400,"error_code":"INVALID_REQUEST","message":"invalid input: ..."}
        raise RuntimeError(res)
    return res["data"]["taskId"]

def wait(task_id: str, timeout_s: int = 900, every: int = 10) -> str:
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        d = requests.get(f"{BASE}/{task_id}", headers=H, timeout=30).json()["data"]
        if d["status"] == "success":
            return d["output"][0]["url"]
        if d["status"] == "fail":
            raise RuntimeError(d.get("error"))
        time.sleep(every)
    raise TimeoutError(task_id)

# 1) text-to-video
t2v = submit("text-to-video",
    prompt="A single white sneaker rotates slowly on a wet black plinth, studio softbox lighting, macro product shot",
    duration=5, resolution="720p", aspect_ratio="16:9", generate_audio=False)

# 2) image-to-video: first frame, optional last frame
i2v = submit("image-to-video",
    prompt="Morning mist drifts over the harbor; the boats rock gently and the camera slowly pushes forward.",
    image_url="https://example.com/harbor.jpg",
    # end_image_url="https://example.com/harbor-end.jpg",   # optional fixed ending
    duration=5, resolution="720p", generate_audio=False)

# 3) keyframes-to-video
FPS = 24
def keyframes_ok(duration: int, frames: list[dict]) -> None:
    idx = [f["frame_index"] for f in frames]
    assert 1 <= len(frames) <= 10, "1-10 keyframes"
    assert len(set(idx)) == len(idx), "frame_index must be unique"
    assert all(0 <= i <= duration * FPS for i in idx), f"frame_index must be 0..{duration * FPS}"

frames = [
    {"image_url": "https://example.com/harbor.jpg", "frame_index": 0},
    {"image_url": "https://example.com/latte.jpg",  "frame_index": 120},
]
keyframes_ok(5, frames)
kf = submit("keyframes-to-video",
    prompt="A continuous cinematic morph from the misty harbor into a close-up of an iced matcha latte.",
    keyframes=frames, duration=5, resolution="720p", generate_audio=False)

url = wait(kf)
open("clip.mp4", "wb").write(requests.get(url).content)

As URLs de saída expiram, portanto, após a tarefa ser concluída com sucesso, baixe ou copie o arquivo imediatamente, em vez de guardar o link.

Keyframes: como funciona a linha do tempo

frame_index é uma posição em um relógio de 24 fps que começa em 0, e não uma porcentagem. O valor máximo permitido é duration × 24: 120 para 5 segundos, 240 para 10 segundos, 480 para 20 segundos. Os índices devem ser únicos e é possível enviar de 1 a 10 keyframes. Para uma transição limpa de A para B, coloque o primeiro ponto de ancoragem em 0 e o último em duration × 24; adiantar o último ponto de ancoragem mantém o final, enquanto atrasá-lo comprime a mudança. Mantenha a proporção de tela igual em todos os keyframes; para um loop contínuo, faça as imagens inicial e final parecerem o mesmo instante.

Considerações para produção

  • Polling ou callback. A API de tarefas aceita callback.url e when: "final", então não é preciso fazer polling; fazer polling a cada 10 segundos, como acima, também funciona bem para scripts e tarefas em lote.
  • Defina sempre um timeout no loop de polling e persista o taskId antes de fazer polling, para que uma falha do programa não faça você perder uma tarefa já paga.
  • Baixe imediatamente. Trate output[0].url como de validade curta.
  • Controle de custos. A cobrança é por segundo de saída e por resolução, então um clipe de 20 segundos em 1080p custa várias vezes mais que um teste de 5 segundos em 720p. Prototipe primeiro com 5 segundos e 720p e aumente ambos depois que o prompt funcionar. Consulte as tarifas atuais na página de preços.

O que testei e o que não testei

Essas verificações foram feitas em 23 de outubro de 2026 contra a API de produção usando uma chave de teste somente leitura. Este artigo não renderizou clipes completos, portanto não faço nenhuma afirmação sobre a qualidade da saída; os prompts de exemplo vêm dos exemplos incluídos nas páginas dos modelos.

Validação síncrona (HTTP 400, não enfileirado). Valores fora do intervalo são rejeitados no momento do envio, retornando error_code: INVALID_REQUEST e uma message legível:

Requisição message da resposta
duration: 3 invalid input: duration: minimum: got 3, want 5
resolution: "4k" value must be one of '720p', '1080p'
aspect_ratio: "5:4" value must be one of 'auto', '21:9', '2:1', '16:9', '4:3', '1:1', '3:4', '9:16'
reasoning_level: "medium" value must be one of 'low', 'high'
image-to-video usando image_urls em vez de image_url image_url: missing required field "image_url"; ... additional properties 'image_urls' not allowed

A última linha é um erro comum: outros modelos de entrada de imagem do hiapi usam o campo no plural, mas o FLUX 3 Max image-to-video aceita apenas um único image_url. Campos desconhecidos são rejeitados, não ignorados.

Erros na linha do tempo de keyframes são assíncronos. Enviei duas requisições de keyframes de 5 segundos, ambas com problemas na linha do tempo: uma usava frame_index: 121 (acima do limite de 120) e a outra tinha dois keyframes em frame_index: 0. Ambas foram aceitas, retornando HTTP 200 e taskId. Cerca de 1–2 segundos após a criação, o polling retornou o estado final:

{"code":200,"data":{"status":"fail","model":"flux-3-max/keyframes-to-video",
 "error":{"code":"INVALID_REQUEST","message":"Invalid request parameters for this model. Please check the request and try again."},
 "taskId":"tk-hiapi-..."},"message":"success"}

Duas conclusões decorrem disso. Primeiro, um envio que retorna 200 não significa que a linha do tempo seja válida, então verifique status e error.code ao fazer polling. Segundo, a mensagem de falha é genérica e não indica qual frame tem problema, e é por isso que vale a pena executar a verificação keyframes_ok acima antes de enviar. A página do modelo informa que tarefas com falha não são cobradas; não verifiquei o registro de cobrança dessas duas tarefas.

Perguntas frequentes

Qual ID de modelo devo usar para quadro inicial mais quadro final? Use flux-3-max/image-to-video, passando image_url e end_image_url. Use keyframes apenas quando precisar de pontos de ancoragem entre o início e o fim.

Adicionar mais keyframes custa mais caro? Segundo a página do modelo, não: a cobrança é por segundo de saída e por resolução, e a quantidade de pontos de ancoragem não afeta o preço.

Qual é a diferença em relação ao flux-3? flux-3-max/* são IDs de modelo independentes, divididos por modo (texto, imagem, keyframes); já o flux-3 base é um único ID que alterna de modo conforme a entrada e também oferece modo rascunho e continuação. Veja o guia da API de vídeo FLUX.3. Não comparei a qualidade de saída dos dois, então escolha com base nos recursos e nas tarifas da página de preços.

Posso usar outro modelo de imagem para vídeo? Sim. Veja outras opções de imagem para vídeo em como usar a API de imagem para vídeo do Ray 3.2.

Artigos relacionados

Ver todos os artigos →

Comece a criar com artefactos de IA persistentes

Obtenha a sua chave de API e chame modelos de imagem, vídeo e áudio através de uma única API baseada em tasks.

Ler a documentação da API