GPT Image
Genere y edite imágenes con GPT Image: parámetros, respuestas y advertencias.
| Elemento | Valor |
|---|---|
| Base URL | https://api.hop-base.com/v1 |
| Generar imágenes | POST /v1/images/generations |
| Editar imágenes | POST /v1/images/edits |
| Consultar tareas asíncronas | GET /v1/images/tasks?task_id=… |
| Grupo de la clave | GPT Image (todos los modelos) |
Por defecto la respuesta es síncrona y trae imágenes en Base64; añada Prefer: respond-async para usar una tarea asíncrona. Las claves de grupos de chat reciben 404 con gpt-image-*.
Modelos disponibles
| Modelo | ID de modelo | Niveles de quality | Precio oficial |
|---|---|---|---|
| GPT Image 2.5 Flare | gpt-image-2.5-flare | low / medium / high / xhigh / max | $5 / $30/ 1M tokens |
| GPT Image 2.5 Sunburst | gpt-image-2.5-sunburst | low / medium / high / xhigh / max | $5 / $30/ 1M tokens |
| GPT Image 2 | gpt-image-2 | low / medium / high | $5 / $30/ 1M tokens |
Cómo elegir: Flare es la opción diaria; Sunburst ofrece mayor fidelidad y es algo más lento que Flare con la misma configuración; gpt-image-2 es de uso general y su ID es gpt-image-2, no gpt-image-2.0. Tiempos de referencia para una imagen de 1024x1024: unos 14 segundos en low con cualquiera de los dos modelos 2.5; en high, Flare tarda unos 19 segundos y Sunburst unos 37.
Parámetros de la solicitud
Generar
POST /v1/images/generations con cuerpo JSON.
| Parámetro | Obligatorio | Tipo y límites | Predeterminado | Notas |
|---|---|---|---|---|
model | Obligatorio | string | — | Uno de los tres ID de arriba |
prompt | Obligatorio | string, ≤ 32.000 caracteres | — | No puede quedar vacío tras quitar espacios |
size | Opcional | auto o WIDTHxHEIGHT | — | Reglas bajo la tabla |
quality | Opcional | auto / low / medium / high | — | 2.5 añade xhigh / max |
n | Opcional | integer, 1–10 | 1 | Algunos grupos solo aceptan 1 |
background | Opcional | auto / opaque / transparent | — | Transparente requiere png / webp |
output_format | Opcional | png / jpeg / webp | png | Formato de la imagen decodificada |
output_compression | Opcional | integer, 0–100 | 100 | Solo jpeg / webp |
moderation | Opcional | auto / low | — | No desactiva los controles de seguridad |
user | Opcional | string | — | Identificador del usuario final |
stream | Opcional | boolean | false | true cambia a Images SSE |
response_format | Opcional | string | — | Omítalo |
input_fidelity | Opcional | low / high | — | Campo de compatibilidad; omítalo |
En size, WIDTHxHEIGHT debe usar múltiplos de 16, cada lado ≤ 3840, relación de aspecto ≤ 3:1 y total de píxeles 655.360–8.294.400. No se aceptan las abreviaturas 1K / 2K / 4K; un size no válido devuelve 400 antes de generar y no se cobra.
Los niveles de quality más altos generan más tokens de salida y cuestan más. response_format siempre devuelve b64_json; user no es un ID de cuenta de HopBase ni cambia a quién se factura.
Editar
POST /v1/images/edits acepta todos los parámetros anteriores, más referencias y máscara. Prefiera multipart/form-data para archivos locales; también acepta JSON con URL / Data URL.
| Parámetro | Obligatorio | Tipo y límites | Predeterminado | Notas |
|---|---|---|---|---|
image | Obligatorio | 1–16 imágenes | — | Multipart: image o image[] repetido |
mask | Opcional | PNG con canal alfa | — | Los píxeles transparentes marcan la zona a editar |
En JSON, image puede ser una cadena URL / Data URL, un array de cadenas u objetos {"url": …}. No se lee images, y no se acepta base64 sin prefijo ni file_id.
Una URL remota debe ser ≤ 25 MiB, con Content-Type image/* y sin apuntar a una dirección interna; puede comprimirse a 4 MiB antes de reenviarse. El cuerpo completo tiene un límite de 60 MB; si lo supera, devuelve 413.
Asíncrono
Añada la cabecera HTTP Prefer: respond-async a una solicitud de generación o edición; el cuerpo no cambia. Es una cabecera, no un parámetro JSON.
Las tareas asíncronas conservan solo model, prompt, n, size, quality, background, output_format, input_fidelity y las imágenes / máscara de edición; el resto se descarta.
Respuesta
Síncrona
| Campo | Tipo | Notas |
|---|---|---|
created | integer | Segundos Unix |
data[].b64_json | string | Imagen en Base64; decodifíquela y guárdela según output_format |
usage.input_tokens | integer | Tokens de entrada (puede devolverse) |
usage.output_tokens | integer | Tokens de salida (puede devolverse) |
usage.total_tokens | integer | Total (puede devolverse) |
error | object | Si falla: message, type, code |
{
"created": 1760000000,
"data": [
{
"b64_json": "iVBORw0KGgoAAA..."
}
],
"usage": {
"input_tokens": 42,
"output_tokens": 1760,
"total_tokens": 1802
}
}Pasados unos 40 segundos, el servidor devuelve HTTP 200 y sigue escribiendo espacios en blanco al inicio del cuerpo para mantener la conexión; el JSON completo llega después. Desde entonces el estado sigue siendo 200 aunque la generación falle, así que busque error en el cuerpo y configure el tiempo de lectura en al menos 300 segundos.
Streaming (stream: true)
La respuesta pasa a Images SSE: mientras espera, el flujo envía líneas de comentario de keepalive que empiezan por dos puntos, y el último evento data: contiene el JSON completo de Images, seguido de [DONE]. No son los eventos progresivos nativos de OpenAI.
: hopbase-keepalive
data: {"created":1760000000,"data":[{"b64_json":"iVBORw0KGgoAAA..."}]}
data: [DONE]Tareas asíncronas
Al enviar, la respuesta llega de inmediato con 202 Accepted; la cabecera Location apunta a la misma URL de consulta:
{
"object": "image.task",
"task_id": "su-task-id",
"status": "pending",
"status_url": "/v1/images/tasks?task_id=su-task-id"
}Consulte solo con GET /v1/images/tasks?task_id=…; no se admite poner el ID de la tarea en la ruta. pending, processing y retrying indican que sigue en curso; completed y failed son finales.
| Campo | Tipo | Notas |
|---|---|---|
task_id | string | ID de la tarea |
status | string | Estado de la tarea |
result_content | string | Al completarse: Markdown, una línea por imagen |
error | string | Solo si failed: motivo en inglés, sin código |
usage.cost | number | Importe realmente descontado por esta tarea |
usage.currency | string | Moneda contable, actualmente CNY |
usage.cost_cny | number | Importe en CNY, para conciliar |
usage.cost_usd | number | Importe en USD, para conciliar |
{
"task_id": "su-task-id",
"status": "completed",
"result_content": "",
"usage": {
"cost": 1.36,
"currency": "CNY",
"cost_cny": 1.36,
"cost_usd": 0.2
}
}result_content contiene rutas relativas; anteponga https://api.hop-base.com para descargar. usage aparece cuando la tarea está completed o failed, y solo la ve la clave que creó la tarea.
Ejemplos
Generar
curl https://api.hop-base.com/v1/images/generations \
-H "Authorization: Bearer sk-su-clave" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2.5-flare",
"prompt": "Un shiba inu bajo un cerezo en flor, acuarela japonesa",
"size": "1024x1024",
"quality": "medium",
"output_format": "png"
}' \
| jq -r '.data[0].b64_json' | base64 --decode > result.pngEl ejemplo de curl necesita tener jq instalado.
Editar (varias referencias + máscara)
curl https://api.hop-base.com/v1/images/edits \
-H "Authorization: Bearer sk-su-clave" \
-F "model=gpt-image-2.5-flare" \
-F "prompt=Pon un jarrón en la zona enmascarada, al estilo de la 2.ª imagen" \
-F "image[][email protected]" \
-F "image[][email protected]" \
-F "[email protected]" \
-F "size=1024x1024" \
-F "quality=high" \
-F "output_format=png"En JSON, sustituya los archivos por URL: "image": ["https://example.com/scene.png", "https://example.com/style.png"] y "mask": "https://example.com/mask.png".
Asíncrono
# 1. Enviar y recibir 202 + task_id
curl -i https://api.hop-base.com/v1/images/generations \
-H "Authorization: Bearer sk-su-clave" \
-H "Content-Type: application/json" \
-H "Prefer: respond-async" \
-d '{
"model": "gpt-image-2",
"prompt": "Una ciudad futurista de noche, estilo cinematográfico",
"size": "2048x2048"
}'
# 2. Consultar con el task_id de la primera respuesta
curl "https://api.hop-base.com/v1/images/tasks?task_id=su-task-id" \
-H "Authorization: Bearer sk-su-clave"Advertencias
- Para imágenes 2K / 4K, prefiera el modo asíncrono y así evitar que la CDN corte solicitudes largas.
- Configure el tiempo de lectura del cliente para solicitudes síncronas en al menos 300 segundos.
sizesolo aceptaautooWIDTHxHEIGHT; las abreviaturas de nivel devuelven 400.xhigh/maxsolo existen en los dos modelos 2.5.background: "transparent"requierepngowebp; la transparencia engpt-image-2es una función en vista previa.- No se admite el campo oficial de streaming
partial_images(0–3); omítalo. - Con los SDK oficiales, mantenga
streamen su valor predeterminadofalse. - El gateway redimensiona la máscara al tamaño de la primera referencia y no garantiza conservar píxel a píxel el resto.
- La URL de
result_contentse abre sin clave, así que no la comparta públicamente y descárguela pronto a su propio almacenamiento.
- Los valores estándar siguen la referencia de OpenAI Images y la referencia oficial de edición.
output_compression,moderation,useryresponse_formatsolo se transmiten en generaciones JSON síncronas y ediciones multipart síncronas; las ediciones JSON y las tareas asíncronas descartan estos campos.- En los grupos que solo aceptan 1, un
nmayor devuelve 400; unn≤ 0 se trata como 1. input_fidelityes un campo de compatibilidad; GPT Image 2 procesa las referencias con alta fidelidad por defecto.- El número de referencias lo verifica el servicio oficial: el gateway no cuenta las imágenes, y el servicio puede rechazar la solicitud o ignorar algunas.
- La referencia oficial no indica un límite agregado en MB para todas las referencias; una cadena URL / Data URL en JSON admite hasta 20.971.520 caracteres.
- 4 MiB es un objetivo de compresión antes de reenviar, no un umbral de rechazo; Base64 añade aproximadamente un tercio al tamaño de los datos.
- Ejemplo de Data URL:
data:image/png;base64,iVBORw0KGgo…; envíe la codificación completa con el tipo MIME correcto. - Al enviar una tarea asíncrona solo se comprueba que el saldo sea mayor que 0; no se reserva ningún importe.
Errores frecuentes
Los parámetros no válidos devuelven 400 antes de generar y no se cobran. Un rechazo de seguridad de contenido también devuelve 400 sin cargo, con error.code igual a safety_rejected.
| Error | Qué hacer |
|---|---|
size must be WIDTHxHEIGHT or auto y otros errores de size | Ajuste el valor según las reglas de size |
prompt must not be empty | Envíe un prompt no vacío |
n must be 1 for this model in the current group | Divida en solicitudes separadas |
/v1/images/edits requires at least one image | Ponga las referencias en image, no en images |
image download returned HTTP 404 | Use una URL pública que el servidor pueda descargar |
Your request was rejected by the safety system. | Reformule el prompt o cambie la referencia |
Request body exceeds the size limit (60 MB) (413) | Comprima las imágenes o envíe URL |
HTTP 200 con error en el cuerpo | Falló tras iniciarse el keepalive; revise error.message |
# size: siga las reglas de tamaño de arriba
size must be WIDTHxHEIGHT or auto
size side length exceeds 3840px (4096x2048)
size width and height must be multiples of 16 (1000x1000)
size aspect ratio must not exceed 3:1 (3840x1024)
size total pixel count must be at least 655360 (512x512=262144)
size total pixel count must not exceed 8294400 (3840x3840=14745600)
# prompt vacío
prompt must not be empty
# edits JSON: referencias en "image" como cadenas o {"url": ...}
# ("images" no se lee)
/v1/images/edits requires at least one image
image object is missing the url field
image must be a data URL or an http(s) URL
# referencias remotas: URL pública que devuelva image/*, como máximo 25 MiB
image download returned HTTP 404
image is too large
image Content-Type is not image/*: text/html
reference image URL must not point to an internal address
image is too large, please compress it to under 4MB and retry
# seguridad de contenido (error.code: safety_rejected)
Your request was rejected by the safety system.
# HTTP 413
Request body exceeds the size limit (60 MB)Facturación
Se factura por token; un quality más alto genera más tokens de salida. Medido a 1024x1024: unos 200 en low, 1.760 en high, 3.120 en xhigh y 7.020 en max. En tareas asíncronas, el cargo real es usage.cost en la consulta (cost_cny / cost_usd con un cambio fijo de 1 USD = 6,8 CNY), y una tarea fallida suele mostrar 0.
Los precios están en las fichas de modelo de arriba y en el catálogo de modelos tras iniciar sesión.
Próximos pasos
- Otras familias de imagen y cómo elegir: Resumen de imágenes
- Otras familias: Imágenes de Gemini, Seedream, Imágenes de Grok Imagine, Imágenes de Kling, Midjourney
- Todos los campos en la referencia de API: Generar imágenes, Editar imágenes, Consultar una tarea de imagen
- Si algo falla, revise Solución de problemas