HiAPI
Blogue

Tutorial

Como usar ideogram-v4.5 via API HiAPI: curl, Python e uma requisição que funciona

Oct 31, 2026
封面图:浅灰蓝底上多层半透明玻璃片交叠,折射出克制的蓝色条带,安静而具建筑感。

O que o ideogram-v4.5 na HiAPI traz para você

Quando o texto na imagem realmente importa, o ideogram-v4.5 é o modelo que você deve escolher. Layouts de pôster, marcas gráficas, mockups de embalagem, cards para redes sociais — qualquer cenário em que um título com erro de ortografia ou uma legenda borrada arruína o material é exatamente onde este modelo agrega valor. Se você vai gerar texturas abstratas ou paisagens fotográficas, nas quais nada precisa estar legível, os modelos de imagem genéricos costumam ser mais baratos e mais rápidos.

Este artigo é um guia de integração, não uma avaliação do modelo. Ao final você terá uma requisição funcional, um cliente Python que faz o mesmo, e uma função auxiliar reutilizável que cobre a parte em que as pessoas costumam errar: o parâmetro de proporção, a consulta (polling) de tarefas assíncronas e a obtenção da saída.

Um ponto que precisa ser internalizado desde cedo: a geração de imagens na HiAPI é uma API de tarefas assíncronas. Você envia a requisição, recebe um identificador e então consulta até a tarefa concluir. Código que assume que a imagem já vem no corpo da resposta não funciona. Cada seção abaixo converge para esse padrão.

Antes de enviar a requisição

Antes da primeira chamada, é preciso ter quatro coisas prontas.

1. Chave de API

Crie uma no console da sua conta HiAPI e mantenha-a longe do controle de versão. Exporte-a como variável de ambiente em vez de colá-la no script:

export HIAPI_API_KEY="your_key_here"

2. URL base

Todas as requisições vão para a URL base da API HiAPI, acrescida do caminho específico do endpoint de geração. A documentação da plataforma lista o caminho atual; se a documentação disser algo diferente, não codifique o caminho que você viu em posts de blog (incluindo este).

3. Identificador do modelo

A string de modelo que você envia no corpo da requisição identifica o ideogram-v4.5. Use a capitalização exata exibida na lista de modelos da plataforma — identificadores de modelo são correspondidos literalmente, e o menor desvio retorna um erro de validação em vez de uma sugestão útil.

4. Referência de parâmetros

A página do modelo ideogram-v4.5 é a fonte autoritativa de quais campos o corpo da requisição aceita: limite de comprimento do prompt, proporções suportadas, formato de saída e qualquer controle de seed ou estilo. Leia antes de escrever código. Parâmetros não listados ali podem ser silenciosamente ignorados ou rejeitados, e adivinhar valores é a forma mais comum de desperdiçar tempo com depuração.

Com essas quatro coisas, você já pode enviar a primeira requisição.

Uma requisição curl que funciona

Abaixo, um exemplo mínimo de envio. Se sua conta exibir valores diferentes, substitua o caminho do endpoint e o identificador do modelo pelos da documentação da plataforma.

curl -X POST "$HIAPI_BASE_URL/<generation-path>" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "ideogram-v4.5",
    "input": {
      "prompt": "A vintage travel poster for the Amalfi Coast, bold serif headline reading \"AMALFI\", warm sunset palette, grainy print texture"
    }
  }'

O que cada parte faz:

  • Authorization — autenticação por bearer token. Cabeçalho ausente ou mal formatado é a causa mais comum de 401.
  • Content-Type — deve ser application/json. Alguns clientes HTTP não o definem automaticamente em POST, gerando erros de parsing confusos no servidor.
  • model — o identificador literal do modelo. Coloque-o no nível superior do corpo, conforme a documentação.
  • input.prompt — sua instrução de geração. Como mostrado acima, coloque entre aspas o texto que você quer renderizado na imagem, para que o modelo o trate como texto literal em vez de descrição.
  • input.* — todos os demais parâmetros de geração (proporção, formato, seed etc.) pertencem a este objeto aninhado, ao lado de prompt.

Um envio bem-sucedido retorna um objeto JSON contendo o identificador da tarefa e um campo de status. Não há imagem nessa resposta — isso é o comportamento esperado. Guarde o identificador; a etapa de consulta vai usá-lo.

A mesma chamada em Python

A versão Python é uma tradução um para um. Usamos requests e compartilhamos o mesmo corpo de requisição, para que você possa compará-los lado a lado.

