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

> ## Agent Instructions
> Authenticate every request with your API key in the `X-API-Key` header or `Authorization: Bearer`. Keys start with `sk-nunchux-`.
> Image generation is synchronous: the image is in the response.
> Video generation is asynchronous: submit the job, poll its task until it reaches a terminal status, then download the output promptly, because output URLs expire.

# Image-to-image

> Edit an image with a text prompt with a Nunchux Optimized model. The edited image is in the response.

# Image-to-image

Send a source image and a text prompt that describes the edit. The response contains the edited image. The request is synchronous. There is no task to poll.

## Models

| Model | Model ID | Use it for |
| - | - | - |
| FLUX.2 Klein 9B Edit | `nunchux-flux.2-klein-9b-edit` | Edits that must keep the identity of the subject. |
| FLUX.2 Klein 4B Edit | `nunchux-flux.2-klein-4b-edit` | The fastest edits. High-volume edit passes. The output follows the input image. |
| Qwen Image Edit 2511 Lightning | `nunchux-qwen-image-edit-2511` | Targeted edits: swap elements, change the style, edit text in the image. The recommended editing model. |

See [Choosing a model](/nunchux-optimized/overview#choosing-a-model) for a comparison, and [Performance tiers](/performance-tiers) for the tiers that each model serves.

## Endpoint

```text theme={"system"}
POST https://api.nunchux.ai/v1/images/edits
```

## Request

Every request must include your API key and a JSON content type. See [Authentication](/authentication).

<ParamField header="X-API-Key" type="string" required>
  Your API key.
</ParamField>

<ParamField header="Content-Type" type="string" required>
  Must be `application/json`.
</ParamField>

<ParamField body="model" type="string" required>
  The model that edits the image.

  Options: `nunchux-flux.2-klein-4b-edit`, `nunchux-flux.2-klein-9b-edit`, `nunchux-qwen-image-edit-2511`
</ParamField>

<ParamField body="url" type="string" required>
  The source image, as a data URI (for example `data:image/png;base64,...`) or as a public URL. Supported formats: PNG, JPEG, WebP. Maximum size: 10 MB. Each side must be at least 64 px. The aspect ratio must be no more extreme than 8:1 in either orientation. A remote URL must resolve to a public host. Nunchux does not follow redirects.
</ParamField>

<ParamField body="prompt" type="string" required>
  A text description of the edit. Say what to change, add or remove.
</ParamField>

<ParamField body="tier" type="string" default="radical_speed">
  The balance of speed and cost. See [Performance tiers](/performance-tiers).

  Options: `radical_speed`, `radical_value`
</ParamField>

<ParamField body="width" type="integer" required>
  Output width in pixels. Send it together with `height`. Range: 1 to 8192.
</ParamField>

<ParamField body="height" type="integer" required>
  Output height in pixels. Send it together with `width`. Range: 1 to 8192.
</ParamField>

<ParamField body="n" type="integer" default={1}>
  The number of images to generate. Only 1 is supported.
</ParamField>

<ParamField body="response_format" type="string" default="b64_json">
  The format of the returned image.

  Options: `url`, `b64_json`

  In both formats, Nunchux keeps the generated image for 7 days, so that it appears in your request history. Then Nunchux deletes it.
</ParamField>

<ParamField body="seed" type="integer">
  The random seed. The same seed with the same parameters gives the same result.
</ParamField>

<Note>
  Dimensions

  * Send `width` and `height` together. A request with only one of them returns a 400.
  * Every image-to-image model is priced per megapixel today and charges from the output area. A request with no dimensions returns a 400. The API does not use the source image size or a default size.
  * Both values must be integers. The string `"1024"` is rejected, not converted.
  * The source image is a reference, not a canvas. The model does not crop or stretch it to `width` and `height`. When the source ratio is different from the output ratio, the model re-frames the content.
  * Smaller source images process faster. Larger output images take longer to generate.
</Note>

A minimal request body:

```json theme={"system"}
{
  "model": "nunchux-qwen-image-edit-2511",
  "url": "https://example.com/example.jpg",
  "prompt": "Transform into a watercolor painting",
  "tier": "radical_speed",
  "width": 1024,
  "height": 1024,
  "response_format": "b64_json"
}
```

## Response

The response is JSON. The `data` array contains the edited image, as base64 data or as a URL.

<ResponseField name="created" type="integer" required>
  The Unix timestamp of the generation.
</ResponseField>

<ResponseField name="data" type="array" required>
  The generated items.

  <Expandable title="Item properties">
    <ResponseField name="url" type="string">
      The URL of the image. Returned when `response_format` is `url`.
    </ResponseField>

    <ResponseField name="b64_json" type="string">
      The image as base64 data. Returned when `response_format` is `b64_json`.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="model" type="string" required>
  The model that edited the image.
</ResponseField>

```json Base64 format theme={"system"}
{
  "created": 1234567890,
  "data": [
    {
      "b64_json": "iVBORw0KGgoAAAANSUhEUgAABAAAAAQACAYAAAB/HSuDAAAACXBIWXMAAA7EAAAOxAGVKw4b..."
    }
  ],
  "model": "nunchux-qwen-image-edit-2511"
}
```

```json URL format theme={"system"}
{
  "created": 1234567890,
  "data": [
    {
      "url": "https://example.com/edited-image.png"
    }
  ],
  "model": "nunchux-qwen-image-edit-2511"
}
```

To save a base64 result from cURL, add this pipe to the command:

```bash theme={"system"}
# Replace output.jpg with the file name that you want.
| jq -r '.data[0].b64_json // error(.error.message // .detail // tostring)' | base64 -d > output.jpg
```

## Example

<CodeGroup>
  ```bash cURL theme={"system"}
  # The media URL below is a placeholder. Point it at your own publicly
  # reachable file before running this.
  curl -X POST https://api.nunchux.ai/v1/images/edits \
    -H "Content-Type: application/json" \
    -H "X-API-Key: $NUNCHUX_API_KEY" \
    -d '{
      "model": "nunchux-qwen-image-edit-2511",
      "url": "https://example.com/example.jpg",
      "prompt": "Transform into a watercolor painting",
      "tier": "radical_speed",
      "width": 1024,
      "height": 1024,
      "response_format": "b64_json"
    }' | jq -r '.data[0].b64_json // error(.error.message // .detail // tostring)' | base64 -d > output.jpg
  ```

  ```python Python theme={"system"}
  # The media URL below is a placeholder. Point it at your own publicly
  # reachable file before running this.
  import os
  import base64
  import requests

  response = requests.post(
      "https://api.nunchux.ai/v1/images/edits",
      headers={
          "Content-Type": "application/json",
          "X-API-Key": os.environ["NUNCHUX_API_KEY"],
      },
      json={
          "model": "nunchux-qwen-image-edit-2511",
          "url": "https://example.com/example.jpg",
          "prompt": "Transform into a watercolor painting",
          "tier": "radical_speed",
          "width": 1024,
          "height": 1024,
      },
  )

  # Decode the base64 image and save it. Change output.jpg to any file name.
  image_b64 = response.json()["data"][0]["b64_json"]
  with open("output.jpg", "wb") as f:
      f.write(base64.b64decode(image_b64))
  ```

  ```javascript JavaScript theme={"system"}
  // The media URL below is a placeholder. Point it at your own publicly
  // reachable file before running this.
  import { writeFile } from "node:fs/promises";

  const response = await fetch("https://api.nunchux.ai/v1/images/edits", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-API-Key": process.env.NUNCHUX_API_KEY,
    },
    body: JSON.stringify({
      model: "nunchux-qwen-image-edit-2511",
      url: "https://example.com/example.jpg",
      prompt: "Transform into a watercolor painting",
      tier: "radical_speed",
      width: 1024,
      height: 1024,
    }),
  });
  const data = await response.json();

  // Decode the base64 image and save it. Change output.jpg to any file name.
  await writeFile("output.jpg", Buffer.from(data.data[0].b64_json, "base64"));
  ```

  ```python Python (OpenAI) theme={"system"}
  # Replace photo.jpg with the path to your source image.
  import os
  import requests

  from openai import OpenAI

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

  response = client.images.edit(
      model="nunchux-qwen-image-edit-2511",
      image=open("photo.jpg", "rb"),
      prompt="Transform into a watercolor painting",
      response_format="url",
      extra_body={"width": 1024, "height": 1024},
  )

  # This tab returns a URL. Download it and save it. Change output.jpg to any file name.
  image_url = response.data[0].url
  with open("output.jpg", "wb") as f:
      f.write(requests.get(image_url).content)
  ```
</CodeGroup>

## Tips

* Say exactly what to change, add or remove. The models can follow instructions with more than one change.
* Use Qwen Image Edit 2511 when the edit must keep the identity of the subject, or when it changes text in the image.
* Use FLUX.2 Klein 4B Edit for fast, high-volume edit passes.
* Use `radical_speed` when response time is important. Use `radical_value` for large batches where cost per image is more important.
* Send smaller source images for faster processing.

## Errors and limits

| Status | Code | Cause |
| - | - | - |
| 400 | none | A required field is missing, the model ID is not valid, or a value is not valid. The body is a plain `detail` string. |
| 400 | `engine_error` | The model cannot render the request, or the source image is rejected: the URL cannot be fetched, the data URI cannot be decoded, or the image is outside the size and ratio limits. |
| 403 | `model_not_available` | Your account does not have access to this model. |
| 504 | `engine_timeout` | Nunchux could not fetch the source image in time. Make sure that the URL is reachable and fast, or send the image as a data URI. |

<Note>
  Refused requests

  * Nunchux charges only after a successful generation. A refused request is never billed.
  * Do not branch on a dimension-specific code. A refusal always carries the `engine_error` code.
</Note>

For authentication, credit and rate-limit errors, see [Error codes](/errors). Every request counts toward the requests-per-minute cap of your plan. See [Rate limits](/rate-limits).


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