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

# 画像編集 API リファレンス

> MAI-Image 2.6 画像編集 API リファレンス（ライブ Playground 付き）— 参照画像と指示のアップロード、image + image2 による2画像合成、multipart/form-data ファイルアップロードのみに対応

<Info>
  右側のインタラクティブなPlaygroundでは、ローカル画像のアップロードに対応しています。**Authorization** にAPIキーを入力し（形式: `Bearer sk-xxx`）、`image` ファイルを選択し、`prompt` と `model` を入力して送信してください。
</Info>

<Warning>
  **🔴 このエンドポイントは `multipart/form-data` ファイルのアップロードのみを受け付けます**

  `/v1/images/edits` に（`image` をURL、データURI、または生の base64 として）JSONを送信すると、400 が返されます:

  ```text theme={null}
  request Content-Type isn't multipart/form-data
  ```

  **入力としての画像URLはサポートされていません。** URLのみをお持ちの場合は、まずサーバー側でダウンロードしてからファイルをアップロードしてください。ファイルアップロードには画像のホスティングは不要です。ローカルファイルをそのまま送信してください。
</Warning>

<Tip>
  **ユースケース**: このページは参照画像の編集や2枚の画像の合成を対象としています。テキストのみから生成する場合は、[Text-to-Image API](/ja/api-capabilities/mai-image/text-to-image)をご利用ください。
</Tip>

<Warning>
  **⚠️ 2枚の画像を使用する場合、フィールド名は `image` + `image2` であり、`image[]` ではありません**

  2枚の参照画像を使用する場合、最初のフィールド名を `image`、2番目を `image2` と指定してください。`image[]` の重複、`image` の重複、または `mask` フィールドの追加は、すべて 400 `File must be attached in a form field with a name starting with 'image'` を返します。

  これは、OpenAI SDKの複数画像フォーム `client.images.edit(image=[f1, f2])` が**動作しない**ことを意味します（`image[]` が送信されるため）。SDKを使用した単一画像の編集は問題なく動作します。
</Warning>

<Info>
  **テキストからの画像生成と同じ禁止パラメータ**: `response_format`、`seed`、または `negative_prompt` は送信しないでください（400が返されます）。レスポンスは常に `data[0].b64_json`（PNG）です。
</Info>

## コード例

### Python（OpenAI SDK・単一画像）

```python theme={null}
from openai import OpenAI
import base64

client = OpenAI(
    api_key="sk-your-api-key",
    base_url="https://api.apiyi.com/v1",
    timeout=180.0
)

# images.edit uses a multipart file upload under the hood; do not pass response_format
resp = client.images.edit(
    model="MAI-Image-2.6-Flash",
    image=open("teaset.jpg", "rb"),
    prompt="Change the teapot to a deep cobalt blue glaze, keep everything else identical"
)

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

### Python（requests・単一画像）

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

# Pass the file via files=; requests sets multipart/form-data and the boundary for you
# Do not use json=, and do not set Content-Type by hand
with open("teaset.jpg", "rb") as fp:
    response = requests.post(
        "https://api.apiyi.com/v1/images/edits",
        headers={"Authorization": f"Bearer {os.environ['APIYI_API_KEY']}"},
        data={
            "model": "MAI-Image-2.6",
            "prompt": "Change the teapot to a deep cobalt blue glaze, keep everything else exactly the same"
        },
        files={"image": ("teaset.jpg", fp, "image/jpeg")},
        timeout=180
    )
response.raise_for_status()

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

### Python（2画像合成・image + image2）

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

files = {
    "image": ("scene.jpg", open("scene.jpg", "rb"), "image/jpeg"),     # image 1
    "image2": ("person.jpg", open("person.jpg", "rb"), "image/jpeg"),  # image 2: field name is image2
}

response = requests.post(
    "https://api.apiyi.com/v1/images/edits",
    headers={"Authorization": f"Bearer {os.environ['APIYI_API_KEY']}"},
    data={
        "model": "MAI-Image-2.6",
        "prompt": "Have the person from image 2 sit at the table in image 1, arranging the tea set, natural light, photorealistic"
    },
    files=files,
    timeout=180
)
response.raise_for_status()

with open("fused.png", "wb") as f:
    f.write(base64.b64decode(response.json()["data"][0]["b64_json"]))
```

### cURL

```bash theme={null}
# Single-image edit: -F means multipart/form-data, @ uploads a local file
curl -X POST "https://api.apiyi.com/v1/images/edits" \
  -H "Authorization: Bearer sk-your-api-key" \
  -F "model=MAI-Image-2.6-Flash" \
  -F "prompt=Change the teapot to a deep cobalt blue glaze, keep everything else identical" \
  -F "image=@teaset.jpg" \
  | python3 -c "import sys,json,base64; open('edited.png','wb').write(base64.b64decode(json.load(sys.stdin)['data'][0]['b64_json']))"
```

