Объявление: Ограниченное время: скидка 20% на новинки GPT Image 2.6 Flare и Sunburst, попробуйте сейчас
HiAPI
Блог

Руководство

Как использовать gpt-image-2.5-sunburst/image-to-image через HiAPI API: curl и Python

Готовые к запуску запросы для разработчиков, процесс загрузки референсных изображений и устранение ошибок

Nov 12, 2026
Abstract brutalist concrete planes with raking daylight shadows in warm gray, slate blue and a thin sage seam; cover art for a HiAPI tutorial.
На этой странице

Возможности «изображение в изображение» на этой конечной точке

Конечная точка gpt-image-2.5-sunburst/image-to-image следует простому соглашению: вы отправляете референсное изображение вместе с инструкцией редактирования на естественном языке, а модель возвращает новое изображение, к которому применена эта инструкция, но которое при этом опирается на референс. В отличие от «текст в изображение» — где генерация начинается с нуля и полностью зависит от вашего промпта — режим «изображение в изображение» использует референс как визуальный контекст: композиция, объект, стиль и цветовые подсказки наследуются, если только ваша инструкция явно не требует их изменить.

Это делает его правильным выбором в сценариях, когда у вас уже есть готовый исходный материал и вы хотите контролируемого преобразования: например, изменить стиль фотографии продукта, поменять освещение или фон, скорректировать внешний вид объекта или получить варианты уже существующей концепции. Выбирайте «текст в изображение», когда у вас нет исходного материала и вы хотите максимальной творческой свободы; выбирайте «изображение в изображение», когда верность существующему изображению важнее новизны.

Ключевая ментальная модель, которую должен запомнить разработчик: референсное изображение — это входное ограничение, а инструкция редактирования — это приращение. Хорошая инструкция описывает, что нужно изменить, а не всё, что должно присутствовать. «Замените фон на чистый студийный градиент, сохранив объект и его тень» работает лучше, чем полное описание сцены, потому что референс уже задаёт сцену. Держите это в уме при чтении описания структуры запроса ниже — тело запроса небольшое, но именно качество инструкции определяет качество результата.

Подготовка и структура запроса

Перед первым вызовом убедитесь, что у вас есть три вещи:

  • API-ключ, выданный вашей учётной записью HiAPI. Храните его в переменной окружения, а не в исходном коде.
  • Базовый URL — base URL API HiAPI; см. вашу панель управления или справочную документацию API.
  • Путь конечной точки: gpt-image-2.5-sunburst/image-to-image.

Каждый запрос — это POST с JSON-телом и заголовком Authorization. Концептуально тело запроса состоит из трёх логических частей:

  1. Выбор модели — идентификатор модели для этой конечной точки, чтобы шлюз правильно маршрутизировал вызов.
  2. Входные данные — референсное изображение (размещённый URL или строка данных base64) и текст инструкции редактирования.
  3. Управление выводом — любые необязательные параметры, перечисленные в документации конечной точки, например размер или количество. Используйте только те параметры, которые присутствуют в официальной справочной документации; не угадывайте имена.

Небольшое замечание о дисциплине: поскольку это управляемая конечная точка, то, какие именно поля принимаются, определяется текущей справочной документацией API, а не выводится по аналогии с другими API изображений. Если сомневаетесь, сначала отправьте минимальное допустимое тело запроса (model, image, prompt), убедитесь, что возвращается ответ 200, и только затем добавляйте необязательные поля по одному. Так каждая ошибка будет привязана к одному изменению, а не к собранному наспех телу запроса.

Отправка референсного изображения и инструкции редактирования

Референсное изображение можно передать двумя поддерживаемыми способами, и выбор в основном зависит от того, где хранятся байты изображения.

Размещённый URL

Если изображение уже общедоступно, просто передайте его URL. Тело запроса получается компактным, сериализация быстрой, и это самый простой вариант на этапе разработки. URL должен быть доступен службе напрямую — не за аутентификацией, не в цепочке перенаправлений и не в виде HTML-страницы, которая случайно содержит изображение.

Данные base64

Если изображение локальное или является приватным ресурсом, закодируйте его и отправьте встроенно. Base64 увеличивает тело запроса примерно на треть, поэтому при крупном исходном изображении можно приблизиться к ограничению размера. Если вы близки к пределу, уменьшите разрешение перед кодированием.

