HiAPI
Blogue

Tutorial

Gerar imagens de produto em dimensões exatas via API: proporções e especificações de marketplaces

Jul 9, 2026
Gerar imagens de produto em dimensões exatas via API: proporções e especificações de marketplaces

Cada canal de vendas exige um tamanho diferente para as suas imagens de produto: a Amazon quer imagens quadradas grandes com fundo branco, o Instagram quer composições verticais 4:5, o Pinterest quer Pins 2:3, e o banner principal da sua própria loja precisa de imagens ultrawide. Este guia mostra como gerar programaticamente imagens em todos esses tamanhos com a API hiapi — usando gpt-image-2 e wan2.7-image — e como chegar com precisão à dimensão final em pixels todas as vezes.

Pré-requisitos: uma chave de API hiapi (crie no console) e curl ou Python. O custo total depende do modelo e da resolução escolhidos — consulte preços.

Como os tamanhos de imagem realmente funcionam na API

Primeiro, o ponto que mais confunde: os modelos de imagem da hiapi não aceitam dimensões em pixels. Não há campos size, width ou height. Se você tentar enviá-los, a API informa explicitamente:

{
  "code": 400,
  "error_code": "INVALID_REQUEST",
  "message": "invalid input: <root>: additional properties 'size' not allowed"
}

Em vez disso, o tamanho é controlado por dois campos dentro de input:

  • aspect_ratio — a forma do enquadramento, escolhida de uma lista fixa por modelo.
  • resolution — o nível de saída: "1K", "2K" ou "4K" (o lado maior tem aproximadamente 1024 / 2048 / 4096 pixels; o número exato de pixels varia conforme a proporção, então sempre verifique o arquivo que você recebeu).

A seguir estão os parâmetros que os dois modelos deste guia realmente aceitam (verificados na API em produção):

gpt-image-2 wan2.7-image/text-to-image
prompt Obrigatório Obrigatório
aspect_ratio auto, 1:1, 3:2, 2:3, 4:3, 3:4, 5:4, 4:5, 16:9, 9:16, 2:1, 1:2, 3:1, 1:3, 21:9, 9:21 — 16 valores no total 1:1, 16:9, 4:3, 21:9, 3:4, 9:16, 8:1, 1:8 — 8 valores no total
resolution 1K, 2K, 4K 1K, 2K, 4K
Recursos adicionais Variante de imagem para imagem (gpt-image-2/image-to-image) seed (inteiro) para reprodução
size em pixels / n Não aceito Não aceito

A diferença prática é: o gpt-image-2 cobre as proporções de que os formatos de redes sociais e marketplaces precisam (4:5, 2:3, 5:4 são exclusivos do gpt-image-2), enquanto o wan2.7-image adiciona faixas ultrawide 8:1/1:8 que nenhuma outra lista de proporções cobre — ótimo para banners promocionais estreitos — e é a escolha comum para fotos de estúdio em 4K.

Portanto, para controlar a dimensão com precisão, a receita tem duas etapas:

  1. Gerar com uma proporção correspondente e escolher o menor nível de resolução cujo lado maior alcance ou ultrapasse o tamanho alvo (reduza depois, nunca amplie).
  2. Redimensionar o arquivo retornado localmente para o valor exato em pixels desejado — uma linha de código com Pillow.

Tabela de referência rápida de especificações de marketplaces

A seguir estão os requisitos públicos comuns, mapeados para os parâmetros da API:

Canal Alvo típico aspect_ratio resolution Observações sobre o modelo
Imagem principal da Amazon Lado maior ≥1000 pixels (acima de 1600 pixels habilita o zoom), quadrada, fundo branco puro 1:1 2K Ambos servem
Página de produto do Shopify Recomendado 2048×2048 1:1 2K Ambos servem
Feed do Instagram (vertical) 1080×1350 4:5 2K Somente gpt-image-2
Stories / Reels / TikTok 1080×1920 9:16 2K Ambos servem
Pin do Pinterest 1000×1500 2:3 2K Somente gpt-image-2
Anúncio no Etsy Recomendado 2700×2025 4:3 4K Ambos servem (requer nível 4K)
Banner principal do site Por exemplo, 2560 pixels de largura 21:9 4K Ambos servem
Faixa promocional estreita Ultrawide 8:1 2K/4K Somente wan2.7-image

(As especificações das plataformas mudam; trate esses alvos em pixels como recomendações públicas comuns e confirme com a documentação atual de cada plataforma.)

Exemplo mínimo funcional (curl)

