Ir al contenido
Regístrate gratis
GPT Image

API de generación de imágenes

Genera imágenes GPT Image con la API compatible con OpenAI de BetterToken. Configura API Key, Base URL y parámetros; revisa ejemplos, costes y errores.

POST /v1/images/generations

El endpoint de texto a imagen usa un cuerpo application/json. Envía un prompt, mantén abierta la solicitud HTTP y procesa cada imagen de data[].b64_json en la misma respuesta.

Elige el flujo adecuado

  • Generar una imagen desde texto y guardar el resultado: continúa en esta página. Empieza con el ejemplo de curl y decodifica cada elemento de data[] en Guardar la imagen.
  • Editar una imagen existente: sube una o varias imágenes de referencia mediante la API de edición de imágenes. La edición normal con referencias no requiere máscara; añádela solo para editar una zona cuando el modelo y el tamaño elegidos lo admitan.
  • Elegir un modelo, revisar parámetros y estimar el presupuesto: consulta los Model ID disponibles y los precios actuales en la model plaza. La guía de GPT Image 2 describe el flujo completo.

Inicio rápido con curl

Usa https://bettertoken.ai/v1 como Base URL y envía una solicitud a https://bettertoken.ai/v1/images/generations:

Ventana de terminal
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

Estos son valores iniciales recomendados, no requisitos fijos. Se recomienda n=1; el endpoint acepta un entero de 1 a 10, pero puede devolver menos imágenes.

{
"model": "gpt-image-2",
"n": 1,
"response_format": "b64_json",
"output_format": "png"
}
ParámetroValorFunción
modelgpt-image-2, gpt-image-2.5-flare o gpt-image-2.5-sunburstElige un Model ID disponible en model plaza. Un ID válido no garantiza que modelo, tamaño u operación estén disponibles para la solicitud.
promptUna descripción de textoDescripción obligatoria de la imagen. Incluye el sujeto, el estilo, la composición y las restricciones importantes.
sizeOmitirlo, usar auto o indicar dimensiones como 1024x1024Solicita tamaño y proporción; las dimensiones entregadas pueden variar.
nEntero de 1 a 10Máximo solicitado. Se recomienda 1; pueden devolverse menos imágenes.
qualityauto, low, medium, high para gpt-image-2; los dos modelos 2.5 también aceptan xhigh y maxPreferencia opcional. Omite el campo o usa JSON null para el valor predeterminado. Aceptar el parámetro no garantiza que un nivel superior mejore la calidad.
response_formatb64_jsonDevuelve cada imagen en base64 en data[].b64_json.
output_formatPor ejemplo, pngSolicita un formato, pero no garantiza la codificación del archivo. Identifica el formato por sus bytes antes de guardarlo.

La respuesta puede incluir menos imágenes que n. Procesa todos los elementos de data[]; recomendar n=1 no significa que sea un límite del servidor.

Tamaños recomendados

sizeProporciónUso
autoAutomáticaSelección automática del tamaño
1024x10241:1Imágenes cuadradas, avatares, portadas y recursos
1536x10243:2Pósteres horizontales, banners y escenas
1024x15362:3Portadas móviles y pósteres verticales
1536x11524:3Imágenes horizontales estándar, productos y gráficos de contenido
1152x15363:4Imágenes verticales estándar, portadas móviles y pósteres verticales
2048x20481:1Imágenes cuadradas de alta resolución
2048x115216:9Imágenes horizontales de alta resolución
3840x216016:9Imágenes horizontales 4K
2160x38409:16Imágenes verticales 4K

La tabla contiene ejemplos, no una lista cerrada. Puedes omitir size o usar auto; null en JSON activa el tamaño automático. Las dimensiones explícitas deben ser positivas, múltiplos de 16 y no mayores de 3840; la proporción no puede superar 3:1 y el total debe estar entre 655360 y 8294400 píxeles. 2080x2080 es válido. Comprueba las dimensiones entregadas y no recortes la imagen a la fuerza.

Guarda la imagen

Una respuesta correcta sigue la estructura de imagen compatible con OpenAI. Los importes siguientes ilustran el formato del recibo y no son precios fijos:

{
"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"
}
]
}
}

Lee todos los data[].b64_json y permite campos adicionales como revised_prompt. BetterToken incluye la facturación en el objeto raíz bettertoken_image_billing: settled_amount y cada amount son cadenas decimales, y outputs[].index empieza en 0. Las dimensiones y billing_resolution del objeto describen el resultado facturado.

