HiAPI
Blogue

Tutorial

Como usar gpt-image-2/text-to-image pela API hiapi: parâmetros, código e exemplo executável

Jun 25, 2026
Como usar gpt-image-2/text-to-image pela API hiapi: parâmetros, código e exemplo executável

Este tutorial mostra o mínimo de código necessário para gerar imagens com gpt-image-2/text-to-image através da API de tarefas unificada da hiapi, e em seguida explica parâmetro por parâmetro, bem como os padrões de nível de produção que você deve adotar depois que o código funcionar (callbacks, idempotência, tratamento de erros).

Pré-requisitos

Você precisa de uma chave de API. Crie-a na página de chaves de API do console hiapi — as chaves começam com sk-. A página do modelo gpt-image-2/text-to-image lista o preço atual por imagem; o detalhamento completo está na página de preços.

Todas as chamadas deste guia vão para o endpoint unificado de tarefas assíncronas:

  • POST https://api.hiapi.ai/v1/tasks — cria uma tarefa de geração
  • GET https://api.hiapi.ai/v1/tasks/{taskId} — consulta o status da tarefa

A documentação de referência geral da plataforma está em documentação da API hiapi.

Exemplo mínimo executável (curl)

Uma única geração é uma interação em duas etapas: primeiro crie a tarefa e depois aguarde sua conclusão.

# 1. Create the task
curl -s -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer sk-YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2/text-to-image",
    "input": {
      "prompt": "a calico cat curled up on a sunlit windowsill, soft focus background",
      "aspect_ratio": "1:1",
      "resolution": "1K"
    }
  }'
# => {"code":200,"data":{"taskId":"tk-hiapi-01KVY...."},"message":"success"}

# 2. Poll until status == "success"
TASK_ID="tk-hiapi-01KVY...."
curl -s "https://api.hiapi.ai/v1/tasks/$TASK_ID" \
  -H "Authorization: Bearer sk-YOUR_KEY"
# => {"code":200,"data":{"status":"success","output":[{"url":"https://..."}], ...}}

A URL da imagem fica em data.output[0].url. Baixe-a imediatamente — output[0].expireAt é curto, portanto essa URL serve apenas para obter a imagem, não para incorporação permanente.

Python: criar + consultar + salvar em disco

import os
import time
import urllib.request
import requests  # pip install requests

API_BASE = "https://api.hiapi.ai/v1/tasks"
TOKEN = os.environ["HIAPI_API_KEY"]  # sk-...

def create_task(prompt: str, aspect_ratio: str = "1:1", resolution: str = "1K") -> str:
    payload = {
        "model": "gpt-image-2/text-to-image",
        "input": {
            "prompt": prompt,
            "aspect_ratio": aspect_ratio,
            "resolution": resolution,
        },
    }
    r = requests.post(API_BASE, json=payload,
                      headers={"Authorization": f"Bearer {TOKEN}"},
                      timeout=60)
    r.raise_for_status()
    body = r.json()
    if body.get("error"):
        raise RuntimeError(f"create failed: {body['error']}")
    return body["data"]["taskId"]

def wait_task(task_id: str, timeout_s: int = 600, poll_s: int = 5) -> dict:
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        r = requests.get(f"{API_BASE}/{task_id}",
                         headers={"Authorization": f"Bearer {TOKEN}"},
                         timeout=30)
        r.raise_for_status()
        task = r.json().get("data") or {}
        status = task.get("status")
        if status == "success":
            return task
        if status == "fail":
            raise RuntimeError(f"task failed: {task.get('error')}")
        time.sleep(poll_s)
    raise TimeoutError(f"task {task_id} did not finish in {timeout_s}s")

if __name__ == "__main__":
    task_id = create_task(
        "a calico cat curled up on a sunlit windowsill, soft focus background",
        aspect_ratio="3:2",
        resolution="1K",
    )
    task = wait_task(task_id)
    url = task["output"][0]["url"]
    urllib.request.urlretrieve(url, "cat.png")
    print(f"saved cat.png from task {task_id}")

