HiAPI
Blogue

Tutorial

Como usar o imagen4-ultra pela API do HiAPI: exemplos em curl e Python

Um exercício prático completo de requisição para geração de imagens de alta qualidade a partir de texto no HiAPI

Oct 31, 2026
博客封面图:淡蓝底上多层半透明玻璃平面叠错排列,折射出克制的冷蓝色带。

O que o imagen4-ultra no HiAPI pode oferecer a você

O imagen4-ultra é o modelo de geração de imagens de alta qualidade a partir de texto do HiAPI: você envia um prompt e recebe uma imagem gerada. O que o torna realmente útil para desenvolvedores é que, assim como todos os outros modelos da plataforma, ele roda por trás da interface unificada do HiAPI, então a forma de autenticação, a estrutura de requisição e o padrão de tratamento de tarefas que você aprende aqui podem ser reaproveitados diretamente em outros endpoints.

Este tutorial é um exercício prático executável, e não uma lista de parâmetros. Ao terminar a leitura, você terá:

  • uma requisição curl pronta para copiar e colar, usada para enviar uma tarefa de geração de imagem a partir de texto,
  • um pequeno cliente em Python reescrito a partir da mesma requisição,
  • uma compreensão clara de como a proporção de tela e outras opções afetam a saída,
  • e um laço de polling para aguardar a conclusão da tarefa e salvar a imagem em disco.

Uma observação inicial sobre expectativas: a geração de imagens não é instantânea. O imagen4-ultra opera de forma assíncrona — você envia a tarefa, recebe um identificador de tarefa e então faz polling até a renderização terminar. Se você já usou outros endpoints assíncronos do HiAPI, esse fluxo será familiar; se não, a seção de polling cobre todo o ciclo de vida.

Vamos nos manter sempre dentro do escopo da própria API do HiAPI: sem SDK específico de fornecedor e sem console de terceiros. Uma URL base, uma chave, um formato de requisição.

Antes de enviar a primeira requisição

Antes que a primeira chamada funcione, você precisa de três coisas.

1. Uma chave de API

Gere a chave no console da sua conta HiAPI. Trate-a como uma senha: guarde-a em uma variável de ambiente, em vez de colá-la diretamente no arquivo-fonte.

export HIAPI_API_KEY="your-key-here"

2. A URL base

Todas as requisições do HiAPI vão para o mesmo host de API documentado na documentação da plataforma. Centralize isso em um único lugar no código, para não acabar com hardcodes em vários pontos:

export HIAPI_BASE_URL="https://api.hiapi.ai"

Se a sua conta ou região usar outro host, utilize o valor mostrado no console — o caminho da requisição abaixo permanece o mesmo.

3. Como as informações de autenticação são enviadas

O HiAPI usa um token bearer no cabeçalho Authorization. Toda requisição — seja de envio ou de polling — carrega os mesmos dois cabeçalhos:

Authorization: Bearer $HIAPI_API_KEY
Content-Type: application/json

É só isso de autenticação. Não há etapa de assinatura de requisição nem troca de token a cada chamada. Se você consegue definir cabeçalhos, consegue chamar esta API.

Antes de continuar, faça uma verificação básica: confirme que sua chave foi exportada na mesma sessão de shell em que você vai executar o curl. Boa parte dos relatos de “401 Unauthorized” acaba se resumindo a uma chave exportada em uma aba de terminal e usada em outra.

Daqui em diante, vamos sempre assumir que o identificador do modelo é imagen4-ultra. Se quiser confirmar a string exata exposta na sua conta, consulte a lista de modelos na documentação.

A requisição curl executável

Abaixo está uma requisição de envio completa. Ela envia o prompt, define a proporção de tela da saída e solicita a geração de uma única imagem.

curl -sS -X POST "$HIAPI_BASE_URL/v1/images/generations" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "imagen4-ultra",
    "prompt": "A lone lighthouse on a rocky coast at dusk, long exposure, dramatic clouds, cinematic lighting",
    "aspect_ratio": "16:9",
    "n": 1
  }'

Explicação campo a campo do corpo da requisição:

  • model —— o identificador do modelo que você está chamando. Ele determina o roteamento da requisição; sem ele, a API não sabe qual modelo executar.
  • prompt —— a descrição em linguagem natural da imagem. É a principal alavanca que afeta a qualidade da saída. Seja específico quanto ao sujeito, à iluminação, ao estilo e à composição; prompts vagos produzem apenas imagens vagas.
  • aspect_ratio —— a forma do canvas de saída, expressa como largura:altura. Mais detalhes adiante.
  • n —— quantas imagens gerar neste envio. Mantenha em 1 durante os testes, para que o custo de cada execução seja fácil de estimar.