output_format solicita un formato, pero no garantiza codificación ni conversión. Inspecciona los bytes y usa la extensión correspondiente. Los ejemplos con bibliotecas estándar detectan PNG, JPEG y WebP sin dependencias adicionales.

import base64
import json
from 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)

Ejemplo con 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);
}

Si tu aplicación necesita una codificación fija PNG, JPEG o WebP, identifica primero el formato real y convierte la imagen cuando sea necesario. Cambiar solo la extensión del archivo no convierte la imagen.

Consulta el coste real

bettertoken_image_billing se devuelve con el resultado; no necesitas una consulta aparte.

CampoSignificado
currencyMoneda liquidada; no siempre es USD o CNY.
settled_amountImporte total de la solicitud como cadena decimal.
requested_resolutionNivel de resolución deducido de la solicitud.
outputs[].indexÍndice desde cero correspondiente a data[].
outputs[].width, heightAncho y alto reales en píxeles.
outputs[].billing_resolutionNivel final de facturación de la imagen.
outputs[].currency, amountMoneda e importe liquidados por imagen.

El tamaño solicitado y el nivel facturado pueden diferir: una solicitud 1024x1024 ha devuelto 1254x1254 con facturación 2K. Usa el importe del recibo y consulta los precios actuales en el model plaza. Conserva los importes como cadenas para mostrarlos y usa aritmética decimal al calcular. Un recibo ausente no equivale a coste cero.

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']}"
)

Flujo de respuesta

Este endpoint es síncrono. Después de enviar POST /images/generations, mantén abierta la solicitud HTTP hasta recibir respuesta. Si se completa, cada imagen aparece en data[].b64_json con sus datos de entrega y facturación.

El endpoint no devuelve un task_id, y no existe un endpoint separado para consultar el estado o descargar el resultado.

Tiempos de espera, reintentos y facturación

Configura varios minutos de timeout. Un timeout, una desconexión o un 5xx ambiguo no confirma si la generación se ejecutó o se cobró. No repitas automáticamente un POST de generación o edición. Primero consulta los registros de consumo o de solicitudes y conserva cualquier request ID devuelto. Un request ID creado por el cliente no hace idempotente al servidor; un reenvío deliberado puede crear otra solicitud y otro cargo.

Corrige primero los errores de entrada, autenticación o cuota. Reintenta un 429 con backoff solo cuando se confirme el rechazo. No asumas que todos los errores 5xx o de transporte son seguros para repetir.

Antes de procesar la solicitud, BetterToken puede preautorizar un límite igual al mayor precio unitario aplicable multiplicado por n. El saldo puede alcanzar para la imagen 1K entregada y aun así no cubrir esa retención; en ese caso, la solicitud se rechaza con 403 y error.code=insufficient_user_quota. El cargo final se calcula según las imágenes entregadas. El objeto raíz bettertoken_image_billing informa el settled_amount, la divisa y el amount, billing_resolution y las dimensiones de cada resultado. Los importes son cadenas decimales y pueden entregarse menos imágenes que n.

Gestión de errores

Los errores suelen devolver JSON. Al mostrar un error, lee primero error.message, después message y, por último, el texto del estado HTTP.

Estado HTTPSignificadoQué hacer
400JSON mal formado, parámetro ausente o tamaño no admitidoComprueba el cuerpo de la solicitud. No reintentes automáticamente.
401Falta la API Key o no es válidaComprueba la cabecera Authorization: Bearer YOUR_API_KEY.
402 o 403Cuota o saldo insuficientes, incluida una retenciónComprueba error.code y el saldo/cuota. 403 con error.code=insufficient_user_quota indica que el saldo puede ser inferior al límite de preautorización.
429Límite de frecuencia, concurrencia o servicio ocupadoReintenta con backoff solo tras confirmar el rechazo.
5xxFallo del gateway o del servicio originalLa ejecución y el cobro pueden ser desconocidos. Consulta los registros antes de reenviar deliberadamente.

Lista de integración

  • La Base URL es https://bettertoken.ai/v1.
  • La cabecera incluye Authorization: Bearer sk-....
  • La solicitud usa application/json.
  • Elige un Model ID disponible para esta solicitud: gpt-image-2, gpt-image-2.5-flare o gpt-image-2.5-sunburst.
  • Usa response_format=b64_json. output_format es un valor solicitado; identifica el formato real por los bytes antes de guardar.
  • n acepta enteros de 1 a 10. Empieza con 1; pueden devolverse menos imágenes.
  • Omite size, usa auto o indica dimensiones válidas. La tabla anterior no es una lista cerrada.
  • El cliente HTTP permite esperar varios minutos a que termine la generación.
  • Los registros y las capturas de errores no revelan la API Key ni el contenido base64 completo.