Node.js: o mesmo fluxo usando fetch

// Node 18+ has global fetch
const API_BASE = "https://api.hiapi.ai/v1/tasks";
const TOKEN = process.env.HIAPI_API_KEY;

async function createTask(prompt, aspectRatio = "1:1", resolution = "1K") {
  const res = await fetch(API_BASE, {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${TOKEN}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      model: "gpt-image-2/text-to-image",
      input: { prompt, aspect_ratio: aspectRatio, resolution },
    }),
  });
  const body = await res.json();
  if (body.error) throw new Error(`create failed: ${body.error.code} ${body.error.message}`);
  return body.data.taskId;
}

async function waitTask(taskId, { timeoutMs = 600_000, pollMs = 5_000 } = {}) {
  const deadline = Date.now() + timeoutMs;
  while (Date.now() < deadline) {
    const res = await fetch(`${API_BASE}/${taskId}`, {
      headers: { "Authorization": `Bearer ${TOKEN}` },
    });
    const task = (await res.json()).data || {};
    if (task.status === "success") return task;
    if (task.status === "fail") throw new Error(`task failed: ${JSON.stringify(task.error)}`);
    await new Promise(r => setTimeout(r, pollMs));
  }
  throw new Error(`task ${taskId} timed out`);
}

(async () => {
  const id = await createTask(
    "a calico cat curled up on a sunlit windowsill, soft focus background",
    "16:9",
    "1K",
  );
  const task = await waitTask(id);
  const url = task.output[0].url;
  const img = await fetch(url).then(r => r.arrayBuffer());
  const { writeFileSync } = await import("node:fs");
  writeFileSync("cat.png", Buffer.from(img));
  console.log(`saved cat.png from task ${id}`);
})();

Referência de parâmetros

O corpo da requisição sempre contém dois campos de nível superior: model (string, o ID de modelo puro gpt-image-2/text-to-image) e input (objeto de parâmetros específico de cada modelo).

Campo de input Obrigatório Tipo Descrição
prompt Sim string Descrição textual da imagem que você deseja.
aspect_ratio Sim string Um dos valores: 1:1, 3:2, 2:3, 4:3, 3:4, 5:4, 4:5, 16:9, 9:16, 21:9 ou auto.
resolution Não string 1K (padrão), 2K ou 4K. As dimensões em pixels são escaladas de acordo com a proporção escolhida.
callback Não object { "url": "https://yours.example/hook", "when": "final" } — veja a próxima seção.

Uma criação bem-sucedida retorna {"code":200, "data":{"taskId":"tk-hiapi-..."}, "message":"success"}. O GET /v1/tasks/{taskId} retorna data.status como um de handling, success ou fail; em caso de sucesso, data.output é um array cujo primeiro elemento contém a url da imagem e o carimbo de data/hora expireAt.

Outros modelos de imagem da hiapi (por exemplo, z-image, qwen-image) usam campos de input ligeiramente diferentes — aspect_ratio é a convenção adotada por gpt-image-2/text-to-image. Ao trocar de modelo, consulte a página do modelo para confirmar a estrutura exata de input.

Padrões de nível de produção

Usar callbacks em vez de consultas

Consultar a cada 5 segundos é aceitável para prototipagem, mas para tráfego de produção você quer que a hiapi envie a tarefa concluída para você, liberando o worker. Adicione um bloco callback em input:

{
  "model": "gpt-image-2/text-to-image",
  "input": {
    "prompt": "an astronaut sketching the moon",
    "aspect_ratio": "3:2",
    "resolution": "1K",
    "callback": {
      "url": "https://your-app.example.com/webhooks/hiapi",
      "when": "final"
    }
  }
}

when: "final" dispara uma vez quando a tarefa atinge um estado terminal (success ou fail). O payload recebido pelo seu endpoint tem a mesma estrutura de GET /v1/tasks/{id}, portanto o handler pode reutilizar a lógica de parsing da consulta. Verifique o taskId contra o taskId que você armazenou ao criar a tarefa, para saber a qual requisição o callback pertence.