Dependendo da configuração do endpoint, a resposta conterá ou a imagem já concluída ou — o que é mais comum para esse tipo de modelo — um objeto de tarefa com um identificador e um campo de status. Capture esse identificador; a seção de polling depende dele.

# 提交响应的典型结构
{
  "id": "job_abc123",
  "status": "queued"
}

Passe a resposta por um formatador JSON (se tiver, | jq .), assim você consegue ler os nomes dos campos conforme a resposta da sua conta, em vez de apertar os olhos para uma linha inteira.

Escrevendo a mesma requisição em Python

A versão em Python é uma tradução linha a linha — mesma URL, mesmos cabeçalhos, mesmo corpo de requisição. Usar requests deixa o mapeamento evidente:

import os
import requests

API_KEY = os.environ["HIAPI_API_KEY"]
BASE_URL = os.environ.get("HIAPI_BASE_URL", "https://api.hiapi.ai")

headers = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}

payload = {
    "model": "imagen4-ultra",
    "prompt": "A lone lighthouse on a rocky coast at dusk, long exposure, dramatic clouds, cinematic lighting",
    "aspect_ratio": "16:9",
    "n": 1,
}

response = requests.post(
    f"{BASE_URL}/v1/images/generations",
    headers=headers,
    json=payload,
    timeout=30,
)
response.raise_for_status()
job = response.json()
print(job["id"], job["status"])

Ao levar este código para um serviço real, vale manter alguns pontos:

  • Leia a chave da variável de ambiente, nunca de um literal no arquivo. A forma os.environ[...] falha de forma explícita quando a variável está ausente, e é exatamente isso que você quer.
  • Defina um timeout explícito para a chamada de envio. A tarefa em si roda de forma assíncrona, então a requisição HTTP deve retornar rápido; um limite de 30 segundos captura problemas de rede em vez de deixar o programa travado.
  • Chame raise_for_status() antes de tocar no JSON. O corpo de uma resposta 4xx não tem a estrutura que você espera; falhar cedo fornece um traceback mais claro do que um KeyError três linhas depois.
  • Reutilize requests.Session se for enviar muitas tarefas — o pool de conexões importa mais do que parece.

Se você preferir httpx ou aiohttp, a conversão é mecânica: mesmo dicionário de headers, mesmo corpo JSON, mesmo caminho. A requisição em si independe da biblioteca HTTP.

Proporção de tela e opções de requisição

A proporção de tela é a opção que você ajusta com mais frequência, porque altera tanto a composição quanto as dimensões de saída disponíveis para o layout a jusante.

A proporção de tela é passada no corpo da requisição como uma string "width:height" — "1:1", "16:9", "9:16", "4:3", "3:2" e assim por diante. Escolha a proporção que corresponde ao uso final da imagem:

  • 1:1 —— avatares, blocos de produto, posts sociais que serão recortados em quadrado.
  • 16:9 / 9:16 —— banners de destaque, thumbnails de vídeo, posicionamentos em formato de story vertical.
  • 4:3 / 3:2 —— composições fotográficas clássicas, layouts de galeria.

Defina a proporção de forma consciente, em vez de gerar um quadrado e depois recortar. O recorte descarta pixels que você já pagou para gerar e ainda pode cortar o sujeito fora do enquadramento. Se você sabe qual é o posicionamento final, codifique isso na requisição.

Além da proporção de tela, as opções que importam no uso diário são:

  • prompt —— continua sendo a entrada de maior impacto. Itere aqui antes de iterar em qualquer outro lugar.
  • n —— a quantidade de imagens geradas por envio. Útil quando você quer várias variantes para escolher; mantenha baixo durante a fase de exploração de prompts.
  • model —— o identificador exato da variante do modelo. Se sua conta expõe vários modelos de imagem, é este campo que alterna entre eles.

Atenha-se aos parâmetros documentados para esse endpoint e não adivinhe nomes. Campos desconhecidos são uma causa comum de respostas 400, e opções com erro de digitação passam facilmente despercebidas em corpos de requisição grandes. Em caso de dúvida, envie primeiro um corpo mínimo — model, prompt, aspect_ratio — confirme que funciona e então adicione uma opção por vez.

