Создание картинок в API

Запрос POST /v1/images/generations в форме OpenAI. Параметры модели, входные картинки, ожидание результата, ссылка и base64.

Обновлено: 5 мин чтения

Отправьте запрос

Картинки создаёт адрес POST /v1/images/generations. Тело запроса — JSON, как в API OpenAI Images. Модели с картинками отдаёт GET /v1/models?type=image.

curl https://epicai.ru/v1/images/generations \
  -H "Authorization: Bearer sk-epic-ВАШ_КЛЮЧ" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "nano-banana-2",
    "prompt": "Маяк на скале в шторм, масляная живопись",
    "aspect_ratio": "16:9",
    "resolution": "2K"
  }'
import os
import requests

reply = requests.post(
    "https://epicai.ru/v1/images/generations",
    headers={"Authorization": "Bearer " + os.environ["EPICAI_API_KEY"]},
    json={
        "model": "nano-banana-2",
        "prompt": "Маяк на скале в шторм, масляная живопись",
        "aspect_ratio": "16:9",
        "resolution": "2K",
    },
    timeout=150,
)
reply.raise_for_status()
body = reply.json()
if reply.status_code == 200:
    print(body["data"][0]["url"])
else:
    print("Ещё не готово, задача", body["id"])

Ответ приходит, когда картинка готова.

{
  "created": 1793114499,
  "data": [{"url": "https://epicai.ru/storage/api/7fa4be5e14351e3dff994aa3/1.jpg"}],
  "epicai": {
    "task": "task_7fa4be5e14351e3dff994aa3",
    "price": {"tokens": 25000, "charged": 25000},
    "expires_at": 1793719429
  }
}

В data лежат ссылки на все картинки результата. Поле epicai.task — номер задачи, по которому результат можно запросить позже. В epicai.price стоит цена в TOK, зафиксированная при создании, и списанная сумма. Та же сумма приходит в заголовке x-epic-cost-tok. Если картинка не получилась, TOK не списываются. Цену заранее считает POST /v1/quote, см. статью Цена задачи.

Поля model и prompt обязательны. Предельная длина описания указана в prompt_max у модели, более длинный текст даёт 400 prompt_too_long. Поле n принимает только 1. Для нескольких картинок отправьте несколько запросов или выберите модель, которая возвращает набор сама, например Midjourney.

Задайте параметры модели

У каждой модели свои параметры. Их список и допустимые значения лежат в поле parameters ответа GET /v1/models/{id}, это JSON Schema с полями enum, default, minimum и maximum. Параметр с пометкой x-affects-price меняет цену. Остальные пометки схемы объясняет статья Видео в API.

Значения пишут рядом с model, как size и quality у OpenAI, либо внутри объекта parameters. Одно имя в двух местах даёт 400 invalid_parameter. Параметры, которых в запросе нет, получают значения по умолчанию, как на сайте.

{
  "model": "gpt-image-2",
  "prompt": "Логотип кофейни, минимализм, тёмно-зелёный на белом",
  "size": "1536x1024",
  "quality": "high",
  "output_format": "png",
  "background": "transparent"
}

Неизвестное имя или значение вне списка возвращает 400 invalid_parameter. Поле param ответа называет параметр, например parameters.aspect_ratio, а текст сообщения перечисляет допустимые значения. Параметры с другими типами, объекты и массивы, отклоняются так же.

Добавьте входные картинки

Чтобы изменить картинку или показать образец, передайте массив images. Элемент — ссылка http(s) либо строка data:image/png;base64,…, допустимые типы png, jpeg и webp, размер до 10 МБ.

{
  "model": "nano-banana-2",
  "prompt": "Перекрась стены в мятный цвет, мебель оставь как есть",
  "images": ["https://example.com/room.jpg"],
  "aspect_ratio": "4:3"
}

Сколько картинок принимает модель, написано в поле inputs.image её описания. Если число зависит от параметра, значения лежат в inputs_by. Лишние файлы дают 400 invalid_image с param: images. Ссылка должна быть публичной и открываться без входа, потому что файл скачивает epicai или сама нейросеть. Если не вышло, придёт 400 invalid_image или input_unavailable.

Дождитесь результата или заберите позже

Запрос остаётся открытым, пока картинка не готова. Сервер ждёт около 100 секунд, поэтому поставьте клиенту таймаут больше этого времени, например 150 секунд.

Если картинка не успела, ответ приходит с кодом 202. Тело ответа — задача в статусе queued или in_progress. Адрес задачи стоит в заголовке Location, а Retry-After: 5 подсказывает паузу между опросами. Результат забирает запрос GET /v1/tasks/{id}, как в статье Задачи. Токены остаются зарезервированными и спишутся по готовности.

Не ждать вовсе можно двумя способами, оба сразу возвращают 202 с задачей:

  • заголовок Prefer: respond-async;
  • поле "async": true в теле.

Уведомление о готовности приходит вебхуком, если указать в теле webhook_url. Подробности в статье Вебхуки. Тот же результат создаёт и POST /v1/tasks с полями model, prompt, parameters и images. Он всегда отвечает задачей, сам не ждёт и подходит для моделей любого вида. Для защиты от двойного запуска при повторе запроса добавьте заголовок Idempotency-Key.

Получите картинку в base64

Поле response_format принимает url (по умолчанию) и b64_json. При b64_json каждый элемент data содержит поле b64_json вместо url. Файл больше 48 МБ в base64 не отдаётся. На него придёт 413 result_too_large, а картинку можно скачать по ссылке из задачи.

Скачайте файл вовремя

Ссылки из data открываются без ключа и действуют 7 суток с момента готовности, срок указан в epicai.expires_at. Потом файл стирается, а задача остаётся с признаком expired. Формат файла определяется по содержимому: PNG, JPEG, WebP или GIF. Сохраняйте результат у себя сразу после получения.

Коды ошибок

КодКогда приходит
400 missing_required_parameterНет model или prompt
400 unsupported_modelМодель не создаёт картинки. Видео, музыку и озвучку запускают через POST /v1/tasks
400 unsupported_parameterВ поле n не 1
400 invalid_parameterНеизвестный параметр или недопустимое значение, в том числе response_format
400 content_filterФильтр безопасности нейросети отклонил описание или входную картинку
400 invalid_image, input_unavailable, input_unsupported, input_invalidНейросеть не скачала входную картинку, не приняла её формат или размер
402 insufficient_fundsНа балансе не хватает TOK на цену задачи
429 too_many_active_tasksУ ключа уже 20 задач в работе
502 generation_failed, empty_result, upstream_errorСбой на стороне нейросети. TOK не списаны, запрос можно повторить
504 upstream_timeoutНейросеть не ответила вовремя. TOK не списаны

Если задача завершилась неудачей уже после ответа 202, ту же причину отдаёт поле error задачи со статусом failed. Общий формат ошибок показывает статья Ошибки.

Не нашли ответ?

Посмотрите частые вопросы или напишите в поддержку.

Войти или создать аккаунт

20 000 токенов в подарок новым пользователям. Без карты и без VPN.

или через сервис

Продолжая, вы получаете сервисные письма.

Для защиты от роботов используется Yandex SmartCaptcha. Условия обработки данных.