Tornar a operação de criação idempotente

Se o worker falhar após o POST /v1/tasks e antes de armazenar o taskId, você pode acabar gerando a mesma imagem duas vezes. A solução de baixo custo é: no momento em que receber a resposta de criação, armazenar (your_request_id → taskId) no banco de dados na mesma transação que envia a requisição. Se o worker tentar novamente, ele encontrará o taskId existente e retomará a consulta, em vez de criar uma nova tarefa.

Tratar corretamente erros de autenticação

Falhas de autenticação da hiapi retornam HTTP 200 com um payload de erro embutido no corpo da resposta:

{"error":{"code":"permission_denied","message":"This API key cannot use the selected model. ...","type":"hiapi_error"}}

Portanto, um código de status 200 sozinho não significa sucesso. Sempre verifique body.error primeiro; se existir, examine error.code (permission_denied, invalid_request, etc.) e error.message. O request_id na mensagem é o que você deve colar em um ticket de suporte caso precise de ajuda.

Baixar imediatamente e rehospedar por conta própria

data.output[0].url é uma URL de curta duração — a resposta inclui expireAt. Não coloque a URL da hiapi diretamente em um <img src> do seu produto; assim que a tarefa for concluída com sucesso, baixe os bytes imediatamente, envie para o seu próprio armazenamento (S3, R2, Supabase Storage, etc.) e sirva a partir de lá.

Definir timeouts razoáveis

Um padrão razoável é: timeout de 60 segundos para o POST (a criação da tarefa é rápida — na prática você está apenas aguardando a confirmação de recebimento da API), orçamento total de 10 minutos para o loop de consulta e intervalo de 5 segundos entre consultas. Tarefas que levam mais de 10 minutos quase sempre significam que a tarefa entrou silenciosamente no estado fail, portanto expirar e registrar o último corpo de resposta da tarefa no log é mais útil do que esperar indefinidamente.

Perguntas frequentes

Qual é a diferença entre gpt-image-2 e gpt-image-2/text-to-image?

gpt-image-2 é a família de modelos; gpt-image-2/text-to-image é o endpoint específico que você chama para converter um prompt de texto em uma nova imagem. Outras variantes da família expõem estruturas de input diferentes (por exemplo, a edição de imagem aceita imagens de referência). Em caso de dúvida, use o ID de modelo puro que você vê na página do modelo.

O que aspect_ratio: auto faz?

auto permite que o modelo decida a proporção com base no prompt. Use isso quando não houver requisitos rígidos de layout; caso contrário, fixe a proporção você mesmo para que o recorte downstream seja previsível.

Por que minha requisição retorna HTTP 200 com permission_denied?

Ou a chave de API está errada (erro de digitação, revogada, faltando o prefixo sk-), ou o plano dessa chave não inclui gpt-image-2/text-to-image. Abra o console de chaves de API, confirme a string da chave e verifique seu plano na página de preços. Sempre verifique body.error.code — nunca confie apenas no código de status HTTP.

Posso gerar várias imagens em uma única requisição?

gpt-image-2/text-to-image gera apenas uma imagem por tarefa — data.output é um array, mas para esse modelo o comprimento é sempre 1. Para gerar N variantes, dispare N tarefas simultaneamente e use o padrão de callback acima, para não deixar N threads de trabalho penduradas.

Como cancelar uma tarefa em execução?

A API de tarefas unificada atualmente não oferece endpoint de cancelamento. A mitigação mais simples é fazer o worker cliente descartar o resultado quando o usuário não precisar mais dele — a geração já executada ainda será cobrada, portanto o lugar correto para impor cancelamento é antes de chamar POST /v1/tasks.

Como trocar para outro modelo de imagem?

Altere model para o novo ID puro (por exemplo, z-image/text-to-image) e ajuste input para corresponder à estrutura desse modelo. As estruturas variam entre modelos — alguns aceitam size, outros aceitam aspect_ratio, e alguns não aceitam resolution. O catálogo de modelos lista todos os modelos disponíveis, e cada página de modelo documenta seus campos de input.

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