curl --request POST \
--url https://api.apiyi.com/v1/images/edits \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form model=gpt-image-2.5-sunburst \
--form 'prompt=Place subject from image 1 into scene from image 2, using color style from image 3' \
--form 'image=<string>' \
--form image.items='@example-file' \
--form mask='@example-file'import requests
url = "https://api.apiyi.com/v1/images/edits"
files = {
"image.items": ("example-file", open("example-file", "rb")),
"mask": ("example-file", open("example-file", "rb"))
}
payload = {
"model": "gpt-image-2.5-sunburst",
"prompt": "Place subject from image 1 into scene from image 2, using color style from image 3",
"image": "<string>"
}
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('model', 'gpt-image-2.5-sunburst');
form.append('prompt', 'Place subject from image 1 into scene from image 2, using color style from image 3');
form.append('image', '<string>');
form.append('image.items', '{
"fileName": "example-file"
}');
form.append('mask', '{
"fileName": "example-file"
}');
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\ngpt-image-2.5-sunburst\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nPlace subject from image 1 into scene from image 2, using color style from image 3\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image.items\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"mask\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\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\ngpt-image-2.5-sunburst\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nPlace subject from image 1 into scene from image 2, using color style from image 3\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image.items\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"mask\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\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\ngpt-image-2.5-sunburst\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nPlace subject from image 1 into scene from image 2, using color style from image 3\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image.items\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"mask\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\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\ngpt-image-2.5-sunburst\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nPlace subject from image 1 into scene from image 2, using color style from image 3\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image.items\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"mask\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"created": 1776832476,
"data": [
{
"b64_json": "iVBORw0KGgoAAAANSUhEUgAA..."
}
],
"usage": {
"input_tokens": 1280,
"output_tokens": 6240,
"total_tokens": 7520
}
}画像編集 API リファレンス
gpt-image-2.5-sunburst / gpt-image-2.5-flare / gpt-image-2 画像編集 API リファレンスおよびライブテスト — 参照画像(最大16枚)と指示をアップロードして、単一画像編集、複数画像合成、またはマスクインペイントを実行します
curl --request POST \
--url https://api.apiyi.com/v1/images/edits \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form model=gpt-image-2.5-sunburst \
--form 'prompt=Place subject from image 1 into scene from image 2, using color style from image 3' \
--form 'image=<string>' \
--form image.items='@example-file' \
--form mask='@example-file'import requests
url = "https://api.apiyi.com/v1/images/edits"
files = {
"image.items": ("example-file", open("example-file", "rb")),
"mask": ("example-file", open("example-file", "rb"))
}
payload = {
"model": "gpt-image-2.5-sunburst",
"prompt": "Place subject from image 1 into scene from image 2, using color style from image 3",
"image": "<string>"
}
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('model', 'gpt-image-2.5-sunburst');
form.append('prompt', 'Place subject from image 1 into scene from image 2, using color style from image 3');
form.append('image', '<string>');
form.append('image.items', '{
"fileName": "example-file"
}');
form.append('mask', '{
"fileName": "example-file"
}');
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\ngpt-image-2.5-sunburst\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nPlace subject from image 1 into scene from image 2, using color style from image 3\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image.items\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"mask\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\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\ngpt-image-2.5-sunburst\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nPlace subject from image 1 into scene from image 2, using color style from image 3\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image.items\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"mask\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\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\ngpt-image-2.5-sunburst\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nPlace subject from image 1 into scene from image 2, using color style from image 3\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image.items\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"mask\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\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\ngpt-image-2.5-sunburst\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nPlace subject from image 1 into scene from image 2, using color style from image 3\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image.items\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"mask\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"created": 1776832476,
"data": [
{
"b64_json": "iVBORw0KGgoAAAANSUhEUgAA..."
}
],
"usage": {
"input_tokens": 1280,
"output_tokens": 6240,
"total_tokens": 7520
}
}Bearer sk-xxx)を入力し、画像 / マスクファイルを選択して、prompt と model を入力してから送信します。multipart/form-dataです。純粋なテキストから画像への変換には、テキスト画像生成エンドポイントを使用してください。请求时发生错误: unable to complete requestと表示される場合があります — リクエストは実際には成功しています。ブラウザでは、このように長いbase64文字列をレンダリングできないだけです。推奨ワークフロー(初心者向け):- 以下のPython / Node.js / cURLサンプルをコピーして、ローカルで実行してください。コードがレスポンスを自動的に
base64.b64decodesし、画像をファイルに書き込みます。 - ブラウザ内のPlaygroundを使用する必要がある場合は、非常に小さい参照画像(< 50KB)を使用し、
sizeを最小ティア(例:1024x1024)に設定して、qualityをlowにしてください。
input_fidelityを渡さないでください — 3つのモデルすべてで高忠実度が強制されます。これを渡すと400が返されます(2026-09-09に2.5で確認済み)- 編集リクエストでは入力tokenが明らかに多くなります — 参照画像はVisionの課金によって多数のtokenに変換されるため、予算を考慮してください
- 複数画像の融合: 最大16枚 —
image[]フィールドを繰り返してください。16枚を超えるとエラーになります
image[]フィールドは複数の参照画像を受け付けます。アップロード順序が、prompt内の「画像1 / 画像2 / 画像3」の参照順序に対応します。次のように明示的に指定してください:画像1の被写体を画像2のシーンに配置し、画像3のカラースタイルを使用するファイルごとの上限: 1ファイルあたり50MB未満(multipartファイルアップロード)、形式:
png / jpg / webp。実際には、アップロード前に1.5MB以内に圧縮してください(下記の「アップロードサイズの制限」を参照)。コード例
Python(OpenAI SDK · 単一画像編集)
from openai import OpenAI
import base64
client = OpenAI(
api_key="sk-your-api-key",
base_url="https://api.apiyi.com/v1"
)
resp = client.images.edit(
model="gpt-image-2.5-sunburst",
image=open("photo.png", "rb"),
prompt="Replace the background with a seaside sunset, preserve subject details",
size="1536x1024",
quality="high"
)
# b64_json is raw base64 (no prefix) — decode manually
with open("edited.png", "wb") as f:
f.write(base64.b64decode(resp.data[0].b64_json))
Python(OpenAI SDK · 複数画像融合)
resp = client.images.edit(
model="gpt-image-2.5-sunburst",
image=[
open("person.png", "rb"),
open("scene.png", "rb"),
open("style.png", "rb"),
],
prompt="Place subject from image 1 into scene from image 2, using color style from image 3, keep lighting consistent",
size="1536x1024",
quality="high"
)
with open("fused.png", "wb") as f:
f.write(base64.b64decode(resp.data[0].b64_json))
cURL(複数画像融合)
curl -X POST "https://api.apiyi.com/v1/images/edits" \
-H "Authorization: Bearer sk-your-api-key" \
-F "model=gpt-image-2.5-sunburst" \
-F "prompt=Place subject from image 1 into scene from image 2, using color style from image 3" \
-F "size=1536x1024" \
-F "quality=high" \
-F "image[][email protected]" \
-F "image[][email protected]" \
-F "image[][email protected]"
cURL(マスクインペインティング)
curl -X POST "https://api.apiyi.com/v1/images/edits" \
-H "Authorization: Bearer sk-your-api-key" \
-F "model=gpt-image-2.5-sunburst" \
-F "prompt=Replace the sky with pink sunset clouds" \
-F "size=1024x1024" \
-F "quality=high" \
-F "image[][email protected]" \
-F "[email protected]" \
| jq -r '.data[0].b64_json' | base64 -d > photo_edited.png
Node.js(ネイティブ fetch + FormData · 複数画像融合)
import fs from 'node:fs';
const form = new FormData();
form.append('model', 'gpt-image-2.5-sunburst');
form.append('prompt', 'Place subject from image 1 into scene from image 2');
form.append('size', '1536x1024');
form.append('quality', 'high');
form.append('image[]', new Blob([fs.readFileSync('./person.png')]), 'person.png');
form.append('image[]', new Blob([fs.readFileSync('./scene.png')]), 'scene.png');
const resp = await fetch('https://api.apiyi.com/v1/images/edits', {
method: 'POST',
headers: { 'Authorization': 'Bearer sk-your-api-key' },
body: form
});
const { data } = await resp.json();
fs.writeFileSync('fused.png', Buffer.from(data[0].b64_json, 'base64'));
パラメータリファレンス
| フィールド | 型 | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
model | テキスト | はい | — | gpt-image-2.5-sunburst(編集精度優先、編集に適した選択肢)/ gpt-image-2.5-flare(速度優先)/ gpt-image-2(旧世代、引き続き利用可能);本番環境では日付付きスナップショット gpt-image-2.5-sunburst-2026-09-08 / gpt-image-2.5-flare-2026-09-08 を固定してください。3つすべてで価格とパラメータは同一です |
prompt | テキスト | はい | — | 編集 / 融合の指示 |
image[] | ファイル | はい | — | 参照画像。繰り返し指定できます(最大16個) |
mask | ファイル | いいえ | — | マスク画像(最初の画像にのみ適用され、アルファチャンネルが必要です) |
size | テキスト | いいえ | auto | 出力サイズ。テキストから画像への生成と同じです |
quality | テキスト | いいえ | auto | low / medium / high / xhigh / max / auto;xhigh / max は2.5で追加され、gpt-image-2 は high で停止します |
output_format | テキスト | いいえ | png | png / jpeg / webp |
output_compression | テキスト | いいえ | — | 0~100。jpeg / webp にのみ使用します |
background | テキスト | いいえ | auto | transparent / opaque / auto。transparent を使用する場合、output_format は png または webp でなければなりません。編集エンドポイントでの透明化は正確な切り抜きではなく再描画である点に注意してください — 透明な背景に関するFAQを参照してください |
quality に旧式の DALL·E 値 standard / hd を渡さないでください。 受け付けられるのは6つの公式列挙値 low / medium / high / xhigh / max / auto のみです(xhigh / max は2つの2.5モデルでのみ利用できます)。旧式の値はバックエンドチャネルによって挙動が一貫しません。400(invalid_value)で直ちに失敗する場合もあれば、暗黙的に無視され、リクエストが auto で実行される場合もあります(コストを予測できません)。必ず公式値のいずれかを明示的に渡してください。アップロードサイズの制限
| 項目 | 制限 | 備考 |
|---|---|---|
| 参照画像数 | 最大 16 枚 | image[] フィールドを繰り返してください |
| 画像ごと(multipart ファイルアップロード) | 各 50MB 未満 | 形式: png / jpg / webp |
| 画像ごと(base64 data URL) | フィールド長 約20MiB | これは URL/base64 の 文字列フィールド の長さ制限(schema maxLength: 20971520)であり、50MB の multipart 上限とは 別 です。base64 によりサイズは約 1/3 増えるため、元画像は 15MB 以内 に収めてください |
| マスクファイル | 4MB 未満の PNG | 元画像と同じ寸法で、アルファチャンネルが必要です |
参照画像の形式要件と前処理
/v1/images/edits は png / jpg / webp の標準形式のみを受け付けます。次の 400 が返ってきた場合:
{
"error": {
"message": "Invalid image file or mode for image 1, please check your image file. ...",
"type": "shell_api_error",
"code": "invalid_image_file"
}
}
.jpg Huawei Mateシリーズの端末からそのまま出力されたファイルには HDR のゲインマップ用サブフレームが埋め込まれており、実際には MPO です。これらのファイルは同じ FFD8 ヘッダーで始まります。拡張子と file コマンドのどちらも JPEG と表示されるため、見た目では判別できません。フレームを認識できるパース(例: Pillow)だけが見分けられます。エラーにある「image 1」は N 番目の参照画像(1 始まり)を指すので、インデックスを使って問題のファイルを特定してください。
Image.open(f).format が "MPO" を返す場合、ファイルの変換が必要です。アップロードパイプラインに 1 回の再エンコード手順を入れておけば、HEIC や他のスマホ形式にも対応できます:
from PIL import Image
import io
def normalize_image(path: str) -> bytes:
"""Convert phone photos (MPO/HDR multi-frame etc.) to standard JPEG that passes edits validation"""
im = Image.open(path)
im.load() # for MPO, keeps only the first (full-size) frame
if im.mode not in ("RGB", "RGBA"):
im = im.convert("RGB")
out = io.BytesIO()
im.save(out, format="JPEG", quality=92) # or format="PNG"
return out.getvalue()
マスク インペインティング要件
- 元画像と同じサイズ、PNG形式、4MB未満
- アルファチャンネル必須: 透明(alpha=0)= インペイント対象領域、不透明 = 保持
- マスクは最初の画像にのみ適用されます
- マスクは「ソフトガイド」です — モデルはマスクされた領域の周囲を拡張または縮小する場合があります
image[]としてフィードバックし、新しい指示で段階的に調整します。各ラウンドは個別に token 課金されます — 累積コストに注意してください。Response Format
{
"created": 1776832476,
"data": [
{
"b64_json": "iVBORw0KGgoAAAANSUhEUgAA..."
}
],
"usage": {
"input_tokens": 848,
"input_tokens_details": {
"image_tokens": 832,
"text_tokens": 16
},
"output_tokens": 196,
"output_tokens_details": {
"image_tokens": 196,
"text_tokens": 0
},
"total_tokens": 1044
}
}
b64_json is raw base64, without the data:image/...;base64, prefix — different from gpt-image-2-all. Decode it client-side to write a file, or prepend the prefix for browser rendering.input_tokens are typically significantly higher than text-to-image at the same size, because reference images are billed per Vision pricing rules — the exact amount is available directly in usage.input_tokens_details.image_tokens, tracked separately from the text portion (text_tokens). Multi-image fusion increases image_tokens strictly linearly per additional reference image (verified July 2026: 4 × 1024² images = 4 × 1024 tokens) — see How Multiple Input Images Affect the Price for the measurement table. See How to check the real token count for each call on the overview page for the full field reference.承認
API Key obtained from APIYI Console
ボディ
Model name. gpt-image-2.5-flare (speed-first) / gpt-image-2.5-sunburst (quality- and editing-first) / gpt-image-2 (previous generation) share the same price and parameters; pin a dated snapshot in production
gpt-image-2.5-flare, gpt-image-2.5-sunburst, gpt-image-2, gpt-image-2.5-flare-2026-09-08, gpt-image-2.5-sunburst-2026-09-08 Edit/fusion instruction. For multi-image, use 'image 1 / image 2 / image 3' to reference upload order
"Place subject from image 1 into scene from image 2, using color style from image 3"
Reference images. For a single image, send the field once; for multiple images, repeat the same image field (e.g., -F [email protected] -F [email protected], max 16) — upload order maps to image 1 / image 2 / ... in the prompt. multipart file upload: each under 50MB, formats: png/jpg/webp; compress to within 1.5MB in practice
Mask image (optional, only applies to first image). Requirements:
- Same size as original
- PNG format, under 4MB
- Must have alpha channel (alpha=0 = inpaint area, opaque = preserve)
Output size (same as text-to-image). Preset or constraint-satisfying custom size
"1536x1024"
Quality tier. xhigh / max are new in 2.5 and rejected by gpt-image-2
auto, low, medium, high, xhigh, max Output format
png, jpeg, webp Output compression (0–100), only effective for jpeg/webp
0 <= x <= 100Background mode. auto or opaque. Not supported: transparent
auto, opaque このページは役に立ちましたか?