> This page is for Gateway.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.merge.dev/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.merge.dev/_mcp/server.

# Image editing

> Edit images on Gateway with POST /v1/images/edits: the multipart request, reference images and masks, upload limits, errors, and image-input billing.

`POST /v1/images/edits` takes one or more reference images plus a prompt and returns a new image, to change or combine pictures you already have. The request is `multipart/form-data`; the response matches [image generation](/merge-gateway/capabilities/multimodal/image-generation): base64 in `data[].b64_json`, plus `usage` and `cost`.

**`cURL`**

```bash title="cURL"
curl https://api-gateway.merge.dev/v1/images/edits \
  -H "Authorization: Bearer $MERGE_GATEWAY_API_KEY" \
  -F "model=openai/gpt-image-2" \
  -F "prompt=Recolor the mug blue and change nothing else" \
  -F "image=@product-shot.png"
```

**`OpenAI SDK`**

```python title="OpenAI SDK"
import base64, os
from openai import OpenAI

# Image endpoints live at /v1, not /v1/openai
client = OpenAI(api_key=os.environ["MERGE_GATEWAY_API_KEY"], base_url="https://api-gateway.merge.dev/v1")

result = client.images.edit(
    model="openai/gpt-image-2",
    image=[open("product-shot.png", "rb"), open("logo.png", "rb")],
    prompt="Place the logo on the mug",
)
with open("edited.png", "wb") as f:
    f.write(base64.b64decode(result.data[0].b64_json))
```

An edit needs a route listing `image` in both `capabilities.input` and `capabilities.output`; filter by both in the [model catalog](/merge-gateway/models/catalog).

## Reference

| Field                                                                                                       | Notes                                                                                 |
| ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| `model`                                                                                                     | Required. A canonical model ID, since `@alias/...` returns `400 alias_not_supported`. |
| `prompt`                                                                                                    | Required                                                                              |
| `image`                                                                                                     | Required. 1 to 16 PNG, JPEG, or WebP files. Repeat the field, or use `image[]`.       |
| `mask`                                                                                                      | PNG with alpha. Transparent areas mark where the first image is edited.               |
| `n`                                                                                                         | 1 to 10                                                                               |
| `output_compression`                                                                                        | 0 to 100                                                                              |
| `size`, `quality`, `background`, `input_fidelity`, `output_format`, `moderation`, `response_format`, `user` | Forwarded to the vendor, which sets the accepted values                               |
| `vendor`                                                                                                    | Pin the execution vendor                                                              |
| `customer`                                                                                                  | Customer UUID to scope the key, budget, and usage to                                  |

| Error                         | Cause                                   |
| ----------------------------- | --------------------------------------- |
| `400 image_required`          | No `image` file                         |
| `400 image_empty`             | An uploaded file is empty               |
| `400 too_many_images`         | More than 16 images                     |
| `400 image_too_large`         | A file over 50 MB                       |
| `400 uploads_too_large`       | Images and mask over 100 MB combined    |
| `400 image_input_unsupported` | The route can't take and produce images |
| `400 stream_unsupported`      | `stream=true`                           |
| `400 invalid_customer`        | `customer` isn't a UUID                 |

Reference images bill as image-input tokens at `pricing.input_image_per_million`, the prompt at the text rate, and the output at the image-output rate. `usage.input_tokens_details` splits `image_tokens` from `text_tokens`.

## Next steps

#### [Image generation](/merge-gateway/capabilities/multimodal/image-generation)

Generate images from a text prompt

#### [Video generation](/merge-gateway/capabilities/multimodal/video-generation)

Video from text and media inputs