Ловушки формата и размера

  • Придерживайтесь распространённых форматов (PNG, JPEG, WebP) и убедитесь, что расширение файла соответствует фактическим байтам.
  • Слишком большие изображения — самая частая причина отказа в запросе. Старайтесь использовать исходные изображения разумного размера; для одного редактирования обычно не нужен материал в полном разрешении.
  • Если вы составляете строку base64 вручную, добавляйте префикс data URI только тогда, когда он присутствует в примерах справочной документации API; иначе его следует убрать. Смешение этих двух соглашений — частая причина ошибки «invalid image».

Составление инструкции редактирования

Качество вывода зависит от инструкции. Конкретно указывайте, что изменить, и явно указывайте, что сохранить. Укажите цель («куртка»), преобразование («перекрасить в тёмно-синий») и ограничение («сохранить позу модели и существующие тени»). Избегайте наслоения нескольких несвязанных правок в одной инструкции — если нужны независимые изменения, разбейте их на несколько вызовов, так каждый результат будет проще оценить.

Рабочий запрос curl

Ниже приведён запрос, который можно полностью выполнить в терминале. Замените заполнители ключа и изображения на свои значения.

curl -X POST "$HIAPI_BASE_URL/gpt-image-2.5-sunburst/image-to-image" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2.5-sunburst/image-to-image",
    "image": "https://your-cdn.example.com/reference.png",
    "prompt": "Замените фон на мягкий нейтральный студийный градиент; сохраните объект, его позу и существующие тени без изменений."
  }'

Разбор по пунктам:

  • -X POST — операция создаёт новое изображение, поэтому используется POST.
  • URL составляется из базового URL и пути конечной точки; хранение базового URL в переменной окружения упрощает переключение между средами.
  • Authorization: Bearer ... — ваш API-ключ. Экспортируйте его как HIAPI_API_KEY, чтобы он не попадал в историю shell или логи.
  • Content-Type: application/json — тело запроса является JSON; пропуск этого заголовка — частая причина непонятных ответов 4xx.
  • model — идентификатор конечной точки. Должен в точности совпадать с документацией.
  • image — референсное изображение, здесь в виде размещённого URL. Чтобы использовать base64, замените его строкой данных или локальной переменной с закодированным значением.
  • prompt — инструкция редактирования. Ограничьтесь описанием того, что меняется, и того, что нужно сохранить.

Если вы хотите протестировать с локальным файлом, не кодируя вручную, большинство оболочек позволяют собрать JSON небольшим скриптом или с помощью jq; главное, чтобы итоговое тело запроса было допустимым JSON с этими полями.

Тот же запрос на Python

Версия на Python сохраняет тело запроса полностью идентичным, чтобы можно было сравнить ответы бок о бок. Используйте requests:

import os
import requests

base_url = os.environ["HIAPI_BASE_URL"]
api_key = os.environ["HIAPI_API_KEY"]

payload = {
    "model": "gpt-image-2.5-sunburst/image-to-image",
    "image": "https://your-cdn.example.com/reference.png",
    "prompt": (
        "Замените фон на мягкий нейтральный студийный градиент; "
        "сохраните объект, его позу и существующие тени без изменений."
    ),
}

response = requests.post(
    f"{base_url}/gpt-image-2.5-sunburst/image-to-image",
    headers={
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json",
    },
    json=payload,
    timeout=120,
)

response.raise_for_status()
print(response.json())

Стоит отметить два момента. Во-первых, json=payload устанавливает тип содержимого и сериализует тело запроса за вас, устраняя целый класс ошибок ручной сборки JSON. Во-вторых, timeout=120 задан намеренно: генерация изображения не мгновенна, и клиент, ожидающий бесконечно, хуже клиента, который чисто завершается с ошибкой. Настройте таймаут под свою нагрузку, но обязательно задайте его.

Чтобы перейти на локальный файл, прочитайте его байты, закодируйте в base64 и присвойте результат image. При использовании размещённого URL оставьте строку как есть. Как только вызовы curl и Python возвращают одинаковую структуру, вы подтвердили, что оба ведут себя согласованно, и можете развивать решение на основе любого из них.

Устранение типичных ошибок запросов

Большинство ошибок сводится к четырём категориям. Проверяйте их в указанном порядке, поскольку каждая категория может маскироваться под следующую.

Ошибки аутентификации

