Руководство
Как использовать режим «изображение в изображение» gpt-image-2 через API hiapi
Готовый к запуску рецепт кода, который показывает, как вызвать эндпоинт «изображение в изображение» gpt-image-2 на hiapi: оболочка запроса, параметры reference image и aspect_ratio, выбор между опросом и callback, а также готовые к копированию примеры на curl, Python и Node.js.
Этот рецепт шаг за шагом показывает, как вызвать режим «изображение в изображение» gpt-image-2 через единый API задач hiapi. Вы получите готовый к запуску пример на curl, скрипт на Python, который можно напрямую встроить в бэкенд, версию на Node.js для бессерверных сценариев, а также действительно важные параметры и детали, на которых легко споткнуться в продакшене.
После прочтения статьи у вас будет скрипт, который принимает URL референсного изображения и промпт и возвращает URL сгенерированного изображения — вы можете сразу его скачать или передать своему слою хранения.
Подготовка
- Аккаунт hiapi и API-ключ. Получить можно в консоли hiapi.
- Референсное изображение, размещённое по публичному HTTPS URL (или base64 data URL — подойдёт любой вариант).
- Текстовый промпт, описывающий, что вы хотите, чтобы модель сделала с этим референсным изображением.
Вот и всё. Устанавливать SDK не нужно — hiapi это HTTP + JSON, подойдёт любой язык, умеющий отправлять POST-запросы.
Хотите сначала разобраться с генерацией изображений только по тексту? Смотрите Как генерировать изображения с помощью API hiapi. Схема ниже — тот же асинхронный процесс задач, только с дополнительным полем
image.
Минимальный рабочий вызов
hiapi предоставляет все модели изображений через один и тот же интерфейс асинхронных задач:
POST /v1/tasks— отправить задачу, получитьtaskId.- Либо опрашивать
GET /v1/tasks/{taskId}, покаstatus === "success", либо указатьcallback.url, чтобы получить итоговый результат через webhook. - Прочитать URL изображения из
data.output[0].urlи скачать или сохранить его.
curl
curl -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer sk-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2/image-to-image",
"input": {
"prompt": "transform the subject into a watercolor painting, soft pastel palette",
"image": "https://example.com/reference.jpg",
"aspect_ratio": "1:1",
"resolution": "1K"
}
}'
Немедленный ответ вернёт вам идентификатор задачи:
{ "data": { "taskId": "task_01HXXXX..." } }
Затем опрашивайте результат:
curl https://api.hiapi.ai/v1/tasks/task_01HXXXX... \
-H "Authorization: Bearer sk-YOUR_KEY"
Когда задача готова, ответ выглядит так:
{
"data": {
"status": "success",
"output": [{ "url": "https://cdn.hiapi.ai/...png", "expireAt": "..." }]
}
}
output[0].url действует ограниченное время (обратите внимание на expireAt), поэтому сразу скачайте его или перезагрузите в собственное хранилище — никогда не давайте конечным пользователям горячие ссылки.
Действительно важные параметры
| Поле | Тип | Описание |
|---|---|---|
model |
string | Используйте голый id gpt-image-2/image-to-image. Не добавляйте префикс models/. |
input.prompt |
string | Преобразование, которое вы хотите применить к референсному изображению. |
input.image |
string | HTTPS URL или URL вида data:image/...;base64,.... |
input.aspect_ratio |
string | Одно из значений: 1:1, 3:2, 2:3, 4:3, 3:4, 5:4, 4:5, 16:9, 9:16, 21:9 или auto. |
input.resolution |
string | 1K, 2K или 4K. По умолчанию 1K. |
Два важных поведения:
- Некоторые модели hiapi принимают только
aspect_ratio(безresolution); другим нужны пиксельные размеры. gpt-image-2/image-to-image принимает комбинациюaspect_ratio+resolution, показанную выше — не передавайте здесьsize: "1024x1024". - Поле
image— это референсное изображение. Если вы передаёте base64 data URL, убедитесь, что payload меньше лимита тела запроса вашей платформы (несколько МБ — нормально; изображения размером в несколько мегабайт следует сначала загрузить, а затем передавать по URL).
Продакшен-скрипт на Python
Эта версия опрашивает результат с учётом дедлайна и корректно завершается при ошибке:
import os
import time
import requests
API = "https://api.hiapi.ai/v1/tasks"
TOKEN = os.environ["HIAPI_API_KEY"]
HEADERS = {"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"}
def submit(prompt: str, image_url: str, aspect_ratio: str = "1:1") -> str:
payload = {
"model": "gpt-image-2/image-to-image",
"input": {
"prompt": prompt,
"image": image_url,
"aspect_ratio": aspect_ratio,
"resolution": "1K",
},
}
r = requests.post(API, headers=HEADERS, json=payload, timeout=30)
r.raise_for_status()
return r.json()["data"]["taskId"]
def wait(task_id: str, timeout_s: int = 300, interval_s: int = 5) -> str:
deadline = time.time() + timeout_s
while time.time() < deadline:
r = requests.get(f"{API}/{task_id}", headers=HEADERS, timeout=20)
r.raise_for_status()
task = r.json()["data"]
status = task.get("status")
if status == "success":
return task["output"][0]["url"]
if status == "fail":
err = task.get("error") or {}
raise RuntimeError(f"task failed: {err.get('code')} {err.get('message')}")
time.sleep(interval_s)
raise TimeoutError(f"task {task_id} did not finish in {timeout_s}s")
if __name__ == "__main__":
task_id = submit(
prompt="transform the subject into a watercolor painting, soft pastel palette",
image_url="https://example.com/reference.jpg",
)
print("task:", task_id)
print("url:", wait(task_id))
Запустите с помощью HIAPI_API_KEY=sk-... python recipe.py.
Node.js (fetch, без зависимостей)
const API = "https://api.hiapi.ai/v1/tasks";
const TOKEN = process.env.HIAPI_API_KEY;
const headers = {
Authorization: `Bearer ${TOKEN}`,
"Content-Type": "application/json",
};
async function submit(prompt, imageUrl, aspectRatio = "1:1") {
const r = await fetch(API, {
method: "POST",
headers,
body: JSON.stringify({
model: "gpt-image-2/image-to-image",
input: { prompt, image: imageUrl, aspect_ratio: aspectRatio, resolution: "1K" },
}),
});
const data = await r.json();
if (!r.ok) throw new Error(JSON.stringify(data));
return data.data.taskId;
}
async function wait(taskId, timeoutMs = 300000, intervalMs = 5000) {
const deadline = Date.now() + timeoutMs;
while (Date.now() < deadline) {
const r = await fetch(`${API}/${taskId}`, { headers });
const task = (await r.json()).data;
if (task.status === "success") return task.output[0].url;
if (task.status === "fail") throw new Error(JSON.stringify(task.error));
await new Promise((res) => setTimeout(res, intervalMs));
}
throw new Error(`task ${taskId} timed out`);
}
(async () => {
const id = await submit(
"transform the subject into a watercolor painting, soft pastel palette",
"https://example.com/reference.jpg",
);
console.log("task:", id, "\nurl:", await wait(id));
})();
Опрос vs. Callback
Опрос каждые 5 секунд подходит для одноразового скрипта, но он занимает worker на всё время выполнения задачи. В реальном бэкенде обычно нужен webhook:
{
"model": "gpt-image-2/image-to-image",
"input": { "prompt": "...", "image": "https://example.com/reference.jpg" },
"callback": { "url": "https://your-app.example.com/api/hiapi-callback", "when": "final" }
}
Когда задача завершается (успешно или с ошибкой), hiapi отправит на этот URL POST с тем же payload, который вы получили бы от GET /v1/tasks/{id}. Рассматривайте этот обработчик как идемпотентный — возможны повторные попытки — и проверяйте запрос, прежде чем ему доверять (свой подписанный токен в URL, проверка заголовка Authorization и т. п.).
Чистая схема такова: отправить задачу, сохранить taskId под своим job id, вернуть вызывающей стороне 202 Accepted, а обработку сохранения и уведомлений поручить webhook.
Обработка ошибок
На практике вы столкнётесь с тремя типами сбоев:
401 permission_deniedс сообщением"This API key cannot use the selected model."— у ключа нет прав на использованиеgpt-image-2/image-to-image. Проверьте в консоли hiapi и убедитесь на странице тарифов, что модель входит в ваш план.400с сообщениемadditional properties not allowed— вы отправили поле, которое конкретная модель не принимает (например,sizeвместоaspect_ratio). Сообщение об ошибке укажет проблемный ключ; удалите его и повторите попытку.status: "fail"при опросе с объектомdata.error— сама модель отклонила ввод (небезопасный контент, недоступный референсный URL и т. п.). Запишитеerror.codeиerror.messageв логи, не повторяйте автоматически вслепую.
Всегда задавайте таймаут запроса для вызова POST /v1/tasks (30 секунд достаточно — он быстро возвращает taskId), а также отдельный, более длительный таймаут для цикла опроса или пути приёма webhook.
Полезные ссылки
- Страница модели gpt-image-2 — матрица возможностей и уровни тарифов.
- Все модели hiapi — полный каталог, если вам нужны другие модели изображений или видео.
- Документация API — полный справочник по
/v1/tasksи всему интерфейсу. - Как генерировать изображения с помощью API hiapi — «сестринский» рецепт по генерации изображений по тексту.
Частые вопросы
Вопрос: поддерживает ли gpt-image-2/image-to-image несколько референсных изображений?
Ответ: минимальный контракт использует одно поле image. Если вашему сценарию нужно несколько референсных изображений (например, изображение субъекта + изображение стиля), сначала объедините их в одно или проверьте страницу модели на предмет актуально поддерживаемых полей.
Вопрос: могу ли я передать локальный файл вместо URL?
Ответ: да — закодируйте его в URL вида data:image/png;base64,... и передайте как input.image. Для файлов размером более примерно 3 МБ сначала загрузите их в собственное хранилище и передайте публичный URL; так быстрее и не упираешься в лимит тела запроса.
Вопрос: сколько времени занимает одна задача?
Ответ: большинство задач «изображение в изображение» gpt-image-2 при разрешении 1K завершаются за 10–30 секунд. Более высокие разрешения и сложные промпты могут занять больше времени — для надёжности задайте таймаут опроса в 5 минут.
Вопрос: как управлять степенью отличия результата от референсного изображения? Ответ: явно формулируйте это в промпте. «Keep the subject's pose and composition, only restyle to watercolor» даёт более строгое соответствие, чем «make this a watercolor». Режим «изображение в изображение» gpt-image-2 управляется промптом — в оболочке запроса нет отдельного ползунка «strength».
Вопрос: является ли output[0].url постоянным?
Ответ: нет. У него есть метка времени expireAt (обычно несколько часов). Как только задача успешно завершится, как можно скорее скачайте байты и загрузите их в собственное хранилище (R2, S3 и т. п.).
Вопрос: сколько стоит одно изображение? Ответ: зависит от вашего плана и разрешения. Актуальную стоимость за вызов смотрите на странице тарифов.
Похожие статьи
Все статьи →-
Руководство
Как вызвать hailuo-2.3-fast/image-to-video через HiAPI API: практика с curl и Python
Первый рабочий запрос к быстрому и недорогому уровню генерации видео по изображению — от ID модели до загрузки MP4
-
Руководство
Как вызывать hailuo-2.3/text-to-video через API HiAPI: curl, Python и рабочие примеры запросов
-
Руководство
Использование Kandinsky 6.0 Pro для преобразования текста в видео на HiAPI: руководство по curl и Python
Практическая демонстрация с упором на запросы: построение вызова от промпта до видеоклипа, отправка запроса, опрос статуса завершения и скачивание результата