API de geração de imagens
Gere imagens GPT Image pela API compatível com OpenAI da BetterToken. Configure API Key, Base URL e parâmetros; consulte exemplos, cobrança e erros.
POST /v1/images/generations
O endpoint de texto para imagem usa um corpo application/json. Envie um prompt, mantenha a solicitação HTTP aberta e processe cada imagem de data[].b64_json na mesma resposta.
Escolha o fluxo correto
- Gerar uma imagem a partir de texto e salvar o resultado: permaneça nesta página. Comece pelo exemplo de
curle decodifique cada item dedata[]em Salvar a imagem. - Editar uma imagem existente: envie uma ou mais imagens de referência pela API de edição de imagens. A edição comum com referências não exige máscara; adicione-a apenas para editar uma área quando o modelo e o tamanho escolhidos oferecerem suporte.
- Escolher um modelo, revisar parâmetros e estimar o orçamento: consulte os Model IDs disponíveis e preços atuais na model plaza. O fluxo completo está no guia GPT Image 2.
Início rápido com curl
Use https://bettertoken.ai/v1 como Base URL e envie uma solicitação para https://bettertoken.ai/v1/images/generations:
curl --max-time 300 -X POST "https://bettertoken.ai/v1/images/generations" \ -o response.json \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-image-2", "prompt": "A product photo of a green ceramic mug on a studio table", "size": "1024x1024", "n": 1, "response_format": "b64_json", "output_format": "png" }'Valores recomendados
Estes são valores iniciais recomendados, não requisitos fixos. Recomenda-se n=1; o endpoint aceita um inteiro de 1 a 10, mas pode retornar menos imagens.
{ "model": "gpt-image-2", "n": 1, "response_format": "b64_json", "output_format": "png"}| Parâmetro | O que enviar | Finalidade |
|---|---|---|
model | gpt-image-2, gpt-image-2.5-flare ou gpt-image-2.5-sunburst | Escolha um Model ID disponível na model plaza. Um ID válido não garante que modelo, tamanho ou operação estejam disponíveis para a solicitação. |
prompt | Uma descrição de texto | Descrição obrigatória da imagem. Inclua o assunto, estilo, composição e restrições importantes. |
size | Omitir, usar auto ou informar dimensões como 1024x1024 | Solicita tamanho e proporção; as dimensões entregues podem variar. |
n | Inteiro de 1 a 10 | Máximo solicitado. Recomenda-se 1; a resposta pode ter menos imagens. |
quality | auto, low, medium, high para gpt-image-2; os dois modelos 2.5 também aceitam xhigh e max | Preferência opcional. Omita o campo ou use JSON null para o padrão. A aceitação do parâmetro não garante que um nível maior melhore a qualidade da imagem. |
response_format | b64_json | Retorna cada imagem em base64 em data[].b64_json. |
output_format | Por exemplo, png | Solicita um formato, mas não garante a codificação do arquivo retornado. Identifique o formato pelos bytes antes de salvar. |
A resposta pode conter menos imagens do que n. Processe todos os itens de data[]; recomendar n=1 não é um limite do servidor.
Tamanhos recomendados
size | Proporção | Caso de uso |
|---|---|---|
auto | Automática | Seleção automática de tamanho |
1024x1024 | 1:1 | Imagens quadradas, avatares, capas e recursos |
1536x1024 | 3:2 | Pôsteres, banners e cenas horizontais |
1024x1536 | 2:3 | Capas e pôsteres verticais para dispositivos móveis |
1536x1152 | 4:3 | Imagens horizontais padrão, imagens de produto e gráficos de conteúdo |
1152x1536 | 3:4 | Imagens verticais padrão, capas móveis e pôsteres verticais |
2048x2048 | 1:1 | Imagens quadradas em alta resolução |
2048x1152 | 16:9 | Imagens horizontais em alta resolução |
3840x2160 | 16:9 | Imagens horizontais 4K |
2160x3840 | 9:16 | Imagens verticais 4K |
Os valores da tabela são exemplos, não uma lista fechada. Você pode omitir size ou usar auto; null em JSON ativa o tamanho automático. Dimensões explícitas devem ser positivas, múltiplas de 16 e cada uma no máximo 3840; a proporção não pode exceder 3:1 e o total deve ficar entre 655360 e 8294400 pixels. 2080x2080 é válido. Confira as dimensões entregues e não corte a imagem à força.
Salve a imagem
Uma resposta bem-sucedida segue o formato de resposta de imagem compatível com OpenAI. Os valores abaixo ilustram o formato do recibo e não são preços fixos:
{ "created": 1710000000, "data": [ { "b64_json": "iVBORw0KGgoAAAANSUhEUgAA...(truncated)", "revised_prompt": "Optional revised prompt" } ], "bettertoken_image_billing": { "currency": "CNY", "settled_amount": "0.15", "outputs": [ { "index": 0, "width": 1254, "height": 1254, "billing_resolution": "2K", "currency": "CNY", "amount": "0.15" } ] }}Leia todos os data[].b64_json e permita campos adicionais como revised_prompt. A cobrança aparece no objeto raiz bettertoken_image_billing: settled_amount e cada amount são strings decimais, e outputs[].index começa em 0. As dimensões e billing_resolution desse objeto refletem a cobrança final.
output_format solicita um formato, mas não garante codificação nem conversão. Inspecione os bytes e use a extensão correspondente. Os exemplos com bibliotecas padrão reconhecem PNG, JPEG e WebP sem dependências extras.
import base64import jsonfrom pathlib import Path
result = json.loads(Path("response.json").read_text(encoding="utf-8"))for index, item in enumerate(result["data"], start=1): encoded = item["b64_json"] if "," in encoded and "base64" in encoded.split(",", 1)[0]: encoded = encoded.split(",", 1)[1] image_bytes = base64.b64decode(encoded) if image_bytes.startswith(b"\x89PNG\r\n\x1a\n"): extension = "png" elif image_bytes.startswith(b"\xff\xd8\xff"): extension = "jpg" elif image_bytes.startswith(b"RIFF") and image_bytes[8:12] == b"WEBP": extension = "webp" else: raise ValueError("Unsupported image signature") Path(f"output-{index}.{extension}").write_bytes(image_bytes)Exemplo JavaScript (Node.js)
import { writeFile } from "node:fs/promises";
const response = await fetch("https://bettertoken.ai/v1/images/generations", { method: "POST", headers: { Authorization: "Bearer YOUR_API_KEY", "Content-Type": "application/json", }, body: JSON.stringify({ model: "gpt-image-2", prompt: "A green ceramic mug on a studio table", size: "1024x1024", n: 1, response_format: "b64_json", output_format: "png", }),});
if (!response.ok) { throw new Error(await response.text());}
const result = await response.json();const { data } = result;for (const [index, item] of data.entries()) { const b64Json = item.b64_json.replace(/^data:.*;base64,/, ""); const imageBytes = Buffer.from(b64Json, "base64"); let extension; if (imageBytes.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]))) { extension = "png"; } else if (imageBytes[0] === 0xff && imageBytes[1] === 0xd8 && imageBytes[2] === 0xff) { extension = "jpg"; } else if (imageBytes.toString("ascii", 0, 4) === "RIFF" && imageBytes.toString("ascii", 8, 12) === "WEBP") { extension = "webp"; } else { throw new Error("Unsupported image signature"); } await writeFile(`output-${index + 1}.${extension}`, imageBytes);}Se a aplicação exigir codificação fixa em PNG, JPEG ou WebP, identifique primeiro o formato real e converta a imagem conforme necessário. Alterar apenas a extensão do arquivo não converte a imagem.
Consulte o custo real
bettertoken_image_billing é retornado com o resultado; não é necessária outra consulta.
| Campo | Significado |
|---|---|
currency | Moeda liquidada; não presuma que seja sempre USD ou CNY. |
settled_amount | Total da solicitação como string decimal. |
requested_resolution | Nível de resolução identificado na solicitação. |
outputs[].index | Índice iniciado em zero, correspondente a data[]. |
outputs[].width, height | Largura e altura reais em pixels. |
outputs[].billing_resolution | Nível final de cobrança da imagem. |
outputs[].currency, amount | Moeda e valor liquidados por imagem. |
O tamanho solicitado pode diferir do nível cobrado: uma solicitação 1024x1024 já retornou 1254x1254 com cobrança 2K. Use o valor do recibo e consulte os preços atuais no model plaza. Mantenha valores como strings na exibição e use aritmética decimal nos cálculos. Recibo ausente não significa custo zero.
from decimal import Decimal
billing = result.get("bettertoken_image_billing")if billing is None: print("Billing receipt unavailable; check your usage records.")else: total = Decimal(billing["settled_amount"]) print(f"Total: {billing['currency']} {total}") for output in billing.get("outputs", []): print( f"Image {output['index'] + 1}: " f"{output['width']}x{output['height']}, " f"{output['billing_resolution']}, " f"{output['currency']} {output['amount']}" )Fluxo de resposta
Este endpoint é síncrono. Depois de enviar POST /images/generations, mantenha a solicitação HTTP aberta até receber resposta. Cada imagem bem-sucedida aparece em data[].b64_json com seus dados de entrega e cobrança.
O endpoint não retorna task_id, e não há endpoint separado para consulta de status ou download do resultado.
Timeouts, novas tentativas e cobrança
Configure timeouts de vários minutos. Timeout, desconexão ou 5xx ambíguo não confirma se a geração foi executada ou cobrada. Não repita automaticamente um POST de geração ou edição. Primeiro confira os registros de consumo ou solicitações e guarde o request ID retornado. Um request ID criado pelo cliente não torna o servidor idempotente; um reenvio deliberado pode criar nova solicitação e cobrança.
Corrija primeiro entradas rejeitadas, autenticação ou quota. Só tente novamente 429 com backoff após confirmar que a solicitação foi rejeitada. Não considere todo erro 5xx ou de transporte seguro para repetir.
Antes do processamento, a BetterToken pode pré-autorizar um limite igual ao maior preço unitário aplicável multiplicado por n. O saldo pode ser suficiente para a imagem 1K entregue, mas insuficiente para essa retenção; nesse caso, a solicitação é rejeitada com 403 e error.code=insufficient_user_quota. A cobrança final considera as imagens entregues. O objeto raiz bettertoken_image_billing informa settled_amount, moeda e o amount, billing_resolution e as dimensões de cada resultado. Os valores são strings decimais e podem ser entregues menos imagens que n.
Tratamento de erros
Os erros geralmente retornam JSON. Ao mostrar um erro, leia primeiro error.message, depois message e, por fim, o texto de status HTTP.
| Status HTTP | Significado | O que fazer |
|---|---|---|
400 | JSON malformado, parâmetro ausente ou tamanho não compatível | Verifique o corpo da solicitação. Não tente novamente automaticamente. |
401 | A API Key está ausente ou é inválida | Verifique o cabeçalho Authorization: Bearer YOUR_API_KEY. |
402 ou 403 | Quota ou saldo insuficientes, inclusive retenção de saldo | Confira error.code e a quota/saldo. 403 com error.code=insufficient_user_quota indica que o saldo pode estar abaixo do limite de pré-autorização. |
429 | Limite de taxa, concorrência ou upstream ocupado | Tente novamente com backoff somente após confirmar a rejeição. |
5xx | Falha de gateway ou upstream | A execução e a cobrança podem ser desconhecidas. Confira os registros antes de reenviar deliberadamente. |
Checklist de integração
- A Base URL é
https://bettertoken.ai/v1. - O cabeçalho inclui
Authorization: Bearer sk-.... - A solicitação usa
application/json. - Escolha um Model ID disponível para esta solicitação:
gpt-image-2,gpt-image-2.5-flareougpt-image-2.5-sunburst. - Use
response_format=b64_json.output_formaté um valor solicitado; identifique o formato real pelos bytes antes de salvar. naceita inteiros de1a10. Comece com1; menos imagens podem ser retornadas.- Omita
size, useautoou informe dimensões válidas. A tabela acima não é uma lista fechada. - O cliente HTTP permite aguardar vários minutos pela geração.
- Os logs e as capturas de erros não revelam a API Key nem todo o conteúdo base64 da imagem.
Documentação relacionada
/v1/images/generationsAutorizações
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Corpo application/json
GPT Image Model ID. One BetterToken API Key works with all available models.
"gpt-image-2"A detailed description of the image to generate.
"A futuristic AI product poster on a light background, with glass textures, a clean composition, and a premium technology aesthetic."Allowed range: 1–10; start with 1. Fewer images may be delivered than requested. Iterate data[] and use actual-delivery billing.
1Omit or use auto for automatic sizing. For WxH, both dimensions must be positive multiples of 16, each at most 3840, aspect ratio at most 3:1, total pixels 655360–8294400. Examples are not an exhaustive enum; 2080x2080 also meets the geometry rules. Inspect actual decoded dimensions. Valid parameters do not guarantee an available service.
"1024x1024"["auto","1024x1024","2048x2048","2080x2080","3840x2160"]Requested output format; png is recommended, but the response is not guaranteed to have been transcoded to PNG. Detect PNG, JPEG, or WebP from actual bytes before choosing an extension. Convert locally if a specific format is required.
"png"gpt-image-2 accepts auto, low, medium, high. The two 2.5 models also accept xhigh and max. Omit for the model default; JSON null is treated as omitted, while multipart requires a nonempty string. Valid values do not guarantee an available service for every model, size, and editing combination. Acceptance does not guarantee that a higher setting improves image quality.
"auto"Resposta
200BetterToken billing extension. Settlement follows the actual delivered pixels and billing tier, which can differ from the requested tier. Amounts are decimal strings; use the returned values.
OpenAI-compatible image response. Iterate data[] and read each image from b64_json. Fewer images may be delivered than requested.
1710000000Show child attributes
BetterToken billing extension. Settlement follows the actual delivered pixels and billing tier, which can differ from the requested tier. Amounts are decimal strings; use the returned values.
Show child attributes
Settlement currency; do not assume a fixed currency.
Final request amount as a decimal string; use decimal arithmetic for calculations.
Delivered image indices, actual dimensions, billing tiers, and per-image amounts. index is zero-based and corresponds to data[].
Settled amount for this image as a decimal string.
Resolution tier inferred from the request; it may differ from the actual billing tier.
{
"created": 1710000000,
"data": [
{
"b64_json": "iVBORw0KGgoAAAANSUhEUgAA...(truncated)",
"revised_prompt": "<string>"
}
],
"bettertoken_image_billing": {
"currency": "<string>",
"settled_amount": "<string>",
"outputs": [
{
"index": 0,
"width": 1,
"height": 1,
"billing_resolution": "1K",
"currency": "<string>",
"amount": "<string>"
}
],
"partial": false,
"requested_resolution": "<string>"
}
}400Invalid request format, missing parameters, malformed JSON or multipart data, or invalid dimensions.
Show child attributes
"invalid request""invalid_request_error""invalid_request""insufficient quota"{
"error": {
"message": "invalid request",
"type": "invalid_request_error",
"code": "invalid_request"
},
"message": "insufficient quota"
}401The BetterToken API Key is missing or invalid.
Show child attributes
"invalid request""invalid_request_error""invalid_request""insufficient quota"{
"error": {
"message": "invalid request",
"type": "invalid_request_error",
"code": "invalid_request"
},
"message": "insufficient quota"
}402The account has insufficient credit or balance.
Show child attributes
"invalid request""invalid_request_error""invalid_request""insufficient quota"{
"error": {
"message": "invalid request",
"type": "invalid_request_error",
"code": "invalid_request"
},
"message": "insufficient quota"
}403Insufficient balance or token quota: error.code is insufficient_user_quota. Funds must also cover the reservation of the highest-tier unit price times the image-count upper bound, before actual-delivery settlement. Inspect error.code rather than treating every 403 as an authorization error.
{
"error": {
"code": "insufficient_user_quota",
"message": "Insufficient balance or token quota."
}
}429A rate or concurrency limit was reached, or the upstream service is busy.
Show child attributes
"invalid request""invalid_request_error""invalid_request""insufficient quota"{
"error": {
"message": "invalid request",
"type": "invalid_request_error",
"code": "invalid_request"
},
"message": "insufficient quota"
}500The gateway or upstream service returned an error.
Show child attributes
"invalid request""invalid_request_error""invalid_request""insufficient quota"{
"error": {
"message": "invalid request",
"type": "invalid_request_error",
"code": "invalid_request"
},
"message": "insufficient quota"
}
