Referência da API
Imagem
Gere uma imagem a partir de um prompt, ou edite imagens existentes com até quatro referências.
/v1/images/generationsDuas rotas sobre o mesmo modelo: uma parte só de um prompt, a outra parte de imagens que você envia. As duas devolvem a imagem em base64 no corpo da resposta.
/v1/images/generations/v1/images/editsEstas rotas exigem uma chave de uma stack do plano de imagem. Uma chave
de plano de texto recebe 403 aqui, e uma chave de imagem recebe 403 nas
rotas de chat. A geração de imagem roda em infraestrutura dedicada, não na
máquina que responde chat.
Geração
application/json. Um prompt entra, um PNG sai.
curl -X POST "https://api.trystac.com/v1/images/generations" \
-H "Authorization: Bearer $STAC_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "a white dress shirt folded on a wooden table",
"size": "1024x1024",
"seed": 42
}'Esta rota não aceita imagem de entrada. Enviar uma devolve 400
wrong_route_for_reference_image — use /v1/images/edits.
Edição
multipart/form-data. De uma a quatro imagens de referência, mais um prompt
descrevendo a mudança.
curl -X POST "https://api.trystac.com/v1/images/edits" \
-H "Authorization: Bearer $STAC_API_KEY" \
-F "prompt=make it black and white" \
-F "size=1024x1024" \
-F "image[]=@photo.png"O campo de arquivo aceita tanto image quanto image[] — o segundo é o que
os próprios exemplos da OpenAI usam para múltiplos arquivos. Até 4 imagens,
de 5 MiB cada, em PNG, JPEG ou WEBP. O formato é lido do conteúdo do
arquivo, não da extensão nem do Content-Type da parte. O corpo multipart
inteiro tem teto de 21 MiB.
As imagens de referência são convertidas para RGB na chegada, o que descarta o canal alfa, perfis de cor e metadados EXIF — inclusive qualquer dado de localização que o arquivo original carregasse.
O campo model se comporta de forma diferente nesta rota. Em todo o
resto da API ele é ignorado e substituído pelo modelo da sua stack. Aqui
não é — reescrevê-lo exigiria re-codificar o corpo multipart inteiro. Omita
o campo, ou envie exatamente flux2-klein-4b. Qualquer outro valor devolve
404.
mask não é suportado e devolve 400. O pod carrega um único pipeline, e
aplicar a edição na imagem inteira fingindo respeitar a máscara seria pior que
recusar.
Parâmetros
Os mesmos campos nas duas rotas — como JSON em /generations, como campos de
formulário em /edits.
promptstringObrigatórioO que gerar, ou o que mudar nas imagens que você enviou. Pode ser omitido se a sua chave tiver um prompt configurado — ver Prompt na chave. Leia Tamanho do prompt antes de escrever um prompt longo.
sizestringOpcionalPadrão: 1024x1024Dimensões de saída — quadrada, horizontal ou vertical. É uma lista fechada; qualquer outro valor devolve 400.
1024x10241536x10241024x1536stepsintegerOpcionalPadrão: 4Passos de difusão, de 1 a 8. O checkpoint é destilado, então está afinado para produzir uma imagem pronta em pouquíssimos passos — é por isso que o teto é 8 e não 50.
guidance_scalenumberOpcionalPadrão: 1.0Quão estritamente seguir o prompt, de 0 a 20.
seedintegerOpcionalDe 0 a 2^64−1. Se você omitir, o servidor sorteia uma e devolve em meta.seed — é esse valor que reproduz a mesma imagem depois.
nintegerOpcionalPadrão: 1Imagens por requisição. Hoje 1 é o único valor aceito.
response_formatstringOpcionalPadrão: b64_jsonApenas b64_json. url é recusado — a imagem vem no corpo da resposta.
Resposta
Idêntica nas duas rotas.
{
"created": 1767225600,
"data": [{ "b64_json": "iVBORw0KGgo..." }],
"meta": {
"prompt": "a white dress shirt folded on a wooden table",
"width": 1024,
"height": 1024,
"steps": 4,
"guidance_scale": 1.0,
"seed": 8151234567890123456,
"n": 1,
"model": "flux2-klein-4b",
"timings": {
"queue_wait_s": 0.0100,
"decode_s": null,
"gpu_s": 4.1000,
"encode_s": 0.1800,
"worker_s": 4.2800
}
}
}O meta traz os parâmetros efetivos — o que o servidor de fato usou,
depois dos padrões e depois de sortear uma seed, se você não mandou uma.
data[].b64_jsonstringOpcionalO PNG, codificado em base64.
meta.seedintegerOpcionalA seed que produziu este resultado. Ela é do lote, não de cada imagem: reproduzir a imagem i exige a mesma seed e o mesmo n.
meta.timingsobjectOpcionalPara onde foi o tempo, em segundos, com quatro casas decimais. queue_wait_s é a espera por uma vaga livre; decode_s é a leitura das suas imagens de referência (null em /generations, que não tem nenhuma); gpu_s é a difusão em si; encode_s é a produção do PNG. worker_s é a soma dos três últimos e não inclui a espera na fila.
Tamanho do prompt
O prompt é truncado em 512 tokens, silenciosamente. Não há erro nem aviso — o que passar disso simplesmente nunca chega ao modelo.
Esta é a causa mais comum de "a imagem ignorou metade do que eu pedi". Um prompt longo e detalhado não só é desperdiçado depois do corte, como também dilui a parte que cabe. Comece pelo assunto e pelos detalhes que mais importam.
Prompt na chave
O prompt pode viver na sua chave de API, como o system prompt das rotas de
texto — e vale a mesma precedência.
| No corpo da requisição | Na chave | O que o modelo recebe |
|---|---|---|
prompt com texto | qualquer coisa | o da requisição |
| ausente ou em branco | configurado | o da chave |
| ausente ou em branco | nada | 400 missing_prompt |
É o que permite mandar só a URL, a chave e a imagem:
curl -X POST "https://api.trystac.com/v1/images/edits" \
-H "Authorization: Bearer $STAC_API_KEY" \
-F "image[]=@photo.png"Substitui, não soma. Não há concatenação entre o prompt da chave e o da
requisição: mandar prompt descarta o configurado por inteiro. E o texto da
chave gasta o mesmo orçamento de 512 tokens — um prompt longo na chave não
deixa espaço para mais nada.
Vazão
Geração de imagem não tem cota diária — difusão não produz tokens, então o orçamento de tokens que vale para as rotas de chat não se aplica aqui. O que limita é a GPU, que renderiza uma imagem por vez.
| Limite | O que significa | |
|---|---|---|
| Submissões | 10 por minuto | Compartilhado entre generations e edits |
| Em voo | 3 de uma vez | 1 renderizando e até 2 aguardando |
| Espera na fila | 60 segundos | Depois disso a requisição devolve 504 |
Os dois limites são da stack, não da chave. Emitir mais chaves não os aumenta, porque é a mesma GPU que faz o trabalho de qualquer jeito.
Disparar 10 requisições de uma vez não as faz terminar antes — 3 são aceitas
e 7 voltam 429. O padrão que funciona é manter 3 em voo e emendar a próxima
conforme cada uma termina.
Observado de ponta a ponta: cerca de 6–9s para texto → imagem e 7–21s para uma edição, variando com a quantidade, as dimensões e o peso das imagens de referência. "10 por minuto" é teto de submissão, não promessa de dez imagens concluídas por minuto.
Armazenamento e retenção
Toda imagem gerada é armazenada, ligada à conta, à stack e à chave que a criou.
Isso acontece no servidor e não muda nada no seu código — a resposta
continua sendo b64_json.
Duas consequências que vale conhecer:
- Um
200significa que a imagem foi armazenada. A gravação acontece antes de a resposta sair e adiciona algumas centenas de milissegundos a uma chamada que já leva segundos. - Um
502pode acontecer com a imagem já gerada. Se o armazenamento falhar, devolvemos o erro em vez de entregar a imagem afirmando que ela foi guardada. Repetir é seguro — mas note que a requisição gera de novo, com uma seed nova se você não fixou nenhuma.
Os arquivos são mantidos por 30 dias. Se você precisa de uma imagem por mais
tempo, guarde o b64_json do seu lado: este armazenamento existe para
rastreabilidade e para a visualização na plataforma, não como hospedagem
permanente.
Erros
Dois formatos de erro chegam até você nestas rotas. As recusas do próprio
gateway usam o formato { "detail": "..." } comum a toda a API; o que o
servidor de imagem recusa volta no formato da OpenAI, com um code estável em
que você pode ramificar:
{
"error": {
"message": "size must be one of: 1024x1024, 1536x1024, 1024x1536",
"type": "invalid_request_error",
"code": "invalid_size"
}
}| Status | code | Significado |
|---|---|---|
400 | invalid_size, invalid_steps, invalid_n, invalid_guidance_scale, invalid_seed | Campo fora da faixa aceita, ou com o tipo errado |
400 | missing_prompt | prompt ausente ou vazio, e nenhum prompt configurado na chave |
400 | mask_not_supported | mask não é suportado nesta versão |
400 | wrong_route_for_reference_image | Mandou imagem para /generations — use /edits |
400 | missing_image | /edits chamado sem arquivo |
400 | too_many_reference_images | Mais de 4 referências |
400 | unsupported_image_format | Uma referência não é PNG, JPEG nem WEBP |
403 | — | A chave não é de uma stack do plano image |
404 | model_not_found | model diferente do modelo servido (só em /edits) |
413 | image_too_large | Referência acima de 5 MiB, ou corpo acima do teto da rota |
429 | queue_full | Já há 3 em voo — respeite o Retry-After |
429 | — | Acima de 10 submissões por minuto — respeite o Retry-After |
502 | — | A imagem foi gerada, mas não foi possível armazená-la |
503 | model_not_ready | Infraestrutura ainda subindo, ou degradada |
504 | queue_timeout | Esperou mais de 60s por uma vaga livre |
Repita 429, 503 e 504 depois do tempo indicado no Retry-After. Um 502
também vale uma tentativa, lembrando que ele renderiza de novo do zero.

