> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bettertoken.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Cómo usar 1K, 2K, 4K, Quality y Mask en GPT Image: guía de pruebas de BetterToken

> Guía con pruebas reales de GPT Image: tamaños entregados, calidad, edición con máscara, enrutamiento y precios de BetterToken, con resultados y límites observados.

export const GptImageComparison = ({kind, labels, caption, label}) => {
  const comparisonPanels = {
    crops: [["comparison-crop-1k.png", 480, 480], ["comparison-crop-2k.png", 480, 480], ["comparison-crop-4k.png", 480, 480]],
    mask: [["comparison-mask-original.png", 476, 476], ["comparison-mask-overlay.png", 476, 476], ["comparison-mask-result.png", 476, 476]],
    boundary: [["comparison-boundary-original.png", 576, 256], ["comparison-boundary-result.png", 576, 256]],
    circles: [["comparison-circles-original.png", 416, 416], ["comparison-circles-overlay.png", 416, 416], ["comparison-circles-result.png", 416, 416]]
  };
  const panels = comparisonPanels[kind];
  return <div className="bt-image-comparison not-prose">
      <div className="bt-image-comparison-scroll" role="region" aria-label={label} tabIndex={0}>
        <div className="bt-image-comparison-grid" style={{
    gridTemplateColumns: `repeat(${panels.length}, minmax(0, 1fr))`,
    '--bt-comparison-min-width': `${panels.length * 176 + (panels.length - 1) * 16}px`
  }}>
          {labels.map((title, index) => <p className="bt-image-comparison-title" key={`title-${index}`}>{title}</p>)}
          {panels.map(([file, width, height], index) => <a key={file} href={`/images/gpt-image-guide/${file}`} target="_blank" rel="noreferrer">
              <img src={`/images/gpt-image-guide/${file}`} alt={labels[index]} width={width} height={height} loading="lazy" style={{
    borderRadius: '0.5rem'
  }} />
            </a>)}
        </div>
      </div>
      <p className="bt-image-comparison-caption">{caption}</p>
    </div>;
};

Al generar imágenes de productos, recursos publicitarios o diseños con `gpt-image-2`, `gpt-image-2.5-flare` y `gpt-image-2.5-sunburst`, muchos desarrolladores se encuentran con varias preguntas difíciles:

* **¿Por qué varían los resultados entre llamadas con el mismo modelo y los mismos parámetros?**
* **¿Por qué, aunque se solicite 4K o un tamaño específico, la imagen recibida se reduce a 1K?**
* **¿El retoque localizado con `Mask` o `quality=high` realmente se aplica? ¿Con qué criterio se cobra al final?**

En las llamadas cotidianas a la API, no basta con comprobar si el estado HTTP es `200 OK`: deben cumplirse a la vez estas tres condiciones: **generar la imagen, poder usarla en el diseño previsto y tener costes transparentes y previsibles**.

Para ayudar a los desarrolladores a entender el comportamiento real de estos tres modelos, BetterToken ha implementado a nivel interno **enrutamiento inteligente según las capacidades, limpieza de parámetros predeterminados, bloqueo previo de parámetros no válidos y facturación transparente basada en los píxeles realmente entregados**. Esta guía se basa en los datos de las pruebas más recientes y en una instantánea de precios del 19 de octubre de 2026. Con imágenes originales generadas y facturas reales, te muestra cómo realizar las llamadas, qué resultados puedes obtener y qué límites objetivos siguen teniendo los propios modelos.

> **Nota**: Esta guía se centra en `gpt-image-2`, `gpt-image-2.5-flare` y `gpt-image-2.5-sunburst`. Los parámetros y el sistema de facturación de la serie Nano Banana son diferentes; los explicaremos en otro artículo para evitar confusiones.

## 1. ¿Por qué pueden variar los resultados con el mismo modelo y los mismos parámetros?

En el uso real, los distintos nodos de servicio que hay detrás del mismo nombre de modelo suelen diferir en capacidad y estabilidad: algunas rutas solo admiten imágenes básicas de 1K, mientras que otras entregan imágenes de alta resolución de `2048×2048` o incluso `3840×2160`. También varía entre nodos el grado de compatibilidad con los valores de `quality`, la edición con imágenes de referencia y las máscaras `Mask`.

Si una plataforma simplemente reenvía las solicitudes a ciegas según el nombre del modelo, los desarrolladores se encontrarán a menudo con situaciones como «solicité 4K, pero recibí una imagen pequeña de 1K», «envié una Mask y la solicitud dio error» o «tengo que ajustar los parámetros una y otra vez». Por eso necesitamos un estándar de pruebas riguroso que verifique por separado si la interfaz acepta los parámetros y cuál es el resultado realmente entregado.