import os
import json
import requests

API_KEY = os.environ["HIAPI_API_KEY"]
BASE_URL = os.environ["HIAPI_BASE_URL"]
GEN_PATH = "/<generation-path>"  # confirm in platform docs

payload = {
    "model": "ideogram-v4.5",
    "input": {
        "prompt": (
            "A vintage travel poster for the Amalfi Coast, bold serif "
            'headline reading "AMALFI", warm sunset palette, grainy print texture'
        )
    },
}

response = requests.post(
    BASE_URL + GEN_PATH,
    headers={
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json",
    },
    data=json.dumps(payload),
    timeout=30,
)
response.raise_for_status()

job = response.json()
print(job)

Duas escolhas intencionais:

  • json.dumps em vez de json= mantém o formato de transporte visivelmente consistente com o exemplo curl. Ambos funcionam; a forma explícita facilita inspecionar o que você realmente envia durante a depuração.
  • timeout=30 apenas no envio. O envio é rápido; a geração não. Nunca deixe a chamada de envio herdar um timeout curto destinado à consulta, ou você reportará tarefas saudáveis como falhas.

O dicionário job impresso contém o identificador da tarefa e o status atual. Guarde o identificador em algum lugar — o loop de consulta depende dele.

Controlar proporção e formato de saída

Proporção e formato de saída são parâmetros do corpo, não endpoints separados. Eles ficam no mesmo objeto input do prompt:

{
  "model": "ideogram-v4.5",
  "input": {
    "prompt": "...",
    "aspect_ratio": "<ratio from docs>",
    "output_format": "<format from docs>"
  }
}

A disciplina importante aqui é não adivinhar valores. Cada modelo de geração expõe um conjunto fixo de proporções e formatos, e modelos diferentes aceitam grafias diferentes — 16:9 versus 16x9, png versus PNG, etc. Passar um valor não suportado costuma gerar erro de validação ou, pior, cair silenciosamente no padrão, o que parece um bug no seu prompt.

Então o fluxo é:

  1. Abra a página do modelo ideogram-v4.5 na plataforma e copie palavra por palavra a lista de proporções suportadas e a de formatos de saída.
  2. Coloque esses valores em uma pequena lista de permissão no código, para que entradas inválidas falhem no ponto de chamada, não na API.
  3. Use por padrão a proporção que bate com o layout de destino. Se a imagem vai ocupar um card social de 1200×630, escolha um valor próximo dessa proporção em vez de gerar um quadrado e cortar o conteúdo.

Imagens com muito texto merecem um aviso extra: proporções extremas (banners ultralargos, pôsteres ultraaltos) comprimem o espaço disponível para renderizar texto. Para títulos que você realmente precisa que sejam legíveis, proporções moderadas em paisagem ou retrato são mais seguras do que extremos panorâmicos.

Lidar com a tarefa assíncrona e baixar o resultado

O ciclo de vida de uma geração tem três etapas: enviar → consultar → obter.

Enviar

Você já dominou esta etapa nas seções anteriores. A resposta devolve um identificador de tarefa e um status, como queued ou processing.

Consultar

Consulte o endpoint de status da tarefa com esse identificador até que o status indique conclusão. Duas regras mantêm o processo saudável:

  • Durma entre consultas. Comece com cerca de um segundo e aumente progressivamente. Martelar o endpoint de status não faz a tarefa terminar mais rápido e ainda arrisca acionar limites de taxa.
  • Limite o tempo de espera. Defina um número máximo de tentativas ou um prazo final e retorne um erro explícito ao ultrapassar, em vez de entrar em loop infinito.
import time

def wait_for_job(job_id, headers, base_url, status_path,
                 max_attempts=60, initial_delay=1.0, factor=1.5):
    delay = initial_delay
    for _ in range(max_attempts):
        r = requests.get(
            f"{base_url}{status_path}/{job_id}",
            headers=headers,
            timeout=30,
        )
        r.raise_for_status()
        data = r.json()
        status = data.get("status")
        if status in ("succeeded", "completed", "success"):
            return data
        if status in ("failed", "error", "cancelled"):
            raise RuntimeError(f"job {job_id} ended with status {status}: {data}")
        time.sleep(delay)
        delay *= factor
    raise TimeoutError(f"job {job_id} did not finish in time")

