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

# Edit an image

> Edit an existing image, optionally masked, with GPT image models.

Edits take one or more source images and a prompt describing the change. With a mask, only the transparent region is repainted; without one, the model rewrites the whole frame guided by the references.

Two request encodings work, and PipeLLM passes both through:

* `multipart/form-data` with the image bytes uploaded directly. This is what the OpenAI SDK sends.
* `application/json` with an `images` array of `file_id` or `image_url` entries, up to 16 references.

<ParamField body="image" type="file | array" required>
  Source image, or several. Send file parts under `image[]` in multipart, or the JSON `images` array. PNG, JPEG, or WebP.
</ParamField>

<ParamField body="prompt" type="string" required>
  What the edited image should show. Up to 32,000 characters on GPT image models.
</ParamField>

<ParamField body="model" type="string">
  Image model ID, for example `gpt-image-2.5-sunburst`.
</ParamField>

<ParamField body="mask" type="file">
  A PNG whose transparent pixels mark the region to repaint. Must match the source dimensions. Omit it to let the model edit the whole image.
</ParamField>

<ParamField body="n" type="integer" default="1">
  Number of images to return, 1–10.
</ParamField>

<ParamField body="size" type="string" default="auto">
  `auto`, `1024x1024`, `1536x1024`, `1024x1536`, or a custom `WIDTHxHEIGHT` divisible by 16.
</ParamField>

<ParamField body="quality" type="string" default="auto">
  `low`, `medium`, `high`, or `auto`. The `gpt-image-2.5` variants add `xhigh` and `max`.
</ParamField>

<ParamField body="input_fidelity" type="string" default="low">
  `high` preserves faces, logos, and fine texture from the source more closely, at a higher input-token cost. `low` gives the model more freedom.
</ParamField>

<ParamField body="background" type="string" default="auto">
  `transparent`, `opaque`, or `auto`. Transparent requires `png` or `webp` output.
</ParamField>

<ParamField body="output_format" type="string" default="png">
  `png`, `jpeg`, or `webp`.
</ParamField>

<ParamField body="output_compression" type="integer" default="100">
  Compression level 0–100, for `jpeg` and `webp` only.
</ParamField>

<ParamField body="user" type="string">
  Stable end-user identifier.
</ParamField>

<RequestExample>
  ```bash cURL theme={"dark"}
  curl https://api.pipellm.ai/v1/images/edits \
    -H "Authorization: Bearer $PIPELLM_API_KEY" \
    -F model="gpt-image-2.5-sunburst" \
    -F image="@room.png" \
    -F mask="@room-mask.png" \
    -F prompt="Replace the sofa with a green velvet one" \
    -F size="1024x1024"
  ```

  ```python Python theme={"dark"}
  import base64
  import os
  from openai import OpenAI

  client = OpenAI(
      api_key=os.environ["PIPELLM_API_KEY"],
      base_url="https://api.pipellm.ai/v1",
  )

  result = client.images.edit(
      model="gpt-image-2.5-sunburst",
      image=open("room.png", "rb"),
      mask=open("room-mask.png", "rb"),
      prompt="Replace the sofa with a green velvet one",
      size="1024x1024",
  )

  with open("room-edited.png", "wb") as f:
      f.write(base64.b64decode(result.data[0].b64_json))
  ```

  ```typescript TypeScript theme={"dark"}
  import fs from "node:fs";
  import OpenAI, { toFile } from "openai";

  const client = new OpenAI({
    apiKey: process.env.PIPELLM_API_KEY,
    baseURL: "https://api.pipellm.ai/v1",
  });

  const result = await client.images.edit({
    model: "gpt-image-2.5-sunburst",
    image: await toFile(fs.createReadStream("room.png"), "room.png"),
    mask: await toFile(fs.createReadStream("room-mask.png"), "room-mask.png"),
    prompt: "Replace the sofa with a green velvet one",
    size: "1024x1024",
  });

  fs.writeFileSync("room-edited.png", Buffer.from(result.data[0].b64_json, "base64"));
  ```
</RequestExample>

<ResponseExample>
  ```json theme={"dark"}
  {
    "created": 1726400000,
    "size": "1024x1024",
    "quality": "medium",
    "output_format": "png",
    "background": "opaque",
    "data": [
      { "b64_json": "iVBORw0KGgoAAAANSUhEUgAA..." }
    ],
    "usage": {
      "input_tokens": 342,
      "input_tokens_details": { "text_tokens": 14, "image_tokens": 328 },
      "output_tokens": 1056
    }
  }
  ```
</ResponseExample>

The response shape matches [Create an image](/api-reference/image/generations): the bytes come back base64-encoded in `data[].b64_json`, and `usage.input_tokens_details.image_tokens` covers the source images you uploaded.

## Combining references

With several source images the model composes across them — a product plus a scene, a person plus an outfit. Order matters: describe the references in the prompt in the order you send them, for example "dress the person from the first reference in the outfit from the second".

Masks apply to the first image only.

## Long requests

Edits use the same keep-alive behavior as generation: after 90 seconds of upstream silence the gateway writes a whitespace padding chunk every 30 seconds ahead of the JSON body. See [Long requests](/api-reference/image/generations#long-requests).

## Errors

Same envelope as [Errors](/api-reference/errors).

<AccordionGroup>
  <Accordion title="400 invalid_request_error">
    Mask dimensions not matching the source, an unreadable upload, or a `size` the model rejects.

    ```json theme={"dark"}
    {
      "error": {
        "type": "invalid_request_error",
        "code": "400",
        "message": "The mask must have the same dimensions as the image"
      }
    }
    ```
  </Accordion>

  <Accordion title="401 authentication_error">
    ```json theme={"dark"}
    {
      "error": {
        "type": "authentication_error",
        "code": "401",
        "message": "Incorrect API key provided. Please visit https://console.pipellm.ai/account/api-keys to find your API key."
      }
    }
    ```
  </Accordion>

  <Accordion title="413 invalid_request_error">
    The upload exceeded the accepted body size. Downscale the source before sending.
  </Accordion>

  <Accordion title="429 rate_limit_error">
    See [Rate Limits](/api-reference/rate-limits).
  </Accordion>
</AccordionGroup>


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