## 2. Cómo probamos: ¿qué consideramos «compatible»?

Para que las conclusiones sean objetivas y fiables, diseñamos **22 escenarios de prueba estándar** para la regresión de la versión estable (17 solicitudes válidas entregaron 18 imágenes; los 5 casos con parámetros no válidos se bloquearon según lo previsto y no generaron cargos) y, además, generamos imágenes de productos y muestras de edición con Mask para escenarios habituales de comercio electrónico.

Nuestros criterios de verificación son directos:

1. **Decodificar los píxeles del archivo original**: no confiamos sin más en lo que declara la interfaz. Decodificamos las dimensiones de cada imagen entregada a partir del archivo original y las contrastamos con el nivel de facturación indicado en la respuesta y el cargo real en la cuenta.
2. **Determinar si se alcanza el tamaño**: comparamos por separado el ancho y el alto solicitados de forma explícita. Si las dimensiones reales son mayores, se considera aprobado; **si cualquiera de los lados queda más de un 5% por debajo del tamaño objetivo, se considera que no lo alcanza** (nota: este criterio sirve para evaluar estrictamente los resultados de la prueba; no significa que la API descarte automáticamente las imágenes válidas que no alcancen el tamaño solicitado). Si se omite el tamaño o se envía `auto`, no se considera que haya un lienzo fijo como objetivo.
3. **Separar la aceptación de parámetros del resultado real**: que la interfaz no dé error solo significa que «acepta el parámetro». Para determinar si `Mask` aísla estrictamente una zona o si `quality=high` mejora la imagen de forma visible, hay que examinar el resultado final.

## 3. Resultados de las pruebas: ¿qué parámetros se malinterpretan con más facilidad?

Al comparar los parámetros solicitados, los píxeles realmente entregados y la factura final, encontramos varios hechos clave que los desarrolladores suelen interpretar mal:

| Escenario solicitado | Tamaño realmente entregado | Nivel de facturación y precio en CNY | Resultado de la prueba y significado práctico |
| :- | :- | :- | :- |
| `gpt-image-2`, `2048x2048`, sin especificar `quality` | 2048×2048 | 2K, ¥0.11 | En esta solicitud, se generó correctamente una imagen grande de 2K sin enviar `quality` (se usó la calidad predeterminada) |
| `flare`, `2048x2048`, sin especificar `quality` | 2048×2048 | 2K, ¥0.15 | Se verificó en las pruebas la entrega en tamaño 2048×2048 |
| `sunburst`, `2048x2048`, sin especificar `quality` | 2048×2048 | 2K, ¥0.15 | Se verificó en las pruebas la entrega en tamaño 2048×2048 |
| `gpt-image-2`, `1024x1024` | **1024×936** | 1K, ¥0.035 | Se entregó una imagen válida, pero la altura se redujo aproximadamente un 8.6%; no alcanzó el estricto estándar de tamaño de esta ronda |
| `flare` / `sunburst`, `1024x1024` | **ambos, 1254×1254** | **2K, ambos a ¥0.15** | **Solicitar 1K no garantiza que se cobre como 1K**; las imágenes cuadradas entregadas superaron lo solicitado y se clasificaron como 2K |
| `gpt-image-2`, `1536x1024` | 1536×1024 | 1K, ¥0.035 | Una imagen horizontal de proporción habitual también pertenece al nivel de facturación 1K |
| `gpt-image-2`, `3840x2160` | **3840×2159** | 4K, ¥0.13 | La altura solo difiere en 1 píxel (desviación \< 0.05%), por lo que cumple el criterio de aceptación de tamaño 4K |
| `gpt-image-2`, Mask válida + `2048x2048` + `high` | 2048×2048 | 2K, ¥0.11 | El flujo de edición con Mask funcionó, pero la precisión del aislamiento de la zona requiere verificar el resultado visual |

Además, las pruebas mostraron lo siguiente sobre la compatibilidad de parámetros y la gestión de errores:

* **Tolerancia a parámetros predeterminados**: la imagen se genera correctamente tanto si `quality` y `size` se omiten, se envían como `null` o se especifican como `"auto"`.
* **Cómo solicitar 4K correctamente**: **«4K» es un concepto de nivel de facturación y no significa que se admitan imágenes cuadradas de `4096x4096`**. Para obtener una imagen grande de alta resolución de nivel 4K, usa el tamaño horizontal `3840x2160`.
* **Bloqueo de parámetros no válidos sin cargos**: al enviar `4096x4096`, `stream=true`, una cadena vacía `quality=""`, una cadena vacía `size=""` o `n=0`, todas las solicitudes de prueba devolvieron un error `HTTP 400` y **no generaron ningún cargo**.