Tudo passa pelo endpoint unificado de tarefas assíncronas: crie com POST /v1/tasks e consulte com GET /v1/tasks/<id>. Criando uma imagem quadrada no estilo Amazon, usando o nível 2K:

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": "Studio product photo of a stainless steel water bottle on a pure white background, centered, soft shadow, e-commerce catalog style",
      "aspect_ratio": "1:1",
      "resolution": "2K"
    }
  }'

O id da tarefa na resposta fica em data.taskId. Consulte-o:

curl -s https://api.hiapi.ai/v1/tasks/TASK_ID \
  -H "Authorization: Bearer sk-YOUR_KEY"

Consulte até que data.status passe para "success" (ou "fail", com detalhes em data.error). A URL da imagem fica em data.output[0].url. Essa URL expira (o objeto de saída traz expireAt), então baixe-a imediatamente e hospede-a novamente no seu próprio armazenamento — nunca faça hotlink direto em listagens de produtos.

Script de produção: um produto, todos os canais, pixels exatos

Este script em lote cria todas as tarefas antecipadamente (elas rodam em paralelo na plataforma), consulta cada uma até a conclusão e depois redimensiona para as dimensões exatas com o Pillow. O ImageOps.fit resolve em uma única chamada tanto a redução quanto qualquer corte fino.

import os
import time
from io import BytesIO

import requests
from PIL import Image, ImageOps

API = "https://api.hiapi.ai/v1"
HDRS = {
    "Authorization": f"Bearer {os.environ['HIAPI_KEY']}",
    "Content-Type": "application/json",
}

# canal -> parâmetros de geração + alvo exato em pixels
SPECS = {
    "amazon-main":    {"model": "gpt-image-2/text-to-image", "aspect_ratio": "1:1",  "resolution": "2K", "px": (1600, 1600)},
    "shopify":        {"model": "gpt-image-2/text-to-image", "aspect_ratio": "1:1",  "resolution": "2K", "px": (2048, 2048)},
    "instagram-feed": {"model": "gpt-image-2/text-to-image", "aspect_ratio": "4:5",  "resolution": "2K", "px": (1080, 1350)},
    "story-reel":     {"model": "gpt-image-2/text-to-image", "aspect_ratio": "9:16", "resolution": "2K", "px": (1080, 1920)},
    "pinterest-pin":  {"model": "gpt-image-2/text-to-image", "aspect_ratio": "2:3",  "resolution": "2K", "px": (1000, 1500)},
    "etsy-listing":   {"model": "wan2.7-image/text-to-image", "aspect_ratio": "4:3",  "resolution": "4K", "px": (2700, 2025)},
    "hero-banner":    {"model": "wan2.7-image/text-to-image", "aspect_ratio": "21:9", "resolution": "4K", "px": (2560, 1097)},
}

PROMPT = (
    "Studio product photo of a stainless steel water bottle on a pure white "
    "background, centered, soft shadow, high detail, e-commerce catalog style"
)


def create_task(model: str, prompt: str, aspect_ratio: str, resolution: str) -> str:
    body = {
        "model": model,
        "input": {"prompt": prompt, "aspect_ratio": aspect_ratio, "resolution": resolution},
    }
    data = requests.post(f"{API}/tasks", json=body, headers=HDRS, timeout=60).json()
    task_id = (data.get("data") or {}).get("taskId")
    if not task_id:
        raise RuntimeError(f"create failed: {data}")
    return task_id


def wait_task(task_id: str, timeout_s: int = 600) -> str:
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        data = requests.get(f"{API}/tasks/{task_id}", headers=HDRS, timeout=30).json()
        task = data.get("data") or {}
        if task.get("status") == "success":
            return task["output"][0]["url"]
        if task.get("status") == "fail":
            err = task.get("error") or {}
            raise RuntimeError(f"task {task_id} failed: {err.get('code')} {err.get('message')}")
        time.sleep(5)
    raise TimeoutError(f"task {task_id} did not finish in {timeout_s}s")


def save_exact(url: str, px: tuple, path: str) -> None:
    # a URL de saída expira — baixe imediatamente e ajuste para os pixels exatos.
    raw = requests.get(url, timeout=120).content
    img = Image.open(BytesIO(raw))
    ImageOps.fit(img, px, Image.LANCZOS).save(path)


if __name__ == "__main__":
    # crie todas as tarefas primeiro: elas rodam em paralelo na plataforma
    tasks = {
        name: create_task(s["model"], PROMPT, s["aspect_ratio"], s["resolution"])
        for name, s in SPECS.items()
    }
    for name, task_id in tasks.items():
        url = wait_task(task_id)
        save_exact(url, SPECS[name]["px"], f"{name}.png")
        print(f"{name}: {SPECS[name]['px']} -> {name}.png")

