Referencia de la API
Esquema completo de la API REST pública. Disponible en los planes Pro y Max. Emite una clave en /account/api.
¿Prefieres Postman? Descarga nuestra colección v2.1 y pega tu clave gimg_… en la variable apiKey.
Autenticación
Todos los endpoints reciben un token Bearer en la cabecera Authorization. Los tokens siempre empiezan con gimg_.
Authorization: Bearer gimg_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Límites de tasa
600 solicitudes / hora / clave, máximo 5 en curso. Cada respuesta incluye:
X-RateLimit-Limit— fijo en 600X-RateLimit-Remaining— llamadas restantes en la ventana actualX-RateLimit-Reset— segundos epoch en los que la ventana se reiniciaRetry-After— segundos hasta la siguiente llamada permitida (solo en 429)
Idempotencia
Pasa Idempotency-Key en las solicitudes POST. Enviar la misma clave dos veces devuelve la generación existente en lugar de cobrar créditos por duplicado.
/api/v1/generateEnvía una generación de texto a imagen O de edición de imagen. Devuelve de inmediato un generationId; consulta /api/v1/generations/:id para obtener el resultado.
Body
promptstring ≤ 4000 charsobligatorioDescripción en lenguaje natural. La terminología fotográfica (cámara, lente, iluminación) ayuda.
type"text2img" | "edit"Por defecto 'text2img'. 'edit' requiere inputImageKeys.
size"1024x1024" | "1024x1536" | "1536x1024"Relación de aspecto. Por defecto 1024x1024.
quality"low" | "medium" | "high"Por defecto medium. high = HD 2K. low es Fast (1cr).
n1–4Número de variaciones. Por defecto 1.
inputImageKeysstring[] (max 4)Claves de R2 devueltas por /api/v1/upload. Obligatorio cuando type=edit.
Respuestas
202 Acceptedjson{ "generationId": "...", "status": "queued" }
400 Bad RequestjsonBody inválido. El error incluye un mensaje de validación de Zod.
401 UnauthorizedjsonClave Bearer ausente o inválida.
402 Payment RequiredjsonCréditos insuficientes o tope mensual de cómputo alcanzado.
403 ForbiddenjsonSe requiere el plan Pro o Max.
422 UnprocessablejsonPrompt bloqueado por la política de contenido.
429 Too Many RequestsjsonLímite de tasa alcanzado. Consulta Retry-After.
/api/v1/uploadObtén una URL PUT firmada de R2 para subir una imagen de entrada. En dos pasos: este endpoint devuelve la URL y tú haces PUT de los bytes directamente.
Body
filenamestring ≤ 200obligatorioNombre para mostrar; no se usa para el almacenamiento.
contentType"image/png" | "image/jpeg" | "image/webp"obligatorioDebe ser exactamente uno de estos tres.
sizenumber (bytes ≤ 10 MB)obligatorioTamaño del archivo que vas a subir con PUT. Se usa para validación.
Respuesta (200)
urlstringURL PUT firmada, expira en 5 minutos.
keystringClave de R2: pásala en inputImageKeys al llamar a /api/v1/generate.
/api/v1/generations/:idConsulta el estado de una generación. Devuelve de inmediato el estado actual.
Respuesta (200)
idstringEl id de la generación.
status"queued" | "running" | "succeeded" | "failed" | "blocked"'blocked' = la moderación de contenido rechazó la entrada o la salida (créditos reembolsados).
typestringtext2img | edit | upscale | …
outputsArray<{ png, webp, width, height }>Se completa cuando status=succeeded. Las URLs son públicas, inmutables y están en caché en el CDN.
errorstring | nullSe completa cuando status=failed o status=blocked.
costCreditsnumberCréditos cobrados (reembolsados si se bloquea o falla).
createdAt / completedAtISO 8601Marcas de tiempo.
Webhooks salientes
Sáltate el polling: registra endpoints HTTPS para recibir los eventos generation.succeeded y generation.failed en cuanto ocurren. Adminístralos en /api/account/webhooks.
Registrar
curl -X POST https://gptimage2.plus/api/account/webhooks \
-H "Cookie: <your session cookie>" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/hooks/gptimg",
"events": ["generation.succeeded", "generation.failed"],
"label": "Production app"
}'
# → { "id": "...", "secret": "whsec_..." } ← copy this, shown ONCEPayload del evento
POST https://your-app.com/hooks/gptimg
X-Gptimg-Event: generation.succeeded
X-Gptimg-Signature: <hex sha256 hmac of body>
X-Gptimg-Delivery: <uuid for dedup>
Content-Type: application/json
{
"event": "generation.succeeded",
"data": {
"generationId": "...",
"type": "text2img",
"status": "succeeded",
"outputs": [{ "png": "...", "webp": "...", "width": 1024, "height": 1024 }],
"createdAt": "2026-04-26T01:23:45.000Z",
"completedAt": "2026-04-26T01:23:50.000Z"
}
}Verificar la firma
// Node example
import crypto from "crypto";
const expected = crypto
.createHmac("sha256", process.env.WEBHOOK_SECRET)
.update(rawBody)
.digest("hex");
const ok = crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(req.headers["x-gptimg-signature"])
);Timeout: 5 s por intento. Reintentamos las respuestas no-2xx hasta 3 veces con backoff exponencial (30 s → 2 m → 10 m). Tras 8 fallos consecutivos entre intentos, el webhook se desactiva automáticamente: reactívalo en /account/webhooks.