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

# Qwen Image Edit Max

> Multi-image editing, up to 3 references

<CardGroup cols={1}>
  <Card title="Try Qwen Image Edit Max in the Workbench" icon="flask" href="https://www.oxen.ai/ai/workbench?model=qwen-image-edit-max">
    Run this model interactively, tune parameters, and compare outputs.
  </Card>
</CardGroup>

**Model ID:** `qwen-image-edit-max`

Qwen Image Edit Max is Alibaba's closed image editing model. It follows natural-language instructions to modify, restyle, or combine up to three input images while preserving the identity of people and products.

The output keeps the aspect ratio of the last input image by default, with total pixels close to 1024x1024, and any side can be set from 512 to 2048 pixels. It can return up to six candidates per call. It suits object removal and replacement, background changes, style transfer, and multi-image composition such as placing a product from one image into a scene from another.

Weights are not published.

| Metric | Value |
| - | - |
| Max Resolution | 2048 per side |
| Multilingual | Yes (Chinese, English) |

## Example request

<Tip>
  Use the [Workbench](https://www.oxen.ai/ai/workbench?model=qwen-image-edit-max) as a request builder: configure parameters for this model in the UI, then open the **API** tab to copy the exact cURL or Python call.
</Tip>

<Tabs>
  <Tab title="Sync">
    See the [image editing reference](/inference-api/reference/image_editing) for more details.

    <Tabs>
      <Tab title="Minimal">
        <CodeGroup>
          ```bash cURL theme={null}
          curl -X POST https://hub.oxen.ai/api/ai/images/edit \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $OXEN_API_KEY" \
            -d '{
            "model": "qwen-image-edit-max",
            "prompt": "<prompt>",
            "input_images": [
              "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
            ]
          }'
          ```

          ```python Python theme={null}
          import os
          import requests

          response = requests.post(
              "https://hub.oxen.ai/api/ai/images/edit",
              headers={
                  "Content-Type": "application/json",
                  "Authorization": f"Bearer {os.environ['OXEN_API_KEY']}",
              },
              json={
                  "model": "qwen-image-edit-max",
                  "prompt": "<prompt>",
                  "input_images": [
                      "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
                  ]
              },
          )
          response.raise_for_status()
          print(response.json())
          ```
        </CodeGroup>
      </Tab>

      <Tab title="All parameters">
        <CodeGroup>
          ```bash cURL theme={null}
          curl -X POST https://hub.oxen.ai/api/ai/images/edit \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $OXEN_API_KEY" \
            -d '{
            "model": "qwen-image-edit-max",
            "prompt": "<prompt>",
            "input_images": [
              "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
            ],
            "aspect_ratio": "auto",
            "num_images": 1,
            "enable_prompt_expansion": true,
            "watermark": false
          }'
          ```

          ```python Python theme={null}
          import os
          import requests

          response = requests.post(
              "https://hub.oxen.ai/api/ai/images/edit",
              headers={
                  "Content-Type": "application/json",
                  "Authorization": f"Bearer {os.environ['OXEN_API_KEY']}",
              },
              json={
                  "model": "qwen-image-edit-max",
                  "prompt": "<prompt>",
                  "input_images": [
                      "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
                  ],
                  "aspect_ratio": "auto",
                  "num_images": 1,
                  "enable_prompt_expansion": true,
                  "watermark": false
              },
          )
          response.raise_for_status()
          print(response.json())
          ```
        </CodeGroup>
      </Tab>
    </Tabs>
  </Tab>

  <Tab title="Async">
    See the [async queue reference](/inference-api/reference/async_queue) for more details.

    <Tabs>
      <Tab title="Minimal">
        <CodeGroup>
          ```bash cURL theme={null}
          # Enqueue, capture the generation id.
          GEN_ID=$(curl -s -X POST https://hub.oxen.ai/api/ai/queue \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $OXEN_API_KEY" \
            -d '{
            "model": "qwen-image-edit-max",
            "prompt": "<prompt>",
            "input_images": [
              "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
            ]
          }' | jq -r '.generations[0].generation_id')

          # Poll until the generation reaches a terminal status.
          while true; do
            STATUS=$(curl -s -H "Authorization: Bearer $OXEN_API_KEY" \
              "https://hub.oxen.ai/api/ai/queue/$GEN_ID" | jq -r '.status')
            echo "Status: $STATUS"
            case $STATUS in succeeded|failed|cancelled) break;; esac
            sleep 5
          done

          # Print the result.
          curl -s -H "Authorization: Bearer $OXEN_API_KEY" \
            "https://hub.oxen.ai/api/ai/queue/$GEN_ID" | jq .
          ```

          ```python Python theme={null}
          import os
          import time
          import requests

          HEADERS = {
              "Content-Type": "application/json",
              "Authorization": f"Bearer {os.environ['OXEN_API_KEY']}",
          }

          enqueue = requests.post(
              "https://hub.oxen.ai/api/ai/queue",
              headers=HEADERS,
              json={
                  "model": "qwen-image-edit-max",
                  "prompt": "<prompt>",
                  "input_images": [
                      "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
                  ]
              },
          )
          enqueue.raise_for_status()
          generation_id = enqueue.json()["generations"][0]["generation_id"]

          while True:
              data = requests.get(
                  f"https://hub.oxen.ai/api/ai/queue/{generation_id}",
                  headers=HEADERS,
              ).json()
              if data["status"] in {"succeeded", "failed", "cancelled"}:
                  break
              time.sleep(5)

          if data["status"] == "succeeded":
              print(f"Result: {data['result_url']}")
          else:
              print(f"Generation {data['status']}: {data.get('error_message')}")
          ```
        </CodeGroup>
      </Tab>

      <Tab title="All parameters">
        <CodeGroup>
          ```bash cURL theme={null}
          # Enqueue, capture the generation id.
          GEN_ID=$(curl -s -X POST https://hub.oxen.ai/api/ai/queue \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $OXEN_API_KEY" \
            -d '{
            "model": "qwen-image-edit-max",
            "prompt": "<prompt>",
            "input_images": [
              "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
            ],
            "aspect_ratio": "auto",
            "num_images": 1,
            "enable_prompt_expansion": true,
            "watermark": false
          }' | jq -r '.generations[0].generation_id')

          # Poll until the generation reaches a terminal status.
          while true; do
            STATUS=$(curl -s -H "Authorization: Bearer $OXEN_API_KEY" \
              "https://hub.oxen.ai/api/ai/queue/$GEN_ID" | jq -r '.status')
            echo "Status: $STATUS"
            case $STATUS in succeeded|failed|cancelled) break;; esac
            sleep 5
          done

          # Print the result.
          curl -s -H "Authorization: Bearer $OXEN_API_KEY" \
            "https://hub.oxen.ai/api/ai/queue/$GEN_ID" | jq .
          ```

          ```python Python theme={null}
          import os
          import time
          import requests

          HEADERS = {
              "Content-Type": "application/json",
              "Authorization": f"Bearer {os.environ['OXEN_API_KEY']}",
          }

          enqueue = requests.post(
              "https://hub.oxen.ai/api/ai/queue",
              headers=HEADERS,
              json={
                  "model": "qwen-image-edit-max",
                  "prompt": "<prompt>",
                  "input_images": [
                      "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
                  ],
                  "aspect_ratio": "auto",
                  "num_images": 1,
                  "enable_prompt_expansion": true,
                  "watermark": false
              },
          )
          enqueue.raise_for_status()
          generation_id = enqueue.json()["generations"][0]["generation_id"]

          while True:
              data = requests.get(
                  f"https://hub.oxen.ai/api/ai/queue/{generation_id}",
                  headers=HEADERS,
              ).json()
              if data["status"] in {"succeeded", "failed", "cancelled"}:
                  break
              time.sleep(5)

          if data["status"] == "succeeded":
              print(f"Result: {data['result_url']}")
          else:
              print(f"Generation {data['status']}: {data.get('error_message')}")
          ```
        </CodeGroup>
      </Tab>
    </Tabs>
  </Tab>

  <Tab title="Async with SSE">
    See the [async queue reference](/inference-api/reference/async_queue) for more details.

    <Tabs>
      <Tab title="Minimal">
        <CodeGroup>
          ```bash cURL theme={null}
          # Enqueue, capture the generation id.
          GEN_ID=$(curl -s -X POST https://hub.oxen.ai/api/ai/queue \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $OXEN_API_KEY" \
            -d '{
            "model": "qwen-image-edit-max",
            "prompt": "<prompt>",
            "input_images": [
              "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
            ]
          }' | jq -r '.generations[0].generation_id')

          # Stream the SSE channel, grab the data line that follows a
          # media_generation_completed event for our id, and pretty-print it.
          curl -sN -H "Authorization: Bearer $OXEN_API_KEY" https://hub.oxen.ai/api/events \
            | awk -v id="$GEN_ID" '
              /^event: media_generation_completed$/ { expect=1; next }
              /^data: / && expect {
                payload = substr($0, 7)
                if (index(payload, "\"generation_id\":\"" id "\"")) { print payload; exit }
                expect = 0
              }
            ' | jq .
          ```

          ```python Python theme={null}
          import json
          import os
          import requests

          API_KEY = os.environ["OXEN_API_KEY"]
          AUTH = {"Authorization": f"Bearer {API_KEY}"}

          enqueue = requests.post(
              "https://hub.oxen.ai/api/ai/queue",
              headers={**AUTH, "Content-Type": "application/json"},
              json={
                  "model": "qwen-image-edit-max",
                  "prompt": "<prompt>",
                  "input_images": [
                      "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
                  ]
              },
          )
          enqueue.raise_for_status()
          generation_id = enqueue.json()["generations"][0]["generation_id"]

          with requests.get(
              "https://hub.oxen.ai/api/events",
              headers=AUTH,
              stream=True,
          ) as stream:
              event_name = None
              for line in stream.iter_lines(decode_unicode=True):
                  if line.startswith("event: "):
                      event_name = line.removeprefix("event: ")
                  elif line.startswith("data: ") and event_name == "media_generation_completed":
                      payload = json.loads(line.removeprefix("data: "))
                      if payload.get("generation_id") == generation_id:
                          print(payload)
                          break
          ```
        </CodeGroup>
      </Tab>

      <Tab title="All parameters">
        <CodeGroup>
          ```bash cURL theme={null}
          # Enqueue, capture the generation id.
          GEN_ID=$(curl -s -X POST https://hub.oxen.ai/api/ai/queue \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $OXEN_API_KEY" \
            -d '{
            "model": "qwen-image-edit-max",
            "prompt": "<prompt>",
            "input_images": [
              "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
            ],
            "aspect_ratio": "auto",
            "num_images": 1,
            "enable_prompt_expansion": true,
            "watermark": false
          }' | jq -r '.generations[0].generation_id')

          # Stream the SSE channel, grab the data line that follows a
          # media_generation_completed event for our id, and pretty-print it.
          curl -sN -H "Authorization: Bearer $OXEN_API_KEY" https://hub.oxen.ai/api/events \
            | awk -v id="$GEN_ID" '
              /^event: media_generation_completed$/ { expect=1; next }
              /^data: / && expect {
                payload = substr($0, 7)
                if (index(payload, "\"generation_id\":\"" id "\"")) { print payload; exit }
                expect = 0
              }
            ' | jq .
          ```

          ```python Python theme={null}
          import json
          import os
          import requests

          API_KEY = os.environ["OXEN_API_KEY"]
          AUTH = {"Authorization": f"Bearer {API_KEY}"}

          enqueue = requests.post(
              "https://hub.oxen.ai/api/ai/queue",
              headers={**AUTH, "Content-Type": "application/json"},
              json={
                  "model": "qwen-image-edit-max",
                  "prompt": "<prompt>",
                  "input_images": [
                      "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
                  ],
                  "aspect_ratio": "auto",
                  "num_images": 1,
                  "enable_prompt_expansion": true,
                  "watermark": false
              },
          )
          enqueue.raise_for_status()
          generation_id = enqueue.json()["generations"][0]["generation_id"]

          with requests.get(
              "https://hub.oxen.ai/api/events",
              headers=AUTH,
              stream=True,
          ) as stream:
              event_name = None
              for line in stream.iter_lines(decode_unicode=True):
                  if line.startswith("event: "):
                      event_name = line.removeprefix("event: ")
                  elif line.startswith("data: ") and event_name == "media_generation_completed":
                      payload = json.loads(line.removeprefix("data: "))
                      if payload.get("generation_id") == generation_id:
                          print(payload)
                          break
          ```
        </CodeGroup>
      </Tab>
    </Tabs>
  </Tab>
</Tabs>

## Fetch model details

The [models endpoint](/inference-api/reference/models/overview) returns the full model object, including its `json_request_schema`.

```bash theme={null}
curl -H "Authorization: Bearer $OXEN_API_KEY" https://hub.oxen.ai/api/ai/models/qwen-image-edit-max
```

## Request parameters

### Required parameters

| Field | Type | Default | Description |
| - | - | - | - |
| `prompt` | `string` | — | Text prompt describing the image to generate, or the edit to apply. Use @Image1, @Image2, etc. to reference the input images. |
| `input_images` | `array<string>` | — | Input images to edit or combine. The output keeps the aspect ratio of the last image unless an aspect ratio is chosen. Reference them in the prompt as @Image1, @Image2, etc. Up to 3 images. |

### Optional parameters

| Field | Type | Default | Description |
| - | - | - | - |
| `aspect_ratio` | `string` | `"auto"` | Aspect Ratio One of: auto, 16:9, 9:16, 1:1, 4:3, 3:4. |
| `num_images` | `integer` | `1` | Number of images to generate, 1 to 6. Only the first is returned; all are billed. Range: 1 – 6. |
| `enable_prompt_expansion` | `boolean` | `true` | Let the model rewrite the prompt with more detail before rendering. Turn off for tighter control over the wording. |
| `negative_prompt` | `string` | — | What to keep out of the image. Up to 500 characters. |
| `seed` | `integer` | — | Seed for reproducible generation, 0 to 2147483647. Results can still vary between runs. |
| `watermark` | `boolean` | `false` | Add an AI-generated watermark in the bottom-right corner. |


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