Mesmo que você reescreva o restante, vale copiar dois detalhes:

  • Escolha um nível de resolução cujo lado maior seja ≥ ao alvo. O alvo de 2700 pixels do Etsy ultrapassa os cerca de 2048 pixels do nível 2K, então gere com 4K e reduza. A redução com LANCZOS é visualmente sem perdas para fins de catálogo de produtos; a ampliação não é.
  • Persista o taskId imediatamente após criar a tarefa. Se o seu worker cair, ao retomar consulte o id armazenado em vez de recriar a tarefa — recriar gera (e cobra) uma segunda imagem.

Alternativa: recompor uma imagem principal já aprovada

Muitas vezes você não quer sete imagens geradas de forma independente — quer a mesma imagem de produto já aprovada, reenquadrada para cada canal. É para isso que serve o gpt-image-2/image-to-image: ele recebe input_urls (um array de URLs de imagens acessíveis publicamente) e prompt, e aceita os mesmos 16 valores de aspect_ratio:

{
  "model": "gpt-image-2/image-to-image",
  "input": {
    "prompt": "Extend the background naturally to fill the new frame; keep the product unchanged and centered",
    "input_urls": ["https://your-cdn.com/hero-shot.png"],
    "aspect_ratio": "9:16"
  }
}

O mesmo ciclo de vida de tarefa, com a mesma etapa final de pixels exatos. Para um passo a passo completo, veja How to Use gpt-image-2 Image-to-Image via the hiapi API.

Considerações de produção

Use callback em vez de polling. No lado do servidor, passe um callback de nível superior ao criar a tarefa e ignore completamente o loop de polling:

{
  "model": "gpt-image-2/text-to-image",
  "input": {"prompt": "...", "aspect_ratio": "1:1", "resolution": "2K"},
  "callback": {"url": "https://yourapp.com/hooks/hiapi", "when": "final"}
}

Você recebe um POST quando o estado final for atingido. Trate o callback como um sinal, não como fonte da verdade: antes de agir, busque novamente com GET /v1/tasks/<id> e deduplique por taskId. Se o callback nunca chegar, consulte Why your hiapi task callback isn't firing.

Tratamento de erros. Falha de autenticação retorna 401 permission_denied — verifique primeiro o cabeçalho Authorization: Bearer sk-.... Falha de validação retorna 400 com error_code: "INVALID_REQUEST", e a mensagem é especialmente útil: ela lista os valores exatos permitidos (foi assim que a tabela de proporções acima foi validada). O schema de entrada varia por modelo — wan2.7-image aceita seed, gpt-image-2 não; alguns modelos rápidos rejeitam completamente resolution — então consulte a página de cada modelo antes de codificar os campos.

Controle de custos. O preço varia conforme o modelo e o nível de resolução. Gere com 1K ao iterar no prompt e mude para 2K/4K só na versão final — os preços atuais por imagem estão na página de preços.

Leitura relacionada

Perguntas frequentes

Posso passar dimensões exatas em pixels, como 1080×1350, na requisição? Não. size, width e height são rejeitados com 400 (additional properties ... not allowed). Gere com um aspect_ratio correspondente e um nível de resolution igual ou superior ao alvo, depois reduza localmente para os pixels exatos — a linha de Pillow acima.

Que configurações devo usar para a imagem principal da Amazon? aspect_ratio: "1:1", resolution: "2K" e depois redimensione para o seu alvo (1600×1600 é um padrão confiável — acima do limite de 1000 pixels que habilita o zoom). A imagem principal da Amazon também exige fundo branco puro, então inclua isso no prompt e revise a saída antes de publicar.

A proporção que preciso não está na lista (por exemplo, o formato 1.91:1 de anúncios de link). O que fazer? Gere com a proporção mais ampla ou igual mais próxima que cubra totalmente o alvo — para 1.91:1, use 2:1 ou 16:9 — e depois faça um corte centralizado. O ImageOps.fit do script faz exatamente isso: em uma única chamada, corta o excedente e ajusta o tamanho.

Como obter imagens de produto realmente em 4K? Defina resolution: "4K" nos dois modelos. O wan2.7-image é a escolha comum para imagens em estilo de estúdio 4K; para padrões de prompt, consulte o guia de e-commerce do Wan 2.7.

As URLs das imagens geradas expiram? Sim — cada saída traz expireAt. Assim que a tarefa for concluída com sucesso, baixe o arquivo imediatamente e hospede-o novamente no seu próprio armazenamento. Nunca cole a URL de saída da tarefa em uma listagem de produto.

Posso gerar várias variações em uma única requisição? Não — esses modelos não têm parâmetro n. Crie uma tarefa por imagem; as tarefas rodam em paralelo, então processar em lote em um loop (como no script acima) é praticamente igual em velocidade. No wan2.7-image, você pode variar o seed para obter variações controladas do mesmo prompt.

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