```bash theme={null}
# Two-image fusion with the canvas changed to 1536×1024
curl -X POST "https://api.apiyi.com/v1/images/edits" \
  -H "Authorization: Bearer sk-your-api-key" \
  -F "model=MAI-Image-2.6" \
  -F "prompt=Have the person from image 2 sit at the table in image 1, arranging the tea set" \
  -F "width=1536" \
  -F "height=1024" \
  -F "image=@scene.jpg" \
  -F "image2=@person.jpg"
```

### Node.js（fetch + FormData）

```javascript theme={null}
import fs from 'node:fs';

const form = new FormData();
form.append('model', 'MAI-Image-2.6-Flash');
form.append('prompt', 'Replace the background with a snowy pine forest at night, keep the person unchanged');
form.append('image', new Blob([fs.readFileSync('./photo.jpg')]), 'photo.jpg');
// Second reference image: form.append('image2', ...)

const resp = await fetch('https://api.apiyi.com/v1/images/edits', {
    method: 'POST',
    // Do not set Content-Type by hand; FormData adds the boundary
    headers: { 'Authorization': `Bearer ${process.env.APIYI_API_KEY}` },
    body: form,
    signal: AbortSignal.timeout(120000)
});

const data = await resp.json();
fs.writeFileSync('edited.png', Buffer.from(data.data[0].b64_json, 'base64'));
```

## パラメータリファレンス

| パラメータ | 型 | 必須 | デフォルト値 | 説明 |
| - | - | - | - | - |
| `model` | string | ✅ | — | `MAI-Image-2.6`（\$0.12/画像）または `MAI-Image-2.6-Flash`（\$0.06/画像）、**大文字と小文字を区別** |
| `prompt` | string | ✅ | — | 編集指示。変更する内容と、それ以外はそのまま維持することを明記します |
| `image` | file | ✅ | — | 参照画像ファイル（1枚目） |
| `image2` | file | ❌ | — | 2枚目の参照画像（2枚の画像合成用） |
| `width` / `height` | integer | ❌ | 元画像のアスペクト比に従う | 出力サイズ。テキストからの画像生成と同じルールが適用されます。アスペクト比を変更すると画像が**再構成**されます |
| `n` | integer | ❌ | `1` | 画像の枚数。**このエンドポイントで有効**で、画像ごとに課金されます |
| ~~`mask`~~ | — | — | — | **非対応**。400を返します |
| ~~`response_format`~~ / ~~`seed`~~ / ~~`negative_prompt`~~ | — | — | — | **400を返します** |

<Info>
  **省略時の出力サイズ**: 出力は元画像のアスペクト比に従い、16の倍数に調整されます（例: 1344×756 の入力は 1360×768 になります）。構図を維持したい部分編集の場合は、`width` / `height` を送信しないでください。
</Info>

## 編集結果とプロンプティング

編集エンドポイントは、**元の構図、色、ディテールを維持し**、promptで指定された内容のみを変更します：

<Frame>
  <img src="https://mintcdn.com/apiyillc/_zXMTnA1u6gpoDyM/images/mai-image-edit-teaset.jpg?fit=max&auto=format&n=_zXMTnA1u6gpoDyM&q=85&s=c86dc86c5aadf0173e19102433c01f49" alt="MAI-Image-2.6-Flashの編集例：ティーポットがクリーム色からコバルトブルーに変更され、その他はすべて変更なし" width="1048" height="532" data-path="images/mai-image-edit-teaset.jpg" />
</Frame>

| prompt | 結果 |
| - | - |
| ✅ `Change the teapot to a deep cobalt blue glaze, keep everything else exactly the same` | ティーポットの色のみが変更され、ラベルやその他のオブジェクトはピクセル単位で同一のまま維持されます |
| ✅ `Turn this photo into a watercolor painting, keep the composition` | スタイルが描き直され、構図は維持されます |
| ✅ `Have the person from image 2 sit at the table in image 1` | 2画像の融合：画像1がシーンを提供し、画像2が人物を提供します |
| ⚠️ `Make it look better` | 曖昧すぎます。変更の範囲が予測できません |

<Tip>
  2画像の融合を行う場合は、prompt内で`image` / `image2`を「image 1 / image 2」として参照してください。テストでは**人物の同一性の再現度は中程度にとどまる**（顔の特徴が変化する可能性があります）ため、ポートレートの一貫性が重要な場合は、まず少量のバッチで検証してください。
</Tip>

## レスポンス形式

```json theme={null}
{
  "created": 1791000788,
  "data": [
    {
      "b64_json": "iVBORw0KGgoAAAANSUhEUgAABAAAAAQACAIAAADwf7zU..."
    }
  ],
  "usage": {
    "prompt_tokens": 1000,
    "total_tokens": 1000,
    "input_tokens": 1000,
    "output_tokens": 0
  }
}
```

