Tutorial
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:
- 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).
- 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
4Ke reduza. A redução com LANCZOS é visualmente sem perdas para fins de catálogo de produtos; a ampliação não é. - Persista o
taskIdimediatamente 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
- Página do modelo gpt-image-2 text-to-image · Página do modelo wan2.7-image text-to-image
- How to use gpt-image-2/text-to-image via the hiapi API — passo a passo completo dos parâmetros
- Wan 2.7 Text-to-Image for E-Commerce Product Photos: 4K Studio Shots
- Best AI Image Generation APIs in 2026 — se você ainda está escolhendo, veja a comparação de modelos
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 →-
Tutorial
Como chamar hailuo-2.3-fast/image-to-video pela API HiAPI: curl e Python na prática
A primeira requisição executável do nível rápido e econômico de geração de vídeo a partir de imagem — do ID do modelo ao download do MP4
-
Tutorial
Como chamar hailuo-2.3/text-to-video pela API HiAPI: curl, Python e exemplos de requisição executáveis
-
Tutorial
Usar Kandinsky 6.0 Pro text-to-video na HiAPI: tutorial de curl e Python
Demonstração prática com foco na requisição: montar a chamada de prompt para clipe de vídeo, enviar a requisição, consultar o status de conclusão e baixar o resultado