---
title: Image Editing API: GPT Image Models
description: "Build a GPT Image editing workflow with reference images, request examples, cost measurement and output validation."
url: https://apitoken.sale/docs/learn/image-editing-api-guide
language: en
---

# Edit images with GPT Image 2, Flare or Sunburst

GPT Image models accept up to five PNG, JPEG or WebP references on the Images edit route. Use the same key and prepaid balance as generation, then validate each result before publication.

## Edit reference images with GPT Image

GPT Image 2, GPT Image 2.5 Flare and GPT Image 2.5 Sunburst use the same OpenAI Images endpoints, key and prepaid balance. Flare is the faster everyday option; Sunburst targets more precise edits. Compare the models on your own accepted outputs. All three use the same published token rates.

POST /v1/images/edits accepts one to five PNG, JPEG or WebP reference files, each up to 50 MB, as image or image[]. Use the same model IDs as generation. The multipart mask field is ignored; use the Responses image_generation tool for region inpainting. Check geometry, labels and product identity before accepting an edit.

## The GPT Image 2 edit: PNG, JPEG or WebP in, one base64 PNG out

The edits endpoint is multipart form data: model, prompt and one image field per reference. The published profile is background opaque or transparent, quality low, and size as a proportion (auto, 1024x1024/1:1, 1536x1024/3:2, 1024x1536/2:3, 4:3, 16:9, 9:16). The response is a single JSON document whose data array holds one base64-encoded PNG. 2K/4K size values steer proportions; they do not guarantee that pixel resolution.

```
curl https://router.apitoken.sale/v1/images/edits \
  -H "Authorization: Bearer $APITOKEN_API_KEY" \
  -F "model=gpt-image-2" \
  -F "prompt=Replace only the background with a neutral studio backdrop; keep the product untouched" \
  -F "image=@reference.png;type=image/png" \
  -F "background=opaque" \
  -F "quality=low" \
  -F "size=auto"
```

> Repeat the field name image for each reference, or send image[]. Multipart mask is ignored on /v1/images/edits; inpaint uses Responses input_image_mask.

```
// Response (abridged): decode data[0].b64_json into a PNG file.
{
  "data": [
    { "b64_json": "<BASE64 PNG>" }
  ]
}
```

Decoding the payload does not finish the request. Store the request ID and the terminal usage next to the source and result files: PNG byte size is not the billing formula, the terminal usage event is the billing authority, and it is what the dashboard charge reconciles against.

## Region inpaint: Responses mask, not Images mask

A multipart mask field on POST /v1/images/edits is ignored. That OpenAI Images shape is not available on this ChatGPT pool. To change only part of a picture — or to run hosted image_generation from a GPT text model — call POST /v1/responses (Chat Completions maps the same tool): put the source PNG in input as input_image, and add tools: [{type:"image_generation", …}]. For a mask, set input_image_mask.image_url to a data:image/png;base64,… string. The mask must match the source size. Transparent pixels are the region to edit; opaque pixels stay. Responses also forwards output_format jpeg/webp and partial_images 1..=3 (SSE response.image_generation_call.partial_image); background=transparent is rewritten to opaque and input_fidelity is dropped. file_id masks fail — there is no Files API here — so official samples that files.create a mask will not run. Billing follows image tokens; the mask is not a second reference image. Separate POST /v1/images/* routes still return only non-streaming PNG.

```
import base64, os
from pathlib import Path
from openai import OpenAI
client = OpenAI(
    api_key=os.environ["APITOKEN_API_KEY"],
    base_url="https://router.apitoken.sale/v1",
)
def png_url(path):
    return "data:image/png;base64," + base64.b64encode(Path(path).read_bytes()).decode()
response = client.responses.create(
    model="gpt-5.6-sol",
    input=[{
        "role": "user",
        "content": [
            {"type": "input_text", "text": "Change only the masked region."},
            {"type": "input_image", "image_url": png_url("photo.png")},
        ],
    }],
    tools=[{
        "type": "image_generation",
        "output_format": "webp",
        "partial_images": 2,
        "input_image_mask": {"image_url": png_url("mask.png")},
    }],
)
```

## Run edits as a validated pipeline

1. Normalize and inspect every reference server-side: decode the file, confirm a supported MIME type and reject empty or oversized payloads before any paid call.
2. Write an edit brief that separates immutable traits — product geometry, logo, label text — from the single named change; one change per request keeps failures diagnosable.
3. Decode each result from data[].b64_json and validate the returned file before storing it.
4. Dispatch one bounded candidate per source asset; do not fan out paid variants before the first output passes review.
5. Validate the delivered image — format, plausible dimensions, product identity and the absence of prohibited changes — before anything downstream sees it.
6. Persist request ID, terminal usage, prompt version, source and result together; that record is both your rollback path and your cost attribution.

## Budget from measured token usage

| Usage per 1M tokens | Official | Regular B2C · 50% off |
| --- | --- | --- |
| Text input | $5 | $2.50 |
| Cached text input | $1.25 | $0.625 |
| Image input | $8 | $4 |
| Cached image input | $2 | $1 |
| Image output | $30 | $15 |

For example, an edit with 900 fresh text-input tokens, 1,200 fresh image-input tokens and 4,000 image-output tokens costs $0.1341 officially, or $0.06705 at the regular B2C rate. These token counts are an example, not a promise for each picture. Use the final usage and matching request charge for your own measurements.

For a catalog or batch, divide all settled charges by the number of accepted assets. Include paid outputs that failed review. GPT Image has no free countTokens estimator: measure a small funded sample and set a spending limit before starting the queue.

## Cost and retry discipline

1. Choose a GPT Image model and a small set of representative prompts and references.
2. Set a spending limit and use n=1, quality=low and size=auto for the sample.
3. Record final usage and the charge for every request, including rejected results.
4. Divide settled charges by accepted images and use that measured cost for the batch budget.

## Frequently asked questions

### Do edits cost more than prompt-only generation?

They add billable image input, so an otherwise comparable edit normally has more input cost. It can still be cheaper per accepted asset when references raise the acceptance rate and remove retries — measure settled cost per accepted asset, not per request.

### Is it safe to retry an edit after a timeout?

Only when you can prove the prior attempt was not accepted. An ambiguous timeout may hide completed provider work; preserve the request ID and reconcile before another paid attempt, otherwise the retry is a second paid render of the same job.

### How can I test the edit routes cheaply?

Start with one reference and n=1, quality=low, size=auto. Check the returned dimensions and final usage before increasing the workload.

### Which reference images can I send?

Send one to five PNG, JPEG or WebP files, each no larger than 50 MB, to /v1/images/edits. Use image or image[] fields.

---
Get a key: https://apitoken.sale/register
More guides: https://apitoken.sale/docs/learn
