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-vip \
--form 'prompt=Place the person from image1 into the scene of image2, in the style of image3' \
--form 'image=<string>' \
--form image.items='@example-file'import requests
url = "https://api.apiyi.com/v1/images/edits"
files = { "image.items": ("example-file", open("example-file", "rb")) }
payload = {
"model": "gpt-image-2-vip",
"prompt": "Place the person from image1 into the scene of image2, in the style of image3",
"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-vip');
form.append('prompt', 'Place the person from image1 into the scene of image2, in the style of image3');
form.append('image', '<string>');
form.append('image.items', '{
"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-vip\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nPlace the person from image1 into the scene of image2, in the style of image3\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--",
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-vip\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nPlace the person from image1 into the scene of image2, in the style of image3\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--")
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-vip\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nPlace the person from image1 into the scene of image2, in the style of image3\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--")
.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-vip\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nPlace the person from image1 into the scene of image2, in the style of image3\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--"
response = http.request(request)
puts response.read_body{
"data": [
{
"b64_json": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
}
],
"created": 1778037127,
"usage": {
"input_tokens": 98,
"output_tokens": 1185,
"total_tokens": 1283
}
}Справочник API редактирования изображений
Справочник API редактирования изображений gpt-image-2-vip и интерактивная песочница — загружайте опорные изображения + инструкции для редактирования одного изображения или слияния нескольких изображений. Используйте size, чтобы зафиксировать размеры выхода.
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-vip \
--form 'prompt=Place the person from image1 into the scene of image2, in the style of image3' \
--form 'image=<string>' \
--form image.items='@example-file'import requests
url = "https://api.apiyi.com/v1/images/edits"
files = { "image.items": ("example-file", open("example-file", "rb")) }
payload = {
"model": "gpt-image-2-vip",
"prompt": "Place the person from image1 into the scene of image2, in the style of image3",
"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-vip');
form.append('prompt', 'Place the person from image1 into the scene of image2, in the style of image3');
form.append('image', '<string>');
form.append('image.items', '{
"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-vip\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nPlace the person from image1 into the scene of image2, in the style of image3\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--",
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-vip\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nPlace the person from image1 into the scene of image2, in the style of image3\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--")
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-vip\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nPlace the person from image1 into the scene of image2, in the style of image3\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--")
.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-vip\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nPlace the person from image1 into the scene of image2, in the style of image3\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--"
response = http.request(request)
puts response.read_body{
"data": [
{
"b64_json": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
}
],
"created": 1778037127,
"usage": {
"input_tokens": 98,
"output_tokens": 1185,
"total_tokens": 1283
}
}Bearer sk-xxx), выберите изображение, задайте prompt / model / size, затем нажмите отправить.multipart/form-data. Для чистой генерации изображений по тексту см. эндпоинт Text-to-Image.Отличие от gpt-image-2-all: идентичная структура вызова, только с одним дополнительным полем size. Если вам не нужно фиксировать размеры и нужен максимально быстрый результат, используйте gpt-image-2-all.b64_json), которая может занимать несколько MB, поэтому браузерный Playground может показывать 请求时发生错误: unable to complete request — запрос на самом деле успешно выполнен; браузер просто не может отобразить такую длинную строку base64.Рекомендуемый рабочий процесс: если вам нужен base64 или требуется загрузить очень большие референсные изображения, скопируйте приведенный ниже пример кода и запустите его локально.image принимает несколько референсных изображений. Порядок является основой для ссылок “image1 / image2 / image3” в вашем prompt. Явно указывайте их в prompt, например:Поместите человека из image1 в сцену image2, в стиле живописи image3Рекомендуется ≤ 10 MB на изображение, форматы
png / jpg / webp. Слишком большие изображения могут упереться в лимиты шлюза.size=auto (или не указываете size), output наследует соотношение сторон того референсного изображения, которое prompt называет целью редактирования — не обязательно первого в сценариях с несколькими изображениями.Например, при prompt “измените image2, подберите одежду и шляпу image2 под image1”, если image2 имеет формат 1:1, output тоже будет 1:1 (даже если image1 — пейзажный формат 16:9).Это полезно для замены одежды, добавления аксессуаров, ретуши и других редактирований с сохранением формы. Если prompt не указывает цель, модель определит ее сама; передавайте явный 30-бакетный size только тогда, когда вам нужно изменить соотношение сторон.size: для редактирования предпочтительноauto(или не указывать поле) — модель сохраняет соотношение сторон того референсного изображения, которое prompt называет целью редактирования, а не обязательно первого в сценариях с несколькими изображениями. Например, при prompt “измените image2, подберите одежду image2 под image1” соотношение сторон output совпадает с image2; если prompt не снимает неоднозначность, модель решит сама. Чтобы принудительно задать другой размер, выберите один из 30 поддерживаемых размеров; используйте строчные ASCIIx, например2048x1360,3840x2160. Полная таблица: страница обзора.quality: ❌ отклонено — не передавайте.n: ❌ отклонено — одно изображение на вызов.response_format: если не указывать, возвращается base64 (raw, без префикса, проверено в июле 2026); передавайте"url"для получения URL изображения. Компаниям, которые зависят от output в виде URL, следует переключить свой token на группуimage2_OSS, чтобы получать детерминированный output URL без fallback на base64.
Примеры кода
Python
Редактирование одного изображения:import requests
API_KEY = "sk-your-api-key"
with open("photo.png", "rb") as f:
response = requests.post(
"https://api.apiyi.com/v1/images/edits",
headers={"Authorization": f"Bearer {API_KEY}"},
data={
"model": "gpt-image-2-vip",
"prompt": "Replace the background with a sunset beach",
"size": "2048x1360" # 3:2 2K Recommended
},
files=[
("image", ("photo.png", f, "image/png"))
],
timeout=300 # conservative; absorbs upload + long-tail
).json()
print(response["data"][0]["url"])
import requests
with open("ref1.png", "rb") as f1, \
open("ref2.png", "rb") as f2, \
open("ref3.png", "rb") as f3:
response = requests.post(
"https://api.apiyi.com/v1/images/edits",
headers={"Authorization": "Bearer sk-your-api-key"},
data={
"model": "gpt-image-2-vip",
"prompt": "Place the person from image1 into the scene of image2, in the style of image3",
"size": "2048x2048" # 1:1 2K Recommended
},
files=[
("image", ("ref1.png", f1, "image/png")),
("image", ("ref2.png", f2, "image/png")),
("image", ("ref3.png", f3, "image/png"))
],
timeout=300
).json()
# Verified July 2026: b64_json is raw base64 (no data: prefix); earlier versions
# included the prefix, so a defensive check is safest
import base64
b64 = response["data"][0]["b64_json"]
if b64.startswith("data:"):
b64 = b64.split(",", 1)[1]
with open("edited.png", "wb") as f:
f.write(base64.b64decode(b64))
cURL
Редактирование одного изображения:curl -X POST "https://api.apiyi.com/v1/images/edits" \
-H "Authorization: Bearer sk-your-api-key" \
-F "model=gpt-image-2-vip" \
-F "prompt=Replace the background with a sunset beach" \
-F "size=2048x1360" \
-F "image=@./photo.png"
curl -X POST "https://api.apiyi.com/v1/images/edits" \
-H "Authorization: Bearer sk-your-api-key" \
-F "model=gpt-image-2-vip" \
-F "prompt=Place the person from image1 into the scene of image2, in the style of image3" \
-F "size=2048x2048" \
-F "image=@./ref1.png" \
-F "image=@./ref2.png" \
-F "image=@./ref3.png"
Node.js (нативные fetch + FormData)
import fs from 'node:fs';
const form = new FormData();
form.append('model', 'gpt-image-2-vip');
form.append('prompt', 'Replace the background with outer space');
form.append('size', '2048x1360');
form.append(
'image',
new Blob([fs.readFileSync('./photo.png')]),
'photo.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();
console.log(data.data[0].url);
JavaScript в браузере (объекты File)
// <input type="file" id="fileInput" multiple>
const files = document.getElementById('fileInput').files;
const form = new FormData();
form.append('model', 'gpt-image-2-vip');
form.append('prompt', 'Fuse these images into a single poster');
form.append('size', '2048x2048');
for (const f of files) form.append('image', f);
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();
document.getElementById('result').src = data[0].url;
Параметры
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
model | text | Да | Зафиксировано на gpt-image-2-vip |
prompt | text | Да | Описание правки/слияния на естественном языке |
image | file | Да | Референсное изображение; может повторяться (поле массива) |
size | text | Нет | Размер вывода: auto (по умолчанию — следует за тем референсным изображением, которое prompt называет целью правки, а не обязательно за первым) или один из 30 размеров; формат WIDTHxHEIGHT (в нижнем регистре x) |
image следующего вызова с новой инструкцией по правке, чтобы постепенно уточнять результат. Каждый раунд может задавать свой собственный size.Формат ответа
Как и в endpoint text-to-image: по умолчанию возвращает base64 (data[0].b64_json, сырой base64 без префикса, проверено в июле 2026). Для URL изображения явно передайте response_format: "url"; компаниям, которым нужен вывод URL, следует перевести свой token в группу image2_OSS для детерминированного вывода URL без fallback на base64. data[0] возвращает либо url, либо b64_json — никогда не оба варианта.
Режим b64_json (по умолчанию):
{
"data": [
{
"b64_json": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
}
],
"created": 1778037127,
"usage": {
"input_tokens": 98,
"output_tokens": 1185,
"total_tokens": 1283
}
}
url (явно передайте response_format: "url"; используйте группу image2_OSS, если вам нужны URL):
{
"data": [
{
"url": "https://r2cdn.copilotbase.com/r2cdn2/0e82148a-bec0-4b42-bbca-117c6b42581b.png"
}
],
"created": 1778037331,
"usage": {
"input_tokens": 30,
"output_tokens": 2074,
"total_tokens": 2104
}
}
b64_json — это сырой base64 без префикса data: — декодируйте его или добавьте префикс самостоятельно перед рендерингом. В более ранних версиях префикс действительно присутствовал, поэтому сначала всегда проверяйте startsWith('data:'), чтобы обработать оба варианта.Связанные ресурсы
Обзор модели (полная таблица размеров)
API для генерации изображений по тексту
/v1/images/generations совместимый эндпоинтСопутствующая модель gpt-image-2-all
Авторизации
API Key from the API易 Console
Тело
Model name, fixed to gpt-image-2-vip
gpt-image-2-vip Edit/fusion instruction. For multi-image flows, reference upload order as image1/image2/image3
"Place the person from image1 into the scene of image2, in the style of image3"
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]) — upload order maps to image1 / image2 / ... in the prompt. Recommended ≤ 10MB each, formats png / jpg / webp.
Output size. For editing, prefer auto (or omit the field) — the model preserves the aspect ratio of whichever reference image the prompt names as the target of the edit (not necessarily the first one in multi-image scenarios). For example, with the prompt "modify image2, change image2's outfit to match image1", the output ratio matches image2. If the prompt doesn't disambiguate, the model decides on its own. To force a different dimension, pick one of the 30 supported sizes; format: WIDTHxHEIGHT with lowercase ASCII x, e.g., 2048x1360, 3840x2160. Flat $0.03/image across all tiers.
auto, 1280x1280, 848x1280, 1280x848, 960x1280, 1280x960, 1024x1280, 1280x1024, 720x1280, 1280x720, 1280x544, 2048x2048, 1360x2048, 2048x1360, 1536x2048, 2048x1536, 1632x2048, 2048x1632, 1152x2048, 2048x1152, 2048x864, 2880x2880, 2336x3520, 3520x2336, 2480x3312, 3312x2480, 2560x3216, 3216x2560, 2160x3840, 3840x2160, 3840x1632 "2048x1360"
Ответ
Image successfully generated. Defaults to base64 in data[0].b64_json — url is not returned in the same response.
Image editing response. Returns base64 by default (data[0].b64_json); to get a url, switch to the image2_OSS group with response_format=url. data[0] returns either url or b64_json, never both.
Была ли эта страница полезной?