## 4. Qué ofrece BetterToken: no tienes que adaptar cada ruta por separado

Ante las variaciones de tamaño y las diferencias entre nodos de los modelos subyacentes, BetterToken se ocupa de cuatro aspectos en la capa de gateway para que no tengas que escribir código de adaptación para cada ruta:

1. **Enrutamiento inteligente según las capacidades**: el sistema selecciona automáticamente un servicio disponible con las capacidades correspondientes, según el modelo, el tamaño objetivo (por ejemplo, 2K/4K) y si se incluyen parámetros de edición de imágenes o `Mask`.
2. **Interfaz unificada y valores alternativos para los parámetros**: las interfaces estándar `POST /v1/images/generations` (generación de imágenes) y `POST /v1/images/edits` (edición con imagen de referencia/Mask) procesan automáticamente los valores `null`, `auto` y los parámetros omitidos, y bloquean las entradas no válidas directamente en el gateway.
3. **Devolución transparente de las dimensiones reales y los detalles de facturación**: junto con los datos de la imagen, el campo `bettertoken_image_billing` del cuerpo de la respuesta indica directamente el **ancho y alto decodificados reales (`width`/`height`), el nivel de facturación (`billing_resolution`), la moneda y el importe liquidado (`settled_amount`)**.
4. **Distinción clara entre dos conceptos fundamentales**:
   * **Admitir el parámetro `Mask` ≠ garantizar un retoque preciso a nivel de píxel**: la interfaz permite subir una imagen de referencia y una Mask para editar, pero algunos resultados de las pruebas también modificaron zonas protegidas fuera de la máscara. Por ejemplo, en nuestra prueba geométrica de dos círculos, se pidió cambiar el color del círculo izquierdo transparente y proteger el derecho opaco, pero se cambiaron ambos. Por eso, **confirmamos que se admite el envío del parámetro Mask, pero no garantizamos que se consiga siempre un aislamiento estricto de las zonas a nivel de píxel**.
   * **Admitir el parámetro `quality` ≠ garantizar una mejora fija de la calidad**: la interfaz admite valores como `"auto"` o `"high"` y los enruta correctamente. Sin embargo, como la generación tiene un componente aleatorio, no prometemos a partir de una sola muestra que `high` proporcione una mejora de calidad de un porcentaje determinado.

> ⚠️ **Dos límites reales que debes conocer antes de integrar**:
>
> 1. **Enrutar según las capacidades no equivale a fijar estrictamente los píxeles en cada llamada**: por las diferencias de salida de los servicios subyacentes, los píxeles reales pueden variar incluso si la solicitud se enruta al nodo correcto (por ejemplo, hoy hubo solicitudes de `1024x1024` que devolvieron `1024×936`, y muestras de solicitudes de `3840x2160` que devolvieron `3840×2161`). Si la proporción del lienzo es crítica para tu aplicación, recorta o procesa la imagen después según el ancho y alto reales de la respuesta.
> 2. **Solicitar 1K no siempre implica que se facture como 1K**: el sistema clasifica la imagen según las **dimensiones de la imagen válida realmente entregada**. Hoy, dos modelos 2.5 (y algunos casos de `gpt-image-2`) devolvieron `1254×1254` al recibir solicitudes de `1024x1024`; el sistema las clasificó como nivel **2K** y las facturó según la tarifa correspondiente.

## 5. Compatibilidad de los tres modelos: ¿cuál debo llamar y qué valores debo enviar?

La configuración de capacidades y la cobertura de pruebas actuales de `gpt-image-2`, `gpt-image-2.5-flare` y `gpt-image-2.5-sunburst` son las siguientes:

| Dimensión de capacidad | `gpt-image-2` | `gpt-image-2.5-flare` | `gpt-image-2.5-sunburst` |
| :- | :- | :- | :- |
| **Solicitud de generación 1K** | Compatible (probado; el tamaño real puede diferir del objetivo, por ejemplo 1024×936 o 1254×1254) | Compatible (probado; esta ronda devolvió 1254×1254, un tamaño mayor, y se facturó como 2K) | Compatible (probado; esta ronda devolvió 1254×1254, un tamaño mayor, y se facturó como 2K) |
| **Generación 2K (`2048x2048`)** | **Entrega probada en esta ronda** | **Entrega probada en esta ronda** | **Entrega probada en esta ronda** |
| **Generación 4K (`3840x2160`)** | **Entrega horizontal probada en esta ronda** | La configuración de enrutamiento ya está alineada para admitirla | La configuración de enrutamiento ya está alineada para admitirla |
| **Edición normal con imagen de referencia (sin Mask)** | **Compatible, probado en esta ronda** (si se omite la Mask o se envía vacía, se realiza una edición normal) | Pendiente de confirmar por separado (la compatibilidad con Mask no demuestra que la edición normal también funcione) | Pendiente de confirmar por separado (la compatibilidad con Mask no demuestra que la edición normal también funcione) |
| **Edición localizada con Mask** | **Entrega 2K probada en esta ronda** | Configurada para admitir edición con Mask en 4K (no se han confirmado otros niveles) | Configurada para admitir edición con Mask en 4K (no se han confirmado otros niveles) |
| **Parámetro de calidad (`quality`)** | Valores predeterminado/`auto`/`high` **verificados en las pruebas** | Valores predeterminado/`auto` probados; enrutamiento de `high` configurado y alineado | Valores predeterminado/`auto` probados; enrutamiento de `high` configurado y alineado |

