Image editing: edit reference images (1–5)
curl --request POST \
--url https://api.apiyi.com/v1/images/edits \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form model=MAI-Image-2.6-Flash \
--form 'prompt=Change the teapot to a deep cobalt blue glaze, keep everything else identical' \
--form 'image=@example-file;type=image/png'import requests
url = "https://api.apiyi.com/v1/images/edits"
files = { "image": ("example-file", open("example-file", "rb"), "image/png") }
payload = {
"model": "MAI-Image-2.6-Flash",
"prompt": "Change the teapot to a deep cobalt blue glaze, keep everything else identical"
}
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('model', 'MAI-Image-2.6-Flash');
form.append('prompt', 'Change the teapot to a deep cobalt blue glaze, keep everything else identical');
form.append('image', '<string>');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://api.apiyi.com/v1/images/edits', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.apiyi.com/v1/images/edits",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nMAI-Image-2.6-Flash\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nChange the teapot to a deep cobalt blue glaze, keep everything else identical\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image\"; filename=\"example-file\"\r\nContent-Type: image/png\r\n\r\n<string>\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: multipart/form-data"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.apiyi.com/v1/images/edits"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nMAI-Image-2.6-Flash\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nChange the teapot to a deep cobalt blue glaze, keep everything else identical\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image\"; filename=\"example-file\"\r\nContent-Type: image/png\r\n\r\n<string>\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.apiyi.com/v1/images/edits")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nMAI-Image-2.6-Flash\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nChange the teapot to a deep cobalt blue glaze, keep everything else identical\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image\"; filename=\"example-file\"\r\nContent-Type: image/png\r\n\r\n<string>\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.apiyi.com/v1/images/edits")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nMAI-Image-2.6-Flash\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nChange the teapot to a deep cobalt blue glaze, keep everything else identical\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image\"; filename=\"example-file\"\r\nContent-Type: image/png\r\n\r\n<string>\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"created": 1791000788,
"data": [
{
"b64_json": "<string>"
}
],
"usage": {
"prompt_tokens": 1000,
"total_tokens": 1000
}
}MAI-Image 2.6画像生成・編集
画像編集 API リファレンス
実行可能な Playground を備えた MAI-Image 2.6 画像編集 API リファレンス — 1〜5 枚の参照画像と編集または融合するための指示をアップロード、multipart/form-data ファイルアップロード専用。参照画像の枚数によって価格は変わりません
POST
/
v1
/
images
/
edits
Image editing: edit reference images (1–5)
curl --request POST \
--url https://api.apiyi.com/v1/images/edits \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form model=MAI-Image-2.6-Flash \
--form 'prompt=Change the teapot to a deep cobalt blue glaze, keep everything else identical' \
--form 'image=@example-file;type=image/png'import requests
url = "https://api.apiyi.com/v1/images/edits"
files = { "image": ("example-file", open("example-file", "rb"), "image/png") }
payload = {
"model": "MAI-Image-2.6-Flash",
"prompt": "Change the teapot to a deep cobalt blue glaze, keep everything else identical"
}
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('model', 'MAI-Image-2.6-Flash');
form.append('prompt', 'Change the teapot to a deep cobalt blue glaze, keep everything else identical');
form.append('image', '<string>');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://api.apiyi.com/v1/images/edits', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.apiyi.com/v1/images/edits",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nMAI-Image-2.6-Flash\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nChange the teapot to a deep cobalt blue glaze, keep everything else identical\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image\"; filename=\"example-file\"\r\nContent-Type: image/png\r\n\r\n<string>\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: multipart/form-data"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.apiyi.com/v1/images/edits"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nMAI-Image-2.6-Flash\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nChange the teapot to a deep cobalt blue glaze, keep everything else identical\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image\"; filename=\"example-file\"\r\nContent-Type: image/png\r\n\r\n<string>\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.apiyi.com/v1/images/edits")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nMAI-Image-2.6-Flash\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nChange the teapot to a deep cobalt blue glaze, keep everything else identical\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image\"; filename=\"example-file\"\r\nContent-Type: image/png\r\n\r\n<string>\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.apiyi.com/v1/images/edits")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nMAI-Image-2.6-Flash\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nChange the teapot to a deep cobalt blue glaze, keep everything else identical\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image\"; filename=\"example-file\"\r\nContent-Type: image/png\r\n\r\n<string>\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"created": 1791000788,
"data": [
{
"b64_json": "<string>"
}
],
"usage": {
"prompt_tokens": 1000,
"total_tokens": 1000
}
}右側のインタラクティブなPlaygroundでは、ローカル画像のアップロードに対応しています。Authorization の下にAPIキー(形式:
Bearer sk-xxx)を入力し、1つ以上の image ファイルを選択して、prompt と model を入力した上で送信してください。🔴 このエンドポイントは 画像のURLは入力としてサポートされていません。 URLのみをお持ちの場合は、まずサーバー側でダウンロードしてからファイルをアップロードしてください。ファイルアップロードなら画像ホスティングは不要で、ローカルファイルを送信するだけです。
multipart/form-data ファイルアップロードのみを受け付けます/v1/images/edits にJSONを送信した場合(image をURL、データURI、または生のbase64として指定)、400が返されます:request Content-Type isn't multipart/form-data
ユースケース: このページは参照画像を使用した編集向けであり、単一画像の編集や1〜5枚の画像の合成に対応しています。テキストのみから生成する場合は、テキストから画像生成 API を使用してください。
🖼️ 1〜5枚の参照画像をサポート(2026-10-07以降)
- 指定方法:
image[]フィールドを繰り返し、1フィールドにつき1枚の画像を指定します。OpenAI SDKを使用する場合は、リストを渡します:client.images.edit(image=[f1, f2, ...])。imageを繰り返すことでも動作します - 順序: 画像はアップロード順に番号付けされます(image 1、image 2、…)。そのため、prompt で「image 2のキツネをimage 1に配置する」のように指定できます
- 料金: リクエストごとに課金されます。画像1枚でも5枚でも料金は同じです
- 対応フォーマット: JPEG、PNG、WebP。GIFなどのその他のフォーマットは400を返します
- 5枚を超える画像: 400
at most 5 reference images are accepted for <model>が返されます
image + image2 のような連番のフィールド名は使用しないでください: リクエストは200を返しますが、最初の画像のみが使用され、2枚目は破棄されます。image1 + image2 は500 image is required を返します。複数の画像を指定する場合は、常に image[] を繰り返してください。テキストから画像生成と同じ禁止パラメータ:
response_format、seed、または negative_prompt は送信しないでください(400)。レスポンスは常に data[0].b64_json(PNG)です。コード例
Python (OpenAI SDK · 単一画像)
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 (OpenAI SDK · 複数画像の合成)
from openai import OpenAI
import base64
client = OpenAI(
api_key="sk-your-api-key",
base_url="https://api.apiyi.com/v1",
timeout=180.0
)
# Pass a list of 1-5 files; the SDK uploads each one as an image[] field
# Images are numbered in upload order (image 1, image 2, ...); same price as a single image
resp = client.images.edit(
model="MAI-Image-2.6-Flash",
image=[open("teaset.jpg", "rb"), open("fox.jpg", "rb")],
prompt="Put the fox from image 2 (keeping every detail of its look) into the scene of image 1, sitting next to the tea set; keep everything else in image 1 unchanged"
)
with open("fused.png", "wb") as f:
f.write(base64.b64decode(resp.data[0].b64_json))
Python (requests · 単一画像)
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"]))
image[] を持つタプルのリストとして files を渡します(辞書型では重複するキーを保持できません):
files = [
("image[]", ("teaset.jpg", open("teaset.jpg", "rb"), "image/jpeg")),
("image[]", ("fox.jpg", open("fox.jpg", "rb"), "image/jpeg")),
]
cURL
# 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 "[email protected]" \
| python3 -c "import sys,json,base64; open('edited.png','wb').write(base64.b64decode(json.load(sys.stdin)['data'][0]['b64_json']))"
# Edit and change the canvas to 1536×1024 (a different aspect ratio recomposes the image)
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=Turn this tea set into a lifestyle scene on a wooden table, natural light, photorealistic" \
-F "width=1536" \
-F "height=1024" \
-F "[email protected]"
# Multi-image fusion: repeat the image[] field, 1-5 images, numbered in upload order
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=Put the fox from image 2 (keeping every detail of its look) into the scene of image 1, sitting next to the tea set; keep everything else in image 1 unchanged" \
-F "image[][email protected]" \
-F "image[][email protected]" \
| python3 -c "import sys,json,base64; open('fused.png','wb').write(base64.b64decode(json.load(sys.stdin)['data'][0]['b64_json']))"
Node.js (fetch + FormData)
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');
// Multi-image fusion: call form.append('image[]', ...) once per image instead, up to 5
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 / image[] | file | ✅ | — | 参照画像ファイル、1〜5枚。画像が1枚の場合は image を使用し、複数の場合はアップロード順に画像1…Nとしてナンバリングしながら image[] フィールドを繰り返します。JPEG / PNG / WebP対応。枚数によって価格は変わりません |
width / height | integer | ❌ | 元の比率に準拠 | 出力サイズ。テキストからの画像生成と同じルールが適用されます。異なるアスペクト比を指定すると、画像が再構成されます |
n | integer | ❌ | 1 | 画像数。このエンドポイントで機能し、画像ごとに課金されます |
mask | — | — | — | サポートされていません。400 <model> does not support mask edits を返します |
response_formatseednegative_prompt | — | — | — | 400を返します |
省略時の出力サイズ: 出力は16の倍数にスナップされた元の画像のアスペクト比に従います(例: 1344×756 の入力に対しては 1360×768 が出力されます)。複数画像の場合、画像1によってアスペクト比が決まります。構図を維持すべき部分的な編集を行う場合は、
width / height を送信しないでください。編集結果とpromptの指定
編集エンドポイントは、元の構図、色、ディテールを維持し、promptで指定された内容のみを変更します。
| 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 | スタイルが再描画され、構図は維持されます |
⚠️ Make it look better | 曖昧すぎるため、変更の範囲が予測できません |
「keep everything else the same」と明示的に指定することは、このモデルにおいて最も効果的な手法であり、元の状態を可能な限り維持します。
複数画像の融合
画像1がベースとなり、promptの指示に従って他の参照画像のオブジェクトが配置されます。以下の例では、1回のリクエストで5枚の画像(ティーセット + キツネ + ラバーダック + 目覚まし時計 + サボテン)を送信し、画像2のキツネ、画像3の黄色いラバーダック、画像4の赤いビンテージ目覚まし時計、画像5の鉢植えサボテンを、画像1のティーテーブルの上に配置し、各オブジェクトの外観を維持したまま画像1のその他の部分を変更しないよう指示するpromptを使用しています。
| Prompt | 結果 |
|---|---|
✅ Put the fox from image 2 into the scene of image 1, keep everything else in image 1 unchanged | アップロード順に画像を「image N」として参照します。最も信頼性の高い表現です |
✅ 各画像のオブジェクト名を指定:the yellow rubber duck from image 3, the red alarm clock from image 4 | 画像数が多い場合、各オブジェクトに名前を付けることで抜け漏れを防ぎます |
⚠️ Combine these images into one | ベース画像や被写体が指定されていないため、構図が予測できません |
レスポンス形式
{
"created": 1791000788,
"data": [
{
"b64_json": "iVBORw0KGgoAAAANSUhEUgAABAAAAAQACAIAAADwf7zU..."
}
],
"usage": {
"prompt_tokens": 1000,
"total_tokens": 1000,
"input_tokens": 1000,
"output_tokens": 0
}
}
レスポンスフィールド
b64_jsonはdata:プレフィックスのないプレーンな base64 であり、PNG にデコードされます。n > 1の場合、data配列には複数のアイテムが含まれます。data[0]だけを読み取らないようにしてください。urlおよびrevised_promptは返されません。
usage で課金を照合しないでください:プレースホルダーが含まれています(prompt_tokens は常に画像数 × 1000 です)。編集のコストはテキストから画像への生成と同じで、画像ごとに課金され、参照画像の数によって価格が変わることはありません。APIYI コンソールの請求内容が正式なものとなります。承認
API key from the APIYI console
ボディ
multipart/form-data
Model ID (case-sensitive)
利用可能なオプション:
MAI-Image-2.6-Flash, MAI-Image-2.6 Edit instruction. State what to change and that everything else stays the same
例:
"Change the teapot to a deep cobalt blue glaze, keep everything else identical"
Reference image files, 1–5, numbered image 1…N in upload order. png / jpg / webp. In code, repeat the image[] field for several images
Required array length:
1 - 5 elementsOptional output width. Same rules as text-to-image: each side ≥ 768, width × height ≤ 2,359,296, sent together with height
必須範囲:
x >= 768Optional output height, same rules as width
必須範囲:
x >= 768Number of images. Works on this endpoint, billed per image
必須範囲:
x >= 1例:
1
このページは役に立ちましたか?