Documentación relacionada

POST/v1/images/generations

Autorizaciones

Authorizationstringheaderrequerido

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Cuerpo application/json

modelenum<string>predeterminado: gpt-image-2requerido

GPT Image Model ID. One BetterToken API Key works with all available models.

Opciones disponibles: gpt-image-2, gpt-image-2.5-flare, gpt-image-2.5-sunburst

Ejemplo:"gpt-image-2"
promptstringrequerido

A detailed description of the image to generate.

Ejemplo:"A futuristic AI product poster on a light background, with glass textures, a clean composition, and a premium technology aesthetic."
ninteger | nullpredeterminado: 1

Allowed range: 1–10; start with 1. Fewer images may be delivered than requested. Iterate data[] and use actual-delivery billing.

Rango requerido: 1 <= x <= 10

Ejemplo:1
sizestring | nullpredeterminado: 1024x1024

Omit 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.

Ejemplo:"1024x1024"
Ejemplo: ["auto","1024x1024","2048x2048","2080x2080","3840x2160"]
response_formatenum<string>predeterminado: b64_json

Use b64_json.

Opciones disponibles: b64_json

Ejemplo:"b64_json"
output_formatstringpredeterminado: png

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.

Ejemplo:"png"
qualityenum<string | null>predeterminado: auto

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.

Opciones disponibles: auto, low, medium, high, xhigh, max, null

Ejemplo:"auto"

Respuesta

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.

createdinteger
Ejemplo:1710000000
dataobject[]
Show child attributes

Base64-encoded image content.

Ejemplo:"iVBORw0KGgoAAAANSUhEUgAA...(truncated)"

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[].

Rango requerido: x >= 0

Rango requerido: x >= 1

Rango requerido: x >= 1

Opciones disponibles: 1K, 2K, 4K

Settled amount for this image as a decimal string.

Resolution tier inferred from the request; it may differ from the actual billing tier.

Ejemplo
{
  "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.
errorobject
Show child attributes
Ejemplo:"invalid request"
Ejemplo:"invalid_request_error"
Ejemplo:"invalid_request"
messagestring
Ejemplo:"insufficient quota"
Ejemplo
{
  "error": {
    "message": "invalid request",
    "type": "invalid_request_error",
    "code": "invalid_request"
  },
  "message": "insufficient quota"
}
401The BetterToken API Key is missing or invalid.
errorobject
Show child attributes
Ejemplo:"invalid request"
Ejemplo:"invalid_request_error"
Ejemplo:"invalid_request"
messagestring
Ejemplo:"insufficient quota"
Ejemplo
{
  "error": {
    "message": "invalid request",
    "type": "invalid_request_error",
    "code": "invalid_request"
  },
  "message": "insufficient quota"
}
402The account has insufficient credit or balance.
errorobject
Show child attributes
Ejemplo:"invalid request"
Ejemplo:"invalid_request_error"
Ejemplo:"invalid_request"
messagestring
Ejemplo:"insufficient quota"
Ejemplo
{
  "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.
errorobject
Show child attributes
Ejemplo
{
  "error": {
    "code": "insufficient_user_quota",
    "message": "Insufficient balance or token quota."
  }
}
429A rate or concurrency limit was reached, or the upstream service is busy.
errorobject
Show child attributes
Ejemplo:"invalid request"
Ejemplo:"invalid_request_error"
Ejemplo:"invalid_request"
messagestring
Ejemplo:"insufficient quota"
Ejemplo
{
  "error": {
    "message": "invalid request",
    "type": "invalid_request_error",
    "code": "invalid_request"
  },
  "message": "insufficient quota"
}
500The gateway or upstream service returned an error.
errorobject
Show child attributes
Ejemplo:"invalid request"
Ejemplo:"invalid_request_error"
Ejemplo:"invalid_request"
messagestring
Ejemplo:"insufficient quota"
Ejemplo
{
  "error": {
    "message": "invalid request",
    "type": "invalid_request_error",
    "code": "invalid_request"
  },
  "message": "insufficient quota"
}