Tutorial
Como usar o flux-1.1-pro via API da HiAPI: curl, Python e requisições executáveis
Um guia prático de integração: requisições que realmente funcionam, processamento assíncrono e receitas de prompt com saídas reais
Nesta página
O que o flux-1.1-pro oferece antes de você escrever código
O flux-1.1-pro é um modelo de texto para imagem, chamado por meio do HiAPI.ai como um endpoint gerenciado. Você envia o prompt e os parâmetros de geração em JSON, e o retorno é a imagem gerada. Não há nada para instalar, nenhum peso de modelo para hospedar por conta própria e nenhum recurso de GPU para gerenciar. Sua superfície de integração é um endpoint HTTP, mais credenciais para autenticação.
Para o desenvolvedor, isso significa que três coisas moldam seu design antes mesmo da primeira linha de código.
Primeiro, a requisição é JSON entra, imagem sai. Seu prompt, a proporção da imagem e alguns parâmetros de controle ficam no corpo da requisição. A resposta traz os dados da imagem ou uma referência a eles, dependendo de como a tarefa é entregue. Trate o corpo da requisição como um contrato e mantenha-o em um único lugar, para que os caminhos curl e Python nunca divirjam.
Segundo, a geração de imagem é uma operação lenta em comparação com uma chamada de API comum. Alguns segundos são normais; prompts complexos em alta resolução podem levar mais tempo. Qualquer chamador em produção deve assumir a latência e planejar para ela, em vez de tratar a chamada como uma leitura de banco de dados.
Terceiro, a qualidade da saída é determinada principalmente pelo prompt, não pela fiação. A integração é a parte fácil. O trabalho real está em descrever com precisão o que você quer e validar sua receita com saídas reais antes de ir para produção.
Com essas três coisas em mente, o restante deste guia é um processo mecânico: montar a requisição, confirmar que ela funciona, portá-la e então reforçá-la e ajustá-la. Do início ao fim, tudo passa pela API da HiAPI — uma credencial, uma URL base, uma estrutura JSON para aprender.
Sua primeira requisição curl
Comece com curl. Ele elimina todas as camadas de abstração entre você e o endpoint, então, quando algo falhar, você sabe que o problema está no corpo da requisição, não no seu framework.
Uma chamada mínima tem três partes: o endpoint, o cabeçalho de autenticação e o corpo JSON.
curl -X POST "https://api.hiapi.ai/v1/images/generations" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "flux-1.1-pro",
"prompt": "a ceramic coffee mug on a weathered wooden table, soft morning window light, shallow depth of field, product photography",
"aspect_ratio": "1:1"
}'
Leia o corpo da requisição campo por campo:
modelespecifica o modelo que você quer usar. Escreva-o explicitamente, para que mudanças futuras no padrão nunca alterem silenciosamente sua saída.prompté a descrição em linguagem natural. Quase todo o seu orçamento de qualidade está aqui.aspect_ratiocontrola o enquadramento. Escolha-o de forma intencional, em vez de depender de um padrão que você não validou.
Coloque a chave em uma variável de ambiente (HIAPI_API_KEY), em vez de colá-la diretamente no comando. Esse hábito se estende diretamente ao Python e a qualquer etapa de CI que você adicionar depois.
Quando a chamada é bem-sucedida, você recebe uma resposta JSON descrevendo a imagem concluída. Antes de fechar o terminal, inspecione-a e localize a referência ou os dados da imagem. Quando a chamada falha, você recebe um corpo de erro com o código de status e a mensagem; leia a mensagem literalmente, pois formatação incorreta de campo é a causa mais comum de falha na primeira tentativa.
Um aviso que economiza uma hora: não cole prompts multilinha com aspas não escapadas no shell. Para qualquer coisa maior que uma frase curta, use um heredoc ou um arquivo.
curl -X POST "https://api.hiapi.ai/v1/images/generations" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
--data @request.json
Esse request.json é o artefato que você deve versionar. Ele é a fonte única da verdade do corpo da requisição, e a próxima seção o reutiliza exatamente como está.
Porte a mesma chamada para Python
O objetivo do porte não é escrever nova lógica, mas enviar exatamente o mesmo corpo JSON. Carregue o mesmo request.json, para que os dois caminhos não possam divergir.
import json
import os
import requests
API_URL = "https://api.hiapi.ai/v1/images/generations"
with open("request.json") as f:
payload = json.load(f)
response = requests.post(
API_URL,
headers={
"Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}",
"Content-Type": "application/json",
},
json=payload,
timeout=120,
)
if response.status_code != 200:
print(response.status_code)
print(response.text)
response.raise_for_status()
print(response.json())
Três detalhes importam aqui.
Os cabeçalhos de autenticação são o mesmo conjunto de cabeçalhos. Usar json=payload faz o requests serializar o corpo e definir o tipo de conteúdo por você; declarar o cabeçalho explicitamente é inofensivo e documenta a intenção.
Defina um timeout. Nunca deixe uma requisição de geração pendurada em um padrão sem limite. Um timeout explícito e generoso é aceitável — o importante é que seja explícito.
Verifique o corpo de erro antes de lançar a exceção. Se você chamar raise_for_status() primeiro, ele descarta o corpo da resposta dos seus logs. Imprima o código de status e o texto primeiro, depois lance. Quando um campo for rejeitado, você vai precisar desse texto.
Se você estiver padronizando em um cliente HTTP assíncrono, a estrutura não muda: mesma URL, mesmos cabeçalhos, mesmo corpo, apenas await client.post(...) com o mesmo timeout. O contrato do corpo da requisição é a constante; o cliente é um detalhe de implementação.
Mantenha o corpo da requisição fora do código-fonte Python. Quando uma receita de prompt funciona, ela deve pertencer a um arquivo ou a uma linha do banco de dados, não a um literal de string enterrado em uma função, para que você possa compará-la e executá-la novamente.
Trate tarefas assíncronas sem bloquear sua aplicação
Trate a geração como uma tarefa, não como uma chamada de função. Seja qual for o seu caminho de entrega — parecendo síncrono ou retornando uma tarefa que você precisa consultar —, a consequência prática é a mesma: sua aplicação nunca deve ocupar uma thread de requisição indefinidamente esperando por uma imagem.
Um padrão viável tem quatro etapas.
1. Envie a partir de um worker, não da requisição do usuário
Aceite a ação de geração do usuário na camada web, persista um registro da tarefa, coloque-a na fila e retorne imediatamente. Um worker em segundo plano faz a chamada real à API. O usuário consulta o seu endpoint, não o modelo.
2. Defina limites para a espera
Defina um timeout para cada tentativa que você escolheu deliberadamente. Se a plataforma retornar uma tarefa que você precisa consultar, faça a consulta em intervalos fixos, com um número máximo de tentativas e um prazo limite calculado a partir do momento de início da tarefa (não do número de tentativas). Prefira um backoff moderado a um loop apertado.
3. Só repita falhas que valem a pena repetir
Repita com backoff exponencial e jitter erros de transporte, timeouts e falhas do servidor, limitados a um pequeno número de tentativas. Não repita erros de validação: um campo rejeitado ou um prompt vazio falhará da mesma forma todas as vezes, e a repetição só faz o usuário esperar mais antes de ver a mensagem real.
4. Torne a tarefa idempotente do seu lado
Registre no banco de dados o corpo exato da requisição e o ID da tarefa. Se seu worker travar depois do envio mas antes de registrar o sucesso, você pode reconsultar a tarefa em vez de reenviar cegamente. Quando precisar reenviar, adicione uma chave curta de deduplicação do lado do cliente, para que uma falha transitória não enfileire a mesma geração três vezes.
import time
def poll_until_done(fetch_status, job_id, deadline_seconds=180):
start = time.monotonic()
delay = 2.0
while True:
status = fetch_status(job_id)
if status["state"] in ("succeeded", "failed"):
return status
if time.monotonic() - start > deadline_seconds:
raise TimeoutError(f"generation {job_id} exceeded deadline")
time.sleep(delay)
delay = min(delay * 1.5, 10.0)
Esse helper é deliberadamente genérico: ele recebe uma função que busca o status, então o mesmo loop serve para qualquer endpoint baseado em tarefas que você integrar depois. As propriedades que importam são o prazo limite, o backoff com teto e a verificação de estado terminal — não o transporte específico.
Construa prompts que renderizam de forma consistente
Prompt longo não significa prompt melhor. Estrutura significa. Um esqueleto repetível lhe dá resultados consistentes e um lugar para mudar uma variável de cada vez quando algo dá errado.
Use quatro espaços nesta ordem:
- Assunto — o que está na imagem, de forma específica. “Uma caneca de cerâmica de café” é melhor que “alguma coisa para uma cafeteria”.
- Estilo — o tom visual: fotografia, ilustração, aquarela, renderização 3D, fotografia de produto. Declare o meio e, quando for útil, a iluminação.
- Composição — enquadramento e câmera: proporção, distância de captura, ângulo, profundidade de campo, posição do assunto no quadro.
- Restrições — o que você quer e não quer explicitamente, de forma breve.
[subject] a single ceramic coffee mug, matte glaze, small handle
[style] product photography, soft diffused window light, muted palette
[composition] 1:1, eye-level, subject centered, shallow depth of field, plain background
[constraints] no text, no logos, no hands
Ao enviar, achate tudo em um único prompt; os colchetes são para você, não para o modelo. O valor de escrever por espaços é que, quando a saída estiver errada, você sabe qual espaço editar.
Algumas regras práticas:
- Coloque o assunto primeiro. A primeira oração tem o maior peso.
- Prefira substantivos e adjetivos concretos a palavras abstratas de emoção. “Matte glaze” muda pixels; “premium feel” basicamente não muda.
- Coloque a linguagem de câmera no espaço de composição, não no de assunto. Misturar gera instruções ansiosas e contraditórias.
- Itere mudando um espaço de cada vez e guarde o texto exato do prompt que produziu a saída aceita.
A proporção é uma decisão de composição, não um remendo de última hora. Escolha-a para corresponder ao local onde a imagem aparecerá — quadrada em grades, mais alta em banners hero — e ajuste o restante do prompt para aquele quadro.
Use listas de termos negativos com eficácia
A lista de termos negativos diz ao modelo o que evitar. É uma ferramenta afiada, com um escopo útil estreito: ótima para suprimir defeitos recorrentes, mas péssima como cesto de lixo onde se listam todas as imperfeições que você consegue imaginar.
Termos negativos devem ser curtos e específicos. Para a maioria dos prompts, cinco a oito itens curtos bastam. Declare coisas concretas:
no text, no watermark, no logos, no extra fingers, no harsh shadows
Essa lista funciona porque cada item nomeia algo visível e verificável. Compare com negações vagas como “not ugly” ou “bad quality” — elas carregam quase nenhum sinal acionável e diluem os itens que realmente importam.
Onde os termos negativos realmente ajudam:
- Suprimir defeitos que você vê repetidamente. Se mãos ou texto aparecem repetidamente, declará-los é a correção mais direta.
- Higiene de marca e jurídica. Exclua logos e marcas d'água antes que a imagem chegue a uma interface voltada ao usuário.
- Forçar fundos limpos para imagens de produto ou imagens próximas de UI.
Onde eles trabalham contra você:
- Contradizer o prompt positivo. “No shadows” nos negativos contra “dramatic side light” no assunto é um conflito que o modelo resolverá de forma imprevisível. Corrija o prompt positivo.
- Negar coisas que dificilmente aconteceriam. Uma longa lista de falhas improváveis só adiciona ruído e não muda a renderização.
- Usar negativos para compensar um assunto vago. Se o assunto não está claro, nenhuma lista de negativos o salva.
Um detalhe prático: alguns clientes aceitam termos negativos como campo separado, em vez de texto anexado. Confirme qual forma sua requisição suporta e mantenha esse campo no corpo da requisição que você guarda, para que curl e Python se comportem de forma idêntica.
Receitas de prompt com saídas reais
As receitas abaixo são pontos de partida, não garantias. O fluxo de trabalho honesto é: executar a receita pela sua própria integração, olhar a saída e ajustar um espaço. Qualquer saída que você não gerou pessoalmente deve ser tratada como não validada.
Receita 1 — Foto de produto limpa
A single matte-black wireless earbud case on a light concrete surface,
studio product photography, soft key light from the left, 1:1, centered,
shallow depth of field, plain background. No text, no logos, no hands.
Características esperadas: assunto nítido e centralizado, queda suave e fundo sem desordem. Se a superfície parecer muito elaborada, reforce “plain background” e remova qualquer palavra de textura. Se a luz estiver plana demais, adicione uma palavra direcional — só isso.
Receita 2 — Retrato editorial
Portrait of a person in a wool coat, natural window light, calm expression,
3:4, chest-up framing, subject slightly off-center, muted film palette.
No text, no watermark.
Características esperadas: luz direcional suave, cores contidas. Se o enquadramento vier mais amplo que o esperado, mova “chest-up framing” para mais cedo e remova palavras de composição concorrentes.
Receita 3 — Ilustração isométrica
Isometric illustration of a small reading nook: armchair, floor lamp, bookshelf,
flat vector style, limited palette of warm neutrals and one accent color,
1:1, centered composition, clean white background. No text, no gradients.
Características esperadas: geometria limpa e preenchimentos planos. Se a paleta derivar, declare a cor de destaque explicitamente e mantenha “clean white background” como a última oração, para que ela prevaleça.
Receita 4 — Banner hero
A wide misty mountain ridge at sunrise, layered depth, minimal detail,
16:9, subject occupying the lower third, generous empty sky for overlaid text.
No text, no watermark.
Características esperadas: imagem silenciosa e com pouco detalhe, com espaço negativo utilizável. A frase “overlaid text” reserva o espaço; ela não renderiza letras, e a lista de negativos mantém o texto fora da própria imagem.
Para cada receita, registre o corpo exato da requisição, a proporção e a data. Ao revisar um mês depois, você pode reexecutar o corpo registrado e comparar com a saída registrada, em vez de adivinhar por que o resultado mudou.
Erros, limites e o que verificar primeiro
Quando uma geração falha ou a saída está errada, antes de mexer no código, percorra esta lista.
Verifique o corpo da requisição primeiro
- O corpo é JSON válido? Vírgulas finais ou aspas não escapadas são a causa mais comum de falha na primeira tentativa. Valide o
request.jsonque você guarda antes de enviar. - Os nomes dos campos estão exatamente corretos? Parâmetros com erro de digitação costumam ser rejeitados ou silenciosamente ignorados. Compare com a estrutura de requisição da documentação, não com a memória.
- O nome do modelo está correto e existe? Não dependa de padrões.
- O prompt não está vazio e está dentro do comprimento especificado na documentação? Os limites estão na documentação da plataforma; leia lá em vez de assumir um número.
Depois verifique autenticação e transporte
- A chave de API existe e é válida no momento? Um 401 geralmente significa cabeçalho ausente, malformado ou chave rotacionada.
- A URL do endpoint e o método estão corretos? Enviar POST para um caminho GET falha de um jeito que parece problema de chave.
- Seu timeout está curto demais? Se seu cliente desiste antes da tarefa terminar, o timeout que você vê não tem relação com o modelo.
Depois verifique a estrutura da requisição
- A classe do código de status indica onde olhar. 4xx quase sempre é problema da sua requisição; 5xx costuma ser transitório e merece nova tentativa limitada.
- Leia a mensagem de erro literalmente. Imprima o corpo da resposta antes de lançar a exceção. O campo mencionado na mensagem é o campo a corrigir.
- Respostas de rate limit ou cota significam desacelerar e tentar de novo com backoff, não reescrever o prompt.
Por fim, verifique o prompt
Se a chamada foi bem-sucedida mas a imagem está errada, você está no domínio do prompt, não no domínio do erro:
- Assunto ausente ou genérico demais? Mova-o para a primeira oração e torne-o específico.
- Composição errada? Corrija a proporção e as palavras de enquadramento juntas; não use uma para compensar a outra.
- Defeitos recorrentes? Adicione um termo negativo curto e específico.
- Há contradição? Encontre o termo negativo que briga com o prompt positivo e remova-o.
O mais importante é manter um hábito: registre o corpo exato da requisição, o status da resposta e a referência da imagem gerada para cada geração que importa para você. A reprodutibilidade transforma a depuração de adivinhação em diff. Monte sua primeira requisição, confirme a saída, depois aperte o prompt antes de ir para produção — e guarde o corpo da requisição que você usou ao entrar em produção, para que a próxima mudança tenha uma base real de comparação.
Artigos relacionados
Ver todos os artigos →-
Tutorial
gemini-omni-1.2-flash na prática: 3 cenários de negócio de geração de vídeo e uma checklist de implementação
Três cenários de aplicação: texto criativo, animação de primeiro frame e restrição visual por imagem de referência
-
Tutorial
Como chamar gpt-image-2.5-sunburst/text-to-image pela API HiAPI: curl e Python
Um roteiro de integração com requisições funcionais, tratamento de imagens de referência e padrões de retentativa
-
Tutorial
Como chamar gpt-5.6-terra@azure pela API da HiAPI: guia com curl e Python
Monte uma requisição funcional, adicione streaming e chamada de ferramentas e trate erros sem chutar