<Warning>
  **レスポンスフィールド**

  * `b64_json` は **`data:` プレフィックスのないプレーンな base64** であり、PNG にデコードされます。
  * `n > 1` の場合、`data` 配列には複数のアイテムが含まれます。`data[0]` のみを取得しないようにしてください。
  * `url` および `revised_prompt` は返されません。
</Warning>

<Info>
  **`usage` で課金の照合を行わないでください**：プレースホルダーが保持されています（`prompt_tokens` は常に画像数 × 1000 となります）。画像編集の**コストは Text-to-Image と同一**であり、画像単位で課金されます。APIYI コンソールの請求明細が正式なものとなります。
</Info>


## OpenAPI

````yaml api-reference/mai-image-edit-openapi-en.yaml POST /v1/images/edits
openapi: 3.1.0
info:
  title: MAI-Image 2.6 Image Editing API
  description: >
    Microsoft MAI-Image 2.6 image generation — image editing endpoint.


    - **The request must be `multipart/form-data` (file upload)**; JSON or image
    URLs return 400

    - Single-image editing and two-image fusion (field names `image` + `image2`)

    - No mask support; do not send `response_format` / `seed` /
    `negative_prompt`

    - Flat per-image pricing, same as text-to-image; `n` works on this endpoint
    and is billed per image


    **Authentication**: add `Authorization: Bearer YOUR_API_KEY` to the request
    headers


    **Get an API key**: create a token in the [APIYI
    console](https://api.apiyi.com/token)
  version: 1.0.0
servers:
  - url: https://api.apiyi.com
    description: Primary endpoint
security:
  - bearerAuth: []
paths:
  /v1/images/edits:
    post:
      tags:
        - Image Editing
      summary: 'Image editing: edit a reference image or fuse two images'
      description: >
        Edit an uploaded reference image, or fuse two images, from a text
        instruction with MAI-Image 2.6.


        - **Must use `multipart/form-data`**. Sending `application/json` returns
          400: `request Content-Type isn't multipart/form-data`
        - The second reference image's field is `image2`; repeated `image[]`,
        repeated `image`, or a `mask` field all return 400

        - Without `width` / `height` the output follows the original's ratio; a
        different aspect ratio recomposes the image
      operationId: editMaiImage
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/MaiImageEditRequest'
            encoding:
              image:
                contentType: image/png, image/jpeg, image/webp
              image2:
                contentType: image/png, image/jpeg, image/webp
      responses:
        '200':
          description: Image generated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImageResponse'
        '400':
          description: >-
            Not multipart/form-data, invalid field names, invalid parameters, or
            blocked by moderation
        '401':
          description: Unauthorized - invalid API key
        '429':
          description: Rate limit exceeded or insufficient balance
        '500':
          description: No image file field in the request (`image is required`)
      security:
        - bearerAuth: []
components:
  schemas:
    MaiImageEditRequest:
      type: object
      required:
        - model
        - prompt
        - image
      properties:
        model:
          type: string
          description: Model ID (case-sensitive)
          enum:
            - MAI-Image-2.6-Flash
            - MAI-Image-2.6
          default: MAI-Image-2.6-Flash
        prompt:
          type: string
          description: >-
            Edit instruction. State what to change and that everything else
            stays the same
          example: >-
            Change the teapot to a deep cobalt blue glaze, keep everything else
            identical
        image:
          type: string
          format: binary
          description: >-
            Reference image file (the first one, "image 1" in the prompt). png /
            jpg / webp
        image2:
          type: string
          format: binary
          description: >-
            Optional second reference image ("image 2" in the prompt), for
            two-image fusion
        width:
          type: integer
          description: >-
            Optional output width. Same rules as text-to-image: each side ≥ 768,
            width × height ≤ 2,359,296, sent together with `height`
          minimum: 768
        height:
          type: integer
          description: Optional output height, same rules as `width`
          minimum: 768
        'n':
          type: integer
          description: Number of images. Works on this endpoint, billed per image
          minimum: 1
          default: 1
          example: 1
    ImageResponse:
      type: object
      properties:
        created:
          type: integer
          description: Creation timestamp
          example: 1791000788
        data:
          type: array
          description: Image results; length equals `n`
          items:
            type: object
            properties:
              b64_json:
                type: string
                description: 'Plain base64 image data (PNG, no data: prefix)'
        usage:
          type: object
          description: >-
            **Placeholder values, not for billing reconciliation.**
            `prompt_tokens` is always `1000 × images`
          properties:
            prompt_tokens:
              type: integer
              example: 1000
            total_tokens:
              type: integer
              example: 1000
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: API key from the APIYI console

````

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