Fazendo polling de tarefas assíncronas e baixando o resultado

A geração de imagens leva tempo, então a chamada de envio retorna uma tarefa, não uma imagem. O ciclo de vida é: enviar → consultar o status → baixar a saída.

Passo 1: enviar e capturar o ID da tarefa

Reutilize a requisição anterior e extraia o id da resposta:

job = response.json()
job_id = job["id"]

Passo 2: fazer polling até a tarefa chegar a um estado terminal

Consulte o endpoint de status com os mesmos cabeçalhos de autenticação, dormindo entre cada tentativa. Faça backoff progressivo para evitar sobrecarregar a API:

import time

def wait_for_job(job_id, headers, base_url, timeout=300):
    deadline = time.time() + timeout
    delay = 2
    while time.time() < deadline:
        r = requests.get(
            f"{base_url}/v1/images/generations/{job_id}",
            headers=headers,
            timeout=30,
        )
        r.raise_for_status()
        data = r.json()
        status = data["status"]
        if status == "succeeded":
            return data
        if status == "failed":
            raise RuntimeError(f"job failed: {data}")
        time.sleep(delay)
        delay = min(delay * 2, 15)
    raise TimeoutError(f"job {job_id} not finished within {timeout}s")

Detalhes importantes: um prazo final rígido, limite máximo para o intervalo de backoff e um ramo explícito para o estado de falha, de modo que tarefas com problema se manifestem como exceção em vez de ficar penduradas.

Passo 3: baixar a imagem

A resposta de uma tarefa concluída contém a localização da saída — uma URL ou uma referência equivalente ao artefato. Busque-a e grave os bytes em disco:

result = wait_for_job(job_id, headers, BASE_URL)
image_url = result["output"][0]["url"]

img = requests.get(image_url, timeout=60)
img.raise_for_status()
with open("lighthouse.png", "wb") as f:
    f.write(img.content)

Dois hábitos que evitam a maioria dos imprevistos em produção: grave sempre em modo binário ("wb"), nunca em modo texto; e trate a URL de download como temporária — salve o arquivo imediatamente no seu próprio armazenamento, em vez de contar com a validade indefinida do link.

Erros comuns e como corrigi-los

A maioria das falhas se enquadra em algumas categorias. Abaixo estão as manifestações de cada uma e como resolver.

401 Unauthorized

Chave ausente, malformada ou invisível para o processo que envia a requisição.

  • Verifique se o cabeçalho é exatamente Authorization: Bearer <key> — a palavra Bearer, um espaço e então a chave.
  • Confirme que a variável de ambiente está definida no mesmo shell ou processo. Em containers e CI, as variáveis exportadas no seu shell local não acompanham o código.
  • Se você rotacionou a chave recentemente, verifique se a chave antiga não continua em cache em algum lugar.

400 Bad Request

Normalmente é um problema no corpo da requisição.

  • Nome de campo desconhecido ou com erro de digitação — atenha-se aos parâmetros documentados.
  • Valor de aspect_ratio não aceito pelo endpoint — use o formato width:height da documentação.
  • n fora do intervalo permitido.
  • JSON malformado — por exemplo, vírgula sobrando ou aspas não escapadas dentro da string do prompt. Se suspeitar disso, formate e imprima o corpo da requisição antes de enviar.

404 na consulta de status ou no passo de download

O ID da tarefa está errado, ou o caminho que você consulta não corresponde ao endpoint usado no envio. Registre integralmente a resposta de envio na primeira integração e compare o ID caractere por caractere.

Timeout no polling

Se o wait_for_job atingiu o prazo final:

  • Confirme que você está verificando o valor de status correto; um estado terminal que você não reconhece parece um travamento.
  • Para renderizações grandes e complexas, aumente o timeout total em vez de encurtar o intervalo de polling.
  • Durante a integração, registre cada resposta de status, assim você vê quanto tempo a tarefa realmente leva com a sua combinação de prompts.

A tarefa retorna status failed

Leia o corpo de erro devolvido pela API — ele existe por um motivo. Tarefas com falha costumam ter origem no prompt ou nos parâmetros, então a correção está na requisição, não no código de polling.

Quando algo não estiver claro, a documentação do HiAPI para esse modelo é a fonte autoritativa para nomes de campos e valores aceitos. Valide uma alteração por vez e guarde uma requisição sabidamente funcional como referência para a próxima integração.

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