*Nota: «Probado en esta ronda» significa que las pruebas de regresión y la generación de casos de hoy entregaron directamente imágenes y muestras de facturación. «Configuración de enrutamiento alineada para admitirlo» significa que la plataforma ya alineó la configuración del canal de esa capacidad, pero no repitió hoy las solicitudes para todas las combinaciones posibles.*

## 6. Dos casos con imágenes reales: ¿qué resultados ofrecen?

Para mostrar la calidad de generación más real posible, seguimos la estructura **«sujeto explícito + textura del material + dirección de la luz + proporción de composición + elementos que se deben excluir»** de la [guía oficial de OpenAI para prompts de imágenes](https://developers.openai.com/api/docs/guides/image-prompting) y generamos los dos casos de comercio electrónico que aparecen a continuación mediante la interfaz real de BetterToken (se conservan las salidas originales, sin retoques posteriores).

### Caso A: fotografía de producto para comercio electrónico; dimensiones y detalles en 1K / 2K / 4K

**Diseño de la escena (concepto en chino)**:

> Genera una fotografía realista de estudio para comercio electrónico: una taza de cerámica de color rojo coral (con el asa hacia la derecha) sobre una encimera de piedra gris claro, con un paño de lino beige doblado a la izquierda. La taza lleva el texto blanco y nítido «BETTER DAY». Luz lateral suave desde arriba a la izquierda; conserva los reflejos sutiles del esmalte cerámico, las fibras del lino y las sombras de contacto naturales. La taza aparece completa y centrada; el fondo es sencillo y neutro, sin otros objetos, marcas de agua ni texto adicional.

**Prompt real enviado en inglés**:

```text theme={null}
Photorealistic ecommerce studio photograph. A coral-red ceramic mug with a handle on the right sits on a pale gray stone tabletop, with a folded beige linen cloth to its left. The mug reads "BETTER DAY" in clear white lettering. Soft directional light from upper left, subtle glaze reflections, visible linen fibers and natural contact shadows. Entire mug in frame, centered composition, simple neutral background. No other objects, no watermark, no additional text.
```

Usamos `gpt-image-2` (`quality="high"`, 1 imagen por generación), mantuvimos exactamente el mismo Prompt y solicitamos tres tamaños distintos exclusivamente mediante el parámetro `size`, sin añadir «4K» al prompt para forzar el resultado:

| Tamaño solicitado (`size`) | Tamaño realmente entregado | Nivel de facturación / coste real | Tiempo de una llamada |
| :- | :- | :- | :- |
| `1024x1024` | **1254×1254** | **2K / ¥0.11** | 34.35 segundos |
| `2048x2048` | **2048×2048** | **2K / ¥0.11** | 31.97 segundos |
| `3840x2160` | **3840×2161** | **4K / ¥0.13** | 24.36 segundos |

**1. Imagen original entregada para la solicitud `1024x1024` (devolvió 1254×1254):**

<Frame>
  <img src="https://mintcdn.com/bettertoken-d796114e/hPGTCgdK9IohJYOA/images/gpt-image-guide/product-1k-0.png?fit=max&auto=format&n=hPGTCgdK9IohJYOA&q=85&s=975ebb5653a1a0e6847310d8448a56d9" alt="Imagen de producto de GPT Image 2: solicitud 1024×1024, entrega real 1254×1254" style={{ borderRadius: '0.5rem' }} width="1254" height="1254" data-path="images/gpt-image-guide/product-1k-0.png" />
</Frame>

**2. Imagen original entregada para la solicitud `2048x2048` (devolvió 2048×2048):**

<Frame>
  <img src="https://mintcdn.com/bettertoken-d796114e/hPGTCgdK9IohJYOA/images/gpt-image-guide/product-2k-0.png?fit=max&auto=format&n=hPGTCgdK9IohJYOA&q=85&s=a290e92bd7db319ed801c06640c7ba8d" alt="Imagen de producto de GPT Image 2: solicitud y entrega real de 2048×2048" style={{ borderRadius: '0.5rem' }} width="2048" height="2048" data-path="images/gpt-image-guide/product-2k-0.png" />
</Frame>

**3. Imagen horizontal original entregada para la solicitud `3840x2160` (devolvió 3840×2161):**

<Frame>
  <img src="https://mintcdn.com/bettertoken-d796114e/hPGTCgdK9IohJYOA/images/gpt-image-guide/product-4k-0.png?fit=max&auto=format&n=hPGTCgdK9IohJYOA&q=85&s=1e68f4d96829d9e52f9fa88aceac3c27" alt="Imagen horizontal de producto de GPT Image 2: solicitud 3840×2160, entrega real 3840×2161" style={{ borderRadius: '0.5rem' }} width="3840" height="2161" data-path="images/gpt-image-guide/product-4k-0.png" />
</Frame>

**4. Comparación de recortes a tamaño original de las zonas correspondientes de las tres imágenes (texto de la taza y detalles del material):**

<Frame>
  <GptImageComparison kind="crops" label="Comparación al 100% de los recortes de píxeles originales de las tres imágenes de producto" labels={["Solicitud 1K · Resultado 1254²","Solicitud 2K · Resultado 2048²","Solicitud 4K · Resultado 3840×2161"]} caption="Cada panel es un recorte de 480×480 píxeles originales. Las imágenes se generaron por separado y tienen composiciones distintas. La escala de la página no cambia los píxeles del archivo." />
</Frame>

**Observaciones de las pruebas**:

* **Imágenes bien acabadas**: las tres muestran los reflejos del esmalte rojo coral, el asa a la derecha, la encimera de piedra gris claro, las fibras del paño de lino beige y el texto blanco «BETTER DAY», claramente legible.
* **Diferencias entre muestras independientes**: cada generación es una muestra independiente, por lo que varían de forma natural la proporción de la taza, el grosor de las letras y la forma de doblar la tela (por ejemplo, en la imagen horizontal 4K el texto aparece en dos líneas). Por eso, los recortes solo muestran los detalles reales de cada imagen; no constituyen un experimento óptico de nitidez con composiciones estrictamente idénticas.
* **Límite de facturación visible**: aunque en la primera imagen se solicitó `1024x1024`, se entregó una imagen cuadrada de alta resolución de `1254×1254`; por ello, se cobró **como nivel 2K (¥0.11)**, igual que la segunda imagen de `2048×2048`.

### Caso B: cambio de color localizado de un producto; resultados y límites reales de Mask

Usamos como imagen original la primera imagen de producto generada en el caso A (`1254×1254`) y preparamos una máscara con canal Alpha y las mismas dimensiones [mask-mug.png](/images/gpt-image-guide/mask-mug.png): **solo se hizo transparente el polígono del cuerpo de la taza (se permite volver a dibujarlo), mientras que el asa, la pared interior del borde y el fondo se dejaron opacos (se pide conservarlos); el texto de la taza quedó dentro de la zona transparente y se indicó en el prompt que se conservara**.

<Frame>
  <GptImageComparison kind="mask" label="Imagen original, visualización superpuesta de la máscara y resultado de edición" labels={["Original","Superposición verde: área editable","Resultado real de la edición"]} caption="Reducidas solo para la comparación. El borde de la taza fuera de la máscara también cambió de color. Las salidas originales de la API se conservan por separado." />
</Frame>

<Frame>
  <img src="https://mintcdn.com/bettertoken-d796114e/hPGTCgdK9IohJYOA/images/gpt-image-guide/mask-diagram.png?fit=max&auto=format&n=hPGTCgdK9IohJYOA&q=85&s=7d648791e31a2358ee47907bc3755fae" alt="Diagrama del alcance de Mask: el negro representa la zona transparente que se puede modificar y el blanco la zona opaca que se debe conservar" style={{ borderRadius: '0.5rem' }} width="1254" height="1254" data-path="images/gpt-image-guide/mask-diagram.png" />
</Frame>

*(Nota: la imagen anterior es una representación visual en blanco y negro: el negro indica la zona que se puede modificar y el blanco, la que se debe conservar. El archivo que se subió realmente a la interfaz fue `mask-mug.png`, con canal de transparencia.)*

**Diseño de la escena (concepto en chino)**:

> Cambia únicamente el cuerpo rojo coral de la taza dentro de la zona transparente de la máscara a azul marino oscuro. Conserva el material cerámico, la iluminación y los reflejos. Mantén sin cambios las letras blancas «BETTER DAY», el asa roja, el paño de lino, la encimera, el fondo y la composición general. No añadas ni elimines ningún objeto.

**Prompt real de edición (modelo: `gpt-image-2`, `size="2048x2048"`, `quality="high"`)**:

```text theme={null}
Change only the coral-red mug body inside the transparent mask to deep navy blue. Preserve ceramic texture, lighting and reflections. Keep the white "BETTER DAY" lettering, red handle, linen cloth, tabletop, background and composition unchanged. Do not add or remove any objects. Do not change anything outside the transparent mask.
```

**Resultado real de edición entregado (2048×2048, 38.51 segundos, coste ¥0.11):**

<Frame>
  <img src="https://mintcdn.com/bettertoken-d796114e/hPGTCgdK9IohJYOA/images/gpt-image-guide/product-mask-0.png?fit=max&auto=format&n=hPGTCgdK9IohJYOA&q=85&s=1a3ba294610d624bd6a09bc7c03aa228" alt="Resultado de edición con Mask en GPT Image 2: el cuerpo de la taza se vuelve azul oscuro y el asa conserva el rojo, pero también cambia la pared interior del borde" style={{ borderRadius: '0.5rem' }} width="2048" height="2048" data-path="images/gpt-image-guide/product-mask-0.png" />
</Frame>

**Comparación detallada del desbordamiento hacia la zona protegida:**

<Frame>
  <GptImageComparison kind="boundary" label="Detalle ampliado de la zona protegida por Mask: el borde y la pared interior no estaban en la zona transparente, pero también cambiaron a azul" labels={["Original: borde y pared interior rojos","Tras editar: el borde y la pared interior también son azules"]} caption="Las áreas correspondientes se amplían o escalan para mostrarlas, no para una comparación píxel a píxel. Ambas están fuera de la máscara transparente." />
</Frame>

**Contraejemplo: muestra de cambio de color de dos círculos en las pruebas de regresión (aceptar Mask ≠ aislamiento preciso)**

<Frame>
  <GptImageComparison kind="circles" label="Contraejemplo de dos círculos en la prueba de regresión: solo se marcó el círculo izquierdo como transparente para cambiarlo, pero también cambió el círculo derecho de la zona protegida" labels={["Original: dos círculos rojos","Verde: solo se permite editar a la izquierda","Resultado: ambos círculos se volvieron azules"]} caption="Muestras existentes de BetterToken API. El objeto protegido de la derecha también cambió. Las imágenes se reducen solo para la presentación." />
</Frame>

**Observaciones de las pruebas (límites comunicados con transparencia)**:

* **Se logró el cambio de color principal**: el exterior del cuerpo de la taza pasó correctamente a azul marino oscuro y conservó el brillo cerámico; **se mantuvieron el asa roja fuera de la máscara, el paño de lino de la izquierda y el fondo, y el texto «BETTER DAY» dentro de la máscara siguió siendo legible**.
* **El límite estricto de Mask no se superó (hubo filtración fuera de la zona)**: al observar el borde y la pared interior de la taza, se ve que **parte del color rojo coral, originalmente dentro de la zona protegida opaca, también se cambió a azul oscuro**. En la prueba geométrica más extrema de «dos círculos», también cambió el círculo derecho que no estaba enmascarado.
* **Recomendación de uso**: al subir una imagen de referencia y una Mask, asegúrate de que ambas tengan el mismo tamaño de lienzo (la zona que se debe modificar ha de ser transparente y la que se conserva, opaca), e indica en el Prompt tanto «qué cambiar» como «qué conservar». En imágenes comerciales industriales con logotipos de marca, texto pequeño en el envase o requisitos estrictos para los bordes, **amplía la imagen después de generarla e inspecciona los límites de la zona protegida**.

## 7. Precios y coste real de uso: ¿cuánto se cobra al final?

BetterToken mantiene precios transparentes. Estos son los precios públicos del **19 de octubre de 2026** (CNY se aplica a las cuentas empresariales en renminbi y USD a las cuentas normales en dólares; son precios independientes y no se convierten con el tipo de cambio en tiempo real):

| Nombre del modelo | Precio 1K / imagen | Precio 2K / imagen | Precio 4K / imagen |
| :- | :- | :- | :- |
| **`gpt-image-2`** (CNY / USD) | ¥0.035 / \$0.0062 | ¥0.11 / \$0.0194 | ¥0.13 / \$0.0229 |
| **`gpt-image-2.5-flare`** (CNY / USD) | ¥0.035 / \$0.0062 | ¥0.15 / \$0.0265 | ¥0.18 / \$0.0318 |
| **`gpt-image-2.5-sunburst`** (CNY / USD) | ¥0.035 / \$0.0062 | ¥0.15 / \$0.0265 | ¥0.18 / \$0.0318 |

Según los precios públicos anteriores, el coste de referencia para 100 llamadas es el siguiente, suponiendo que las 100 imágenes entregadas correspondan realmente al nivel de facturación indicado (estimación aritmética):

| Nombre del modelo | Coste de 100 imágenes 1K | Coste de 100 imágenes 2K | Coste de 100 imágenes 4K |
| :- | :- | :- | :- |
| **`gpt-image-2`** (CNY / USD) | ¥3.50 / \$0.62 | ¥11.00 / \$1.94 | ¥13.00 / \$2.29 |
| **`flare` o `sunburst`** (CNY / USD) | ¥3.50 / \$0.62 | ¥15.00 / \$2.65 | ¥18.00 / \$3.18 |

> 💡 **Punto clave para planificar el presupuesto: calcula el coste según el «nivel realmente entregado», no según los «parámetros solicitados».**
>
> Como muestran las pruebas anteriores, hoy algunas solicitudes a `flare`, `sunburst` o `gpt-image-2` con `1024x1024` (1K) entregaron imágenes de `1254×1254`. En ese caso, el sistema las clasifica según el resultado real como **2K** (es decir, cobra ¥0.15 o ¥0.11, no el precio 1K de ¥0.035). Si las 100 solicitudes de `1024x1024` a `flare` devolvieran `1254×1254`, al precio actual el coste de las 100 imágenes sería **¥15.00 (estimación aritmética)**.
>
> Además, la lógica de clasificación combina el tamaño objetivo con un umbral de desviación razonable (por ejemplo, `3840×2159` se clasifica normalmente como 4K y `1536×1024` como 1K). No recalcules el coste en tu aplicación con una regla simplista como «si el lado más largo supera 1024»; **la liquidación siempre se determina según el campo `bettertoken_image_billing` del cuerpo de la respuesta**.

### ¿Por qué no basta con fijarse en el «precio bajo por imagen»?

Al comparar los costes de las API de imágenes de distintas plataformas, te conviene hacer bien estas tres cuentas:

1. **El precio solo es comparable si el tamaño real de la respuesta alcanza el objetivo**: una solicitud que anuncia «compatibilidad con 4K a un precio muy bajo», pero solo devuelve una imagen reducida de 1024, no puede utilizarse en un entorno de producción que necesite imágenes de alta resolución y no debe compararse como un precio 4K válido.
2. **Incluye en el total los fallos y el coste de volver a generar**: las pruebas de parámetros no válidos de esta ronda no tuvieron coste; si una imagen se entregó correctamente pero no satisface tus necesidades, volver a enviarla es una nueva solicitud y debe presupuestarse por separado. Las 4 imágenes de los casos de producto y Mask de esta guía (3 generadas + 1 editada) se entregaron con una solicitud cada una. La muestra de Mask tuvo el cambio de color fuera de la zona explicado arriba. Sus precios individuales fueron ¥0.11, ¥0.11, ¥0.13 y ¥0.11, **con un coste real total de solo ¥0.46 por las 4 imágenes**; la factura coincidió exactamente con los cargos de la cuenta. Si una ruta inestable o parámetros incompatibles te obligan a repetir las generaciones, el coste real de obtener un recurso utilizable puede aumentar aunque el precio anunciado por imagen sea bajo.
3. **Reduce el coste oculto de adaptación para el equipo de desarrollo**: BetterToken unifica la normalización de parámetros, enruta según las capacidades y devuelve en tiempo real los píxeles reales y los campos de facturación, reduciendo el trabajo de adaptar cada servicio y organizar por separado las dimensiones y los costes.

## 8. Ejemplos de llamadas listos para copiar

Guarda tu BetterToken API Key en la variable de entorno `BETTERTOKEN_API_KEY` y podrás copiar directamente los siguientes comandos para empezar a realizar llamadas.

### Ejemplo 1: solicitud JSON para generar una imagen de producto de alta resolución (`POST /v1/images/generations`)

El ejemplo llama a `gpt-image-2` para generar una imagen de producto de alta resolución de `2048x2048` (`model` se puede sustituir directamente por `gpt-image-2.5-flare` o `gpt-image-2.5-sunburst`):

```bash theme={null}
curl https://bettertoken.ai/v1/images/generations -o response.json \
  -H "Authorization: Bearer $BETTERTOKEN_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @- <<'JSON'
{
  "model": "gpt-image-2",
  "prompt": "Photorealistic ecommerce studio photograph. A coral-red ceramic mug with a handle on the right sits on a pale gray stone tabletop, with a folded beige linen cloth to its left. The mug reads \"BETTER DAY\" in clear white lettering. Soft directional light from upper left, subtle glaze reflections, visible linen fibers and natural contact shadows. Entire mug in frame, centered composition, simple neutral background. No other objects, no watermark, no additional text.",
  "size": "2048x2048",
  "quality": "high",
  "n": 1,
  "response_format": "b64_json",
  "output_format": "png"
}
JSON
```

* **Nota sobre las dimensiones**: para una imagen horizontal 4K, cambia `"size"` por `"3840x2160"` (no uses `"4096x4096"`). Las dimensiones válidas actuales deben cumplir lo siguiente: ancho y alto múltiplos de 16, lado más largo no superior a 3840, relación entre lado largo y corto no superior a 3:1 y un total de entre `655,360` y `8,294,400` píxeles.
* **Nota sobre la identificación del formato de archivo**: aunque la solicitud especifique `"output_format": "png"`, algunos nodos subyacentes pueden devolver contenido binario en formato JPEG. Al guardar o procesar la imagen, conviene identificar el formato real según la cabecera del archivo (Magic Bytes) y no fijar la extensión por adelantado.

### Ejemplo 2: edición localizada con imagen de referencia y Mask en Multipart (`POST /v1/images/edits`)

Prepara la imagen original `product-1k-0.png` y la máscara transparente del mismo tamaño `mask-mug.png` (si solo necesitas editar una imagen de referencia normal, elimina directamente la línea `-F "mask=..."`):

```bash theme={null}
curl https://bettertoken.ai/v1/images/edits -o response.json \
  -H "Authorization: Bearer $BETTERTOKEN_API_KEY" \
  -F "model=gpt-image-2" \
  -F "image=@product-1k-0.png;type=image/png" \
  -F "mask=@mask-mug.png;type=image/png" \
  -F 'prompt=Change only the coral-red mug body inside the transparent mask to deep navy blue. Preserve ceramic texture, lighting and reflections. Keep the white "BETTER DAY" lettering, red handle, linen cloth, tabletop, background and composition unchanged. Do not add or remove any objects. Do not change anything outside the transparent mask.' \
  -F "size=2048x2048" \
  -F "quality=high" \
  -F "n=1" \
  -F "response_format=b64_json"
```

### Ejemplo 3: lectura de los píxeles realmente entregados y los datos de facturación (estructura de respuesta y código de análisis)

Además de `data[].b64_json`, el cuerpo de respuesta de BetterToken incluye el nodo del campo ampliado `bettertoken_image_billing`:

```json theme={null}
{
  "created": 1792398084,
  "data": [
    {
      "b64_json": "iVBORw0KGgoAAAANSUhEUgAA..."
    }
  ],
  "bettertoken_image_billing": {
    "currency": "CNY",
    "settled_amount": "0.11",
    "outputs": [
      {
        "index": 0,
        "width": 2048,
        "height": 2048,
        "billing_resolution": "2K",
        "currency": "CNY",
        "amount": "0.11"
      }
    ]
  }
}
```

Puedes usar el siguiente fragmento de código Python para completar en un solo paso la **decodificación de la imagen, la identificación del formato real, la lectura de las dimensiones y la verificación de la factura**:

```python theme={null}
import base64
import io
import json
from pathlib import Path
from PIL import Image  # 需要 Pillow

# 将 API 的 JSON 响应保存为 response.json 后执行。
resp_json = json.loads(Path("response.json").read_text())
if "error" in resp_json:
    raise RuntimeError(resp_json["error"])

billing = resp_json["bettertoken_image_billing"]
outputs = {item["index"]: item for item in billing["outputs"]}
for index, item in enumerate(resp_json["data"]):
    img_bytes = base64.b64decode(item["b64_json"], validate=True)
    with Image.open(io.BytesIO(img_bytes)) as image:
        image.load()
        width, height = image.size
        ext = {"PNG": "png", "JPEG": "jpg", "WEBP": "webp"}.get(image.format)
        if ext is None:
            raise ValueError(f"未处理的图片格式：{image.format}")
    Path(f"output_{index}.{ext}").write_bytes(img_bytes)
    info = outputs[index]
    print(f"图片 {index}：原图 {width}×{height}；计费档位 {info['billing_resolution']}")
    print(f"单张费用：{info['amount']} {info['currency']}")
    if (width, height) != (info["width"], info["height"]):
        print("图片像素与响应尺寸不一致，请保留结果并联系支持。")
print(f"本次结算：{billing['settled_amount']} {billing['currency']}")

```

***

**Referencias**:

* [Documentación oficial de OpenAI: guía para escribir prompts de imágenes (Image Prompting Guide)](https://developers.openai.com/api/docs/guides/image-prompting)
* [OpenAI Cookbook: ejemplo de generación y edición de imágenes con alta fidelidad de entrada](https://developers.openai.com/cookbook/examples/generate_images_with_high_input_fidelity)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.