401 или 403 почти всегда означают, что ключ отсутствует, имеет неверный формат или истёк. Проверьте, что заголовок имеет строго вид Authorization: Bearer <key>, убедитесь, что в него не попали лишние кавычки или переводы строк из-за копирования и вставки, и что переменная окружения действительно установлена в оболочке или процессе, выполняющем запрос. Ключ, который работает в curl, но не в Python, обычно указывает на неустановленную переменную, а не на неработающий ключ.

Некорректный формат тела запроса

400 с информацией о валидации обычно означает недопустимый JSON или отсутствие обязательных полей. Перед отправкой красиво отформатируйте тело запроса, убедитесь, что model совпадает с идентификатором конечной точки, и что имя поля инструкции редактирования соответствует документации. При ручном написании JSON в curl классические виновники — висячие запятые и одинарные кавычки; json= в Python позволяет их избежать.

Недопустимое или слишком большое изображение

Если служба отклоняет изображение, проверьте три вещи: URL доступен публично и возвращает именно изображение (а не перенаправление или страницу ошибки), формат поддерживается, а тело запроса не превышает указанное в документации ограничение размера. Для ввода base64 убедитесь, что кодировка чистая и соглашение о префиксе data URI совпадает со справочным примером. Если сомневаетесь, уменьшите разрешение и повторите попытку — меньшее исходное изображение решает значительную часть таких ошибок.

Тайм-ауты и временные сбои

Длительная генерация может превысить тайм-аут клиента, а ответы 429 или 5xx означают срабатывание ограничения частоты или временную проблему сервера. Отличайте их от клиентских ошибок: не повторяйте 400 как есть, но 429 или 503 подходят для повторной попытки с задержкой. Записывайте код состояния и тело ответа при каждом сбое — понятный журнал ошибок превращает отладку из догадок в последовательную проверку.

От скрипта к переиспользуемому клиенту

Одноразовый скрипт доказывает, что конечная точка работает; небольшая обёртка позволяет ей стабильно работать в конвейере. Оберните вызов в функцию, которая отвечает за три вещи: запрос, тайм-аут и стратегию ограниченных повторных попыток.

import os
import time
import requests

class ImageEditClient:
    def __init__(self, base_url: str, api_key: str, timeout: int = 120):
        self.base_url = base_url.rstrip("/")
        self.api_key = api_key
        self.timeout = timeout

    def edit(self, image: str, prompt: str, retries: int = 3):
        url = f"{self.base_url}/gpt-image-2.5-sunburst/image-to-image"
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json",
        }
        payload = {
            "model": "gpt-image-2.5-sunburst/image-to-image",
            "image": image,
            "prompt": prompt,
        }
        last_error = None
        for attempt in range(retries):
            try:
                resp = requests.post(
                    url, headers=headers, json=payload, timeout=self.timeout
                )
            except requests.Timeout as err:
                last_error = err
                time.sleep(2 ** attempt)
                continue
            if resp.status_code in (429, 500, 502, 503, 504):
                last_error = RuntimeError(f"transient {resp.status_code}: {resp.text}")
                time.sleep(2 ** attempt)
                continue
            if resp.status_code >= 400:
                raise RuntimeError(f"request failed {resp.status_code}: {resp.text}")
            return resp.json()
        raise RuntimeError(f"exhausted retries: {last_error}")

Проектные решения важнее самого кода. Повторные попытки применяются только к тайм-аутам и временным кодам состояния и никогда к клиентским ошибкам 4xx, потому что повторная отправка некорректного тела запроса лишь расходует квоту. Экспоненциальная задержка не позволяет конвейеру, ограниченному по частоте, снова и снова обрушиваться на конечную точку. Клиентские ошибки немедленно выбрасываются вместе с телом ответа, чтобы вызывающая сторона точно видела, что именно отвергла служба. А централизация идентификатора модели в одном месте означает, что будущий переход на другую конечную точку изображений потребует изменения одной строки, а не поиска по всей кодовой базе.

На этой основе добавьте структурированное журналирование для каждой попытки и проверку размера/формы ответа до того, как нижестоящий потребитель начнёт его использовать. Когда вы будете готовы изучить другие модели изображений на том же шлюзе, каталог моделей HiAPI — отличное место, чтобы сравнить конечные точки без переписывания клиента.

Похожие статьи

Все статьи →

Начните работать с постоянными артефактами ИИ

Получите API-ключ и вызывайте модели изображений, видео и аудио через один API на основе tasks.

Читать документацию API