Consulte a documentação da plataforma para obter as strings de status e o caminho de status exatos da sua conta — faça a correspondência com os valores da documentação e trate qualquer status não reconhecido como ainda em execução, não como sucesso.

Obter

Quando a tarefa reporta conclusão, a resposta contém o local da saída (normalmente uma URL). Baixe com um GET comum e grave os bytes em disco. A URL de saída pode ter validade temporária, então baixe o quanto antes em vez de guardar a URL para depois. Tudo o que você precisa saber para escrever esse loop vem da estrutura da resposta de envio — não há uma API separada de "obter imagem" para aprender.

Empacotar em uma função auxiliar reutilizável

Três scripts separados que reimplementam a consulta cada um é um problema de manutenção. Empacote uma vez.

import os, json, time, requests

class IdeogramClient:
    def __init__(self, base_url, api_key, gen_path, status_path,
                 poll_attempts=60, poll_factor=1.5):
        self.base_url = base_url.rstrip("/")
        self.gen_path = gen_path
        self.status_path = status_path
        self.poll_attempts = poll_attempts
        self.poll_factor = poll_factor
        self.headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json",
        }

    def generate(self, prompt, **params):
        body = {"model": "ideogram-v4.5", "input": {"prompt": prompt, **params}}
        r = requests.post(self.base_url + self.gen_path,
                          headers=self.headers,
                          data=json.dumps(body), timeout=30)
        r.raise_for_status()
        job = r.json()
        done = self._wait(job["id"])
        url = done["output"]["url"]  # confirm shape in docs
        return self._download(url)

    def _wait(self, job_id):
        delay = 1.0
        for _ in range(self.poll_attempts):
            r = requests.get(f"{self.base_url}{self.status_path}/{job_id}",
                             headers=self.headers, timeout=30)
            r.raise_for_status()
            data = r.json()
            if data.get("status") in ("succeeded", "completed", "success"):
                return data
            if data.get("status") in ("failed", "error", "cancelled"):
                raise RuntimeError(data)
            time.sleep(delay)
            delay *= self.poll_factor
        raise TimeoutError(job_id)

    def _download(self, url):
        r = requests.get(url, timeout=60)
        r.raise_for_status()
        return r.content

O uso é uma única chamada: img_bytes = IdeogramClient(...).generate("...", aspect_ratio="<from docs>"). Ajuste o acesso a done["output"]["url"] e as strings de status para bater com a estrutura de resposta da documentação — esses dois pontos são os mais prováveis de precisar de ajuste fino por conta.

Erros comuns e dicas de depuração

A maioria das falhas da primeira semana se enquadra em cinco categorias.

401 / 403 — autenticação. Chave ausente, com espaços em branco por causa de copiar e colar, ou sem o prefixo Bearer . Imprima os quatro primeiros e os quatro últimos caracteres da chave que você está realmente enviando; quebras de linha vindas de arquivos de ambiente são o clássico culpado.

400 — JSON malformado ou campo desconhecido. Se o corpo foi montado por concatenação de strings, aspas não escapadas no prompt quebram o JSON. Construa o corpo como dicionário e serialize com json.dumps. Se o JSON faz parsing, o próximo suspeito é um nome de parâmetro que o modelo não aceita — confira suas chaves caractere por caractere contra a página do modelo.

404 / modelo não encontrado. Normalmente é erro de grafia ou de capitalização no identificador do modelo, ou um caminho de endpoint desatualizado. Copie ambos da documentação da plataforma, não de memória nem de tutoriais antigos.

429 — limite de taxa. Quase sempre é consulta agressiva demais. Aumente o atraso inicial de consulta e o fator de recuo. No lado do envio, adicione retentativas com jitter para respostas 429 e 5xx, mas não repita erros de validação 4xx — eles falham da mesma forma sempre.

Tarefa concluída, mas a imagem não abre. Verifique se você baixou bytes e não uma página JSON de erro; chamar raise_for_status() no GET de download captura a maioria desses casos. Confirme também que você trata a URL de download como de curta duração, em vez de cacheá-la entre sessões.

Em caso de dúvida, registre o corpo completo da resposta e o código de status de cada chamada da cadeia inteira — envio, cada consulta e download. A API normalmente diz exatamente o que deu errado; o bug costuma ser que nunca olhamos.

Com um envio funcional, um loop de consulta e tratamento de erros razoável, o ideogram-v4.5 se integra a um pipeline real como qualquer outra chamada de modelo da HiAPI.

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