Skip to main content
API асинхронных задач состоит из двух эндпоинтов и одного конверта запроса. Вы отправляете задачу, сразу получаете идентификатор, а генерация выполняется на стороне WideRouter. Пока модель работает, вашему запросу не нужно оставаться подключённым.
Используйте этот API, если в противном случае вам пришлось бы удерживать HTTP-соединение открытым в течение 20–50 секунд. Если у вас уже есть рабочая синхронная интеграция, ознакомьтесь с разделом Выбор синхронного или асинхронного режима перед миграцией.

Эндпоинты

Обратите внимание: при создании путь имеет форму множественного числа, а при чтении — единственного числа. Эндпоинтов для получения списка, отмены или удаления нет.

Создание задачи

Тело запроса всегда представляет собой один и тот же конверт с тремя ключами: model, input и необязательный callback_url.
Ответ содержит три поля и приходит значительно меньше чем за секунду:

Поля конверта

Неизвестные ключи на уровне конверта в настоящее время принимаются и игнорируются — не полагайтесь на это и не указывайте там параметры генерации. Их следует указывать в input.

Объект input

input содержит параметры генерации, и набор принимаемых им полей зависит от модели. Конверт вокруг него фиксирован, а содержимое — нет. Проверка внутри input выполняется строго: любой нераспознанный моделью ключ сразу отклоняется, поэтому опечатка будет явно обнаружена, а не останется незамеченной:

Серия Nano Banana

Полный список полей, уровни разрешения, соотношения сторон и редактирование изображений.

Опрос результата

Завершённая задача выглядит так:

Поля задачи

Ответ расширяется по мере продвижения задачи — outputs и expires_at просто отсутствуют, пока задача ещё выполняется. Читайте поля с учётом возможного отсутствия, а не предполагая фиксированную структуру, и сначала проверяйте status.

Поток состояний

Оба конечных состояния являются окончательными, а эндпоинт чтения идемпотентен: повторные чтения завершённой задачи возвращают побайтно идентичный JSON.

Как долго ждать

Отправка занимает доли секунды и сохраняет такую скорость под нагрузкой: измеренный p50 — 0,88 с, p95 — 0,92 с для 30 задач при 12 параллельных запросах. Основное время занимает сама генерация — примерно 12–50 секунд в зависимости от модели и разрешения, из которых 0–11 секунд приходится на нахождение в очереди. Показатели для каждой модели приведены на её странице.
Выполняйте опрос каждые 2–3 секунды, а не в плотном цикле. Один запрос чтения сам по себе занимает около 0,9 с в оба конца, поэтому более частый опрос ничего не даёт и лишь расходует лимит запросов.

Скачивание результатов

outputs содержит обычные URL https без подписи и строки запроса, обслуживаемые CDN доставки WideRouter — это другое имя хоста, отличное от API. Отсюда следуют два вывода:
1

Они не требуют аутентификации

Не отправляйте им свой API-ключ и считайте сам URL секретом. Любой, у кого есть ссылка, может получить изображение, пока она действует.
2

Они истекают через 24 часа

expires_at всегда равен created_at плюс 86400. Скопируйте всё, что нужно сохранить, в собственное хранилище — не сохраняйте URL результатов как постоянные ссылки.
При скачивании отправляйте заголовок User-Agent. CDN находится за WAF, который отвечает простым 403 на запросы без User-Agent и на запросы со значением по умолчанию Python-urllib/3.x. Это выглядит в точности как истёкшая ссылка, но таковой не является. Проверено, работает: браузеры, curl, requests, axios, okhttp, Java, Go, Postman. Не работает: обычный urllib.request.urlopen(url) без заголовков.
Изображения возвращаются в формате JPEG и содержат манифест учётных данных контента C2PA. Измеренный размер файлов: около 0.4–0.7 МБ при 1K, 2.4–3.0 МБ при 2K и 7.5–8.2 МБ при 4K. Читайте Content-Type из ответа, вместо того чтобы предполагать расширение файла.

Обратные вызовы

Укажите callback_url при создании, и WideRouter отправит на него завершённую задачу, поэтому вы можете полностью отказаться от опроса.
URL должен быть https. Любое другое значение — http, имя хоста без схемы или нестроковое значение — отклоняется при отправке с ошибкой invalid_callback_url, поэтому опечатки обнаруживаются сразу, а не приводят к тому, что данные незаметно никогда не будут доставлены. WideRouter отправляет объект задачи как application/json с заголовками, по которым можно маршрутизировать запрос до разбора тела: Тело побайтно идентично тому, что GET /v1/task/{task_id} возвращает в этот момент: те же поля и те же значения, поэтому один обработчик может обслуживать оба пути. При тестировании доставка выполнялась немедленно: обратные вызовы для трёх задач поступили в течение секунды после того, как задача достигала completed. Если ваш эндпоинт отвечает кодом 5xx, WideRouter повторяет попытку; наблюдались попытки примерно через 0, 10 и 70 секунд.
Обратные вызовы не подписываются. Заголовка HMAC нет, и URL — единственное подтверждение того, что запрос поступил от WideRouter. Считайте полезную нагрузку подсказкой, а не источником достоверных данных: используйте длинный непредсказуемый путь в вашем callback_url и заставьте обработчик заново прочитать GET /v1/task/{task_id}, прежде чем выполнять какие-либо важные действия.
Обратный вызов — это оптимизация задержки, а не гарантия доставки. Сохраняйте резервный вариант с опросом для задач, обратный вызов которых не поступил, и сделайте обработчик идемпотентным — используйте идентификатор задачи id в качестве ключа, поскольку из-за повторных попыток одна и та же задача может поступить более одного раза.

Если задача завершается с ошибкой

Задача failed по-прежнему является 200 на эндпоинте чтения. Ошибка находится в теле, а не в HTTP-статусе:
Обратите внимание: здесь нет outputs и нет expires_at. Ошибки получения входных данных происходят быстро — менее чем за секунду, — поскольку возникают до начала работы модели.

Ошибки при отправке

Проверка выполняется до постановки чего-либо в очередь, поэтому 400 здесь ничего не стоит. Ошибки указывают на одно поле за раз, а param использует полные пути, включая индексы массивов (input.images[0]), поэтому вы можете сразу сопоставить ошибку с вашим запросом.

Какие модели здесь работают

Идентификаторы моделей сопоставляются точно. Псевдонимов нет, а имена с суффиксом -preview не принимаются. Отправка идентификатора, который не обслуживается асинхронным API, возвращает model_not_supported во время отправки, ещё до постановки чего-либо в очередь.

Серия Nano Banana

Модели изображений Google — доступность на каждом интерфейсе, параметры и измеренная задержка.

Выбор синхронного или асинхронного режима

Доступны оба варианта, и ни один из них не объявлен устаревшим. Асинхронный режим — лучший вариант по умолчанию для всего, что выполняется за бессерверной функцией, обратным прокси или мобильным клиентом, поскольку ни один из этих вариантов не обеспечивает надёжное выполнение запроса длительностью 50 секунд. Синхронные вызовы остаются более простым решением для скрипта, которому нужно просто получить данные.

Следующие шаги

серия Nano Banana

Матрица параметров, уровни разрешения и различия между двумя моделями.

Быстрый старт

Один и тот же процесс от начала до конца примерно за пять минут.