curl --request POST \
--url https://api.apiyi.com/v1/images/edits \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form model=grok-imagine-image \
--form 'prompt=Change the scarf color to bright RED. Keep everything else exactly the same.' \
--form image='@example-file'import requests
url = "https://api.apiyi.com/v1/images/edits"
files = { "image": ("example-file", open("example-file", "rb")) }
payload = {
"model": "grok-imagine-image",
"prompt": "Change the scarf color to bright RED. Keep everything else exactly the same."
}
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('model', 'grok-imagine-image');
form.append('prompt', 'Change the scarf color to bright RED. Keep everything else exactly the same.');
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\ngrok-imagine-image\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nChange the scarf color to bright RED. Keep everything else exactly the same.\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\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\ngrok-imagine-image\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nChange the scarf color to bright RED. Keep everything else exactly the same.\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\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\ngrok-imagine-image\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nChange the scarf color to bright RED. Keep everything else exactly the same.\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\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\ngrok-imagine-image\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nChange the scarf color to bright RED. Keep everything else exactly the same.\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"created": 0,
"data": [
{
"url": "https://apac.ossforai.com/2026/08/12/09b026d5-3492-4678-907c-e25972e6c914.jpg",
"b64_json": "<string>"
}
],
"usage": {
"prompt_tokens": 1000,
"total_tokens": 1000
}
}Справочник API для редактирования изображений
Справочник API для редактирования изображений Grok Imagine 2 и тестирование в реальном времени — загрузите 1-3 эталонных изображения и инструкцию для редактирования или слияния; требуется multipart/form-data
curl --request POST \
--url https://api.apiyi.com/v1/images/edits \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form model=grok-imagine-image \
--form 'prompt=Change the scarf color to bright RED. Keep everything else exactly the same.' \
--form image='@example-file'import requests
url = "https://api.apiyi.com/v1/images/edits"
files = { "image": ("example-file", open("example-file", "rb")) }
payload = {
"model": "grok-imagine-image",
"prompt": "Change the scarf color to bright RED. Keep everything else exactly the same."
}
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('model', 'grok-imagine-image');
form.append('prompt', 'Change the scarf color to bright RED. Keep everything else exactly the same.');
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\ngrok-imagine-image\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nChange the scarf color to bright RED. Keep everything else exactly the same.\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\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\ngrok-imagine-image\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nChange the scarf color to bright RED. Keep everything else exactly the same.\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\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\ngrok-imagine-image\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nChange the scarf color to bright RED. Keep everything else exactly the same.\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\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\ngrok-imagine-image\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nChange the scarf color to bright RED. Keep everything else exactly the same.\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"image\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"created": 0,
"data": [
{
"url": "https://apac.ossforai.com/2026/08/12/09b026d5-3492-4678-907c-e25972e6c914.jpg",
"b64_json": "<string>"
}
],
"usage": {
"prompt_tokens": 1000,
"total_tokens": 1000
}
}Bearer sk-xxx), выберите файл image, заполните prompt и model, и отправьте.multipart/form-dataОтправка JSON в /v1/images/edits всегда возвращает 400:request Content-Type isn't multipart/form-data
{"image": {"type": "image_url", "url": "..."}}), и такой формат не работает через шлюз APIYI. Вместо этого используйте эту страницу.Преимущество в том, что загрузка файла означает не нужен хостинг изображений — просто отправьте локальный файл, что проще, чем готовить общедоступный URL.Поле файла должно называться image или image[]; images / image_file возвращают 415. prompt требуется — если его не указать, возвращается 400.resolution и aspect_ratio принимаются здесь без ошибки, но не влияют ни на что — результат редактирования всегда совпадает с размерами входного референсного изображения (1280x720 на входе дает 1280x720 на выходе; 1024x1024 на входе дает 1024x1024 на выходе).Чтобы изменить размер вывода, обрежьте или измените размер референсного изображения перед загрузкой.image[] принимает 1-3 референсных изображения, и порядок загрузки — это то, к чему в prompt относятся «изображение 1 / изображение 2 / изображение 3». Укажите это явно, например: «поместите объект из изображения 1 в сцену из изображения 2, сохранив художественный стиль изображения 2».Примеры кода
Python (OpenAI SDK, одно изображение)
from openai import OpenAI
import urllib.request
client = OpenAI(
api_key="sk-your-api-key",
base_url="https://api.apiyi.com/v1",
timeout=360.0
)
# The SDK's images.edit already performs a multipart upload — pass the file object directly
resp = client.images.edit(
model="grok-imagine-image",
image=open("fox.jpg", "rb"),
prompt="Change the scarf color to bright RED. Keep everything else exactly the same.",
n=1
)
urllib.request.urlretrieve(resp.data[0].url, "edited.jpg")
Python (raw requests, одно изображение)
import requests
import urllib.request
API_KEY = "sk-your-api-key"
# Key point: use files= so requests sets multipart/form-data and the boundary for you.
# Never use json= — that sends application/json and the gateway rejects it with 400.
with open("fox.jpg", "rb") as fp:
response = requests.post(
"https://api.apiyi.com/v1/images/edits",
headers={"Authorization": f"Bearer {API_KEY}"}, # do NOT set Content-Type manually
data={
"model": "grok-imagine-image",
"prompt": "Change the scarf to red, keep everything else exactly the same",
"n": 1,
"response_format": "url"
},
files={"image": ("fox.jpg", fp, "image/jpeg")},
timeout=360
).json()
urllib.request.urlretrieve(response["data"][0]["url"], "edited.jpg")
Python (слияние нескольких изображений, 1-3 файла)
import requests
API_KEY = "sk-your-api-key"
# Repeat the image[] field for multiple references — order is "image 1 / image 2"
files = [
("image[]", ("character.jpg", open("character.jpg", "rb"), "image/jpeg")),
("image[]", ("scene.jpg", open("scene.jpg", "rb"), "image/jpeg")),
]
response = requests.post(
"https://api.apiyi.com/v1/images/edits",
headers={"Authorization": f"Bearer {API_KEY}"},
data={
"model": "grok-imagine-image",
"prompt": "Put the character from image 1 into the scene from image 2, "
"keeping image 2's art style and palette",
"response_format": "url"
},
files=files,
timeout=360
).json()
print(response["data"][0]["url"])
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=grok-imagine-image" \
-F "prompt=Change the scarf to red, keep everything else exactly the same" \
-F "n=1" \
-F "response_format=url" \
-F "[email protected]"
# Multi-image fusion: repeat image[], order is "image 1 / image 2"
curl -X POST "https://api.apiyi.com/v1/images/edits" \
-H "Authorization: Bearer sk-your-api-key" \
-F "model=grok-imagine-image-quality" \
-F "prompt=Put the character from image 1 into the scene from image 2, keep image 2's style" \
-F "image[][email protected]" \
-F "image[][email protected]"
Node.js (нативный fetch + FormData)
import fs from 'node:fs';
const form = new FormData();
form.append('model', 'grok-imagine-image');
form.append('prompt', 'Change the scarf to red, keep everything else exactly the same');
form.append('n', '1');
form.append('response_format', 'url');
// Single image uses `image`; for fusion append `image[]` repeatedly (max 3)
form.append('image', new Blob([fs.readFileSync('./fox.jpg')]), 'fox.jpg');
const resp = await fetch('https://api.apiyi.com/v1/images/edits', {
method: 'POST',
// Do not set Content-Type manually — let FormData supply the boundary
headers: { 'Authorization': 'Bearer sk-your-api-key' },
body: form,
signal: AbortSignal.timeout(360000)
});
const data = await resp.json();
const img = await fetch(data.data[0].url);
fs.writeFileSync('edited.jpg', Buffer.from(await img.arrayBuffer()));
JavaScript в браузере
// ⚠️ Demo only: a front-end key is exposed — use a backend proxy in production
const fileInput = document.querySelector('#file'); // an <input type="file"> element
const form = new FormData();
form.append('model', 'grok-imagine-image');
form.append('prompt', 'Replace the background with a snowy pine forest at night, keep the subject');
form.append('response_format', 'url');
form.append('image', fileInput.files[0]);
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.querySelector('#preview').src = data.data[0].url;
Справочник параметров
| Параметр | Тип | Обязательно | Значение по умолчанию | Описание |
|---|---|---|---|---|
model | string | ✅ | — | grok-imagine-image ($0.02/изображение) или grok-imagine-image-quality ($0.045/изображение) |
prompt | string | ✅ | — | Инструкция по редактированию. Укажите, что нужно изменить, и что всё остальное должно остаться без изменений |
image | file | ✅ | — | Файл эталонного изображения. Для fusion повторите image[], 1-3 файла |
n | integer | ❌ | 1 | Выходные изображения, 1-10, тарифицируются за каждое изображение, независимо от количества эталонных изображений |
response_format | string | ❌ | url | url возвращает прямую ссылку; b64_json возвращает необработанный base64 (без data: префикса) |
resolution | string | ❌ | — | Здесь нет эффекта — результат следует за входным изображением |
aspect_ratio | string | ❌ | — | Здесь нет эффекта — результат следует за входным изображением |
Поведение редактирования и стиль промпта
Эндпоинт редактирования сохраняет художественный стиль, композицию, палитру и идентичность объекта входного изображения, изменяя только то, что указано в prompt. Для стабильных результатов:| Стиль prompt | Результат |
|---|---|
✅ Change the scarf to red, keep everything else exactly the same | Меняется только шарф; стиль, композиция и фон сохраняются |
✅ Add round black sunglasses to the cat, keep everything else unchanged | Добавляются только солнечные очки; стиль контуров и цвет фона остаются без изменений |
✅ Put the character from image 1 into the scene from image 2, keep image 2's style | Слияние, сохраняющее характеристики обоих входных изображений |
⚠️ Make it look better | Слишком расплывчато — область изменений становится непредсказуемой |
image[].Формат ответа
{
"created": 0,
"data": [
{
"url": "https://apac.ossforai.com/2026/08/12/09b026d5-3492-4678-907c-e25972e6c914.jpg"
}
],
"usage": {
"prompt_tokens": 1000,
"total_tokens": 1000
}
}
- Каждая запись
data[]содержит либоurlилиb64_jsonв зависимости отresponse_format— никогда оба. revised_promptне возвращается — не предполагайте, что оно существует.b64_json— это необработанный base64 без префиксаdata:image/...;base64,— декодируйте его напрямую.createdвсегда0и не может использоваться как временная метка.- Размеры вывода определяются входным изображением, поэтому не определяйте ширину/высоту по параметрам запроса.
usage не может использоваться для сверки: prompt_tokens всегда 1000 x n, это заполнитель. Редактирование стоит столько же, сколько text-to-image, по фиксированной ставке за изображение; используйте записи тарификации в APIYI Console для фактических списаний.Авторизации
API Key created in the APIYI Console
Тело
Model ID
grok-imagine-image, grok-imagine-image-quality Editing instruction. State what to change and explicitly ask for everything else to stay put,
e.g. Change the scarf color to bright RED. Keep everything else exactly the same.
"Change the scarf color to bright RED. Keep everything else exactly the same."
Reference image file. For multi-image fusion repeat the image[] field (1-3 files);
upload order is what "image 1 / image 2 / image 3" refers to in the prompt.
Accepted formats: png / jpg / webp.
Number of output images, 1-10. Independent of the number of reference images
1 <= x <= 101
Response format. url returns a direct link; b64_json returns raw base64 (no data: prefix)
url, b64_json "url"
Ответ
Image generated successfully
Creation timestamp. Always 0 for this model — do not use it for timing
0
Array of image results, length equals the requested n
Show child attributes
Show child attributes
Placeholder values — do not use for billing reconciliation. prompt_tokens is always 1000 x n
Show child attributes
Show child attributes
Была ли эта страница полезной?