API
REST поверх HTTPS, JSON в запросах и ответах, даты в ISO 8601 (UTC). Базовый адрес: {{origin}}/v1. Ключ создаётся в кабинете, для работы нужна активная подписка.
Быстрый старт
curl {{origin}}/v1/images \
-H "Authorization: Bearer sk-genaro-…" \
-H "Content-Type: application/json" \
-d '{"prompt": "рыжий кот в шлеме космонавта, студийный свет", "model": "genaro-fast", "wait": true}'
Ответ (задание завершено, wait: true):
{
"data": [{
"id": "img_3f9c1a2b7d4e5f6a8b90",
"object": "image.job",
"status": "succeeded",
"model": "genaro-fast",
"prompt": "рыжий кот в шлеме космонавта, студийный свет",
"aspect_ratio": "1:1",
"upscale": false,
"credits": 1,
"created": "2026-11-06T12:00:00Z",
"finished": "2026-11-06T12:00:48Z",
"source": "api",
"expired": false,
"error": null,
"images": [{"url": "{{origin}}/i/3f9c1a2b7d4e5f6a8b90.jpg", "thumbnail_url": "{{origin}}/i/3f9c1a2b7d4e5f6a8b90.t.webp", "width": 1024, "height": 1024}]
}]
}
Обычно генерация занимает около 30 секунд, в 9 случаях из 10 укладывается в 70 секунд, изредка идёт дольше. В рабочих интеграциях используйте вебхук или опрос, а не долгое ожидание соединения.
Авторизация
Передавайте ключ в заголовке Authorization: Bearer sk-genaro-… или X-API-Key: sk-genaro-…. Ключ привязан к аккаунту и тратит его кредиты. Ключ показывается один раз при создании, на аккаунт можно держать до 10 ключей. Держите ключ на сервере: в браузере и мобильных приложениях он виден всем. Скомпрометированный ключ отзывается в кабинете. Без ключа работают только GET /v1/models и ссылки на готовые файлы.
Модели и кредиты
В запросах указывается id, в таблице рядом показана реальная модель, которая выполняет генерацию. Стоимость задания в кредитах списывается из часового лимита тарифа.
| id | Реальная модель | Для чего | Кредитов | С апскейлом ×2 |
|---|
Форматы: 1:1, 16:9, 9:16, 4:3, 3:4. Длинная сторона результата обычно 1–1,4K, точный размер приходит в полях width и height. Апскейл ×2 доступен моделям с supports_upscale.
GET /v1/models
{
"data": [{
"id": "genaro-pro",
"label": "Genaro Pro",
"underlying_model": "Nano Banana Pro (Google)",
"description": "Лучшее качество: надписи на картинке, портреты, работа по референсу.",
"credits": 4,
"credits_upscale": 8,
"supports_upscale": true,
"aspects": ["1:1", "16:9", "9:16", "4:3", "3:4"]
}]
}
Тарифы и лимиты
| Тариф | Цена | Кредитов в час | Максимум за период | Заданий одновременно |
|---|
- Кредиты в час. Лимит действует на окно с :00 до :59 и обновляется в начале часа, остаток не переносится. Задание резервирует свою цену при создании. Если не хватает, ответ
429 quota_exceededс заголовкомRetry-Afterи полямиcredits_left,credits_needed,resets_at(Unix-время). Неудавшиеся и отменённые задания лимит не тратят. - Параллельность. Сверх лимита одновременных заданий запросы ждут в очереди, очередь между клиентами делится честно: первым идёт тот, кто в этом часу получил меньше.
- Запросы. До 120 запросов в минуту с одного IP-адреса и до 600 в минуту на ключ. Опрос статуса раз в 2–3 секунды в эти лимиты укладывается.
- Запрос на генерацию. Описание до 4000 символов, до 4 референсов по 6 МБ, до 4 картинок за запрос, всё тело запроса до 40 МБ.
- Хранение. Готовые файлы хранятся 14 дней, референсы удаляются сразу после задания.
Создать изображение
POST /v1/images → 202 Accepted, или 200 при wait: true, если все задания успели завершиться. В ответе массив data с объектами заданий.
| Поле | Тип | Описание |
|---|---|---|
prompt | string | Обязательное. Описание, до 4000 символов. Русский и английский. |
model | string | По умолчанию genaro-fast. |
aspect_ratio | string | По умолчанию 1:1. |
n | int | 1–4. Каждая картинка — отдельное задание со своей ценой и id. Цена резервируется за все сразу. |
upscale | bool | Апскейл ×2, цена ×2. Только для моделей с поддержкой. |
seed | int | От 0 до 2147483647. Для повторяемости, если модель поддерживает. |
reference_images | string[] | До 4 референсов: JPEG, PNG, WebP или GIF в base64 либо data:image/…;base64,…, до 6 МБ и 50 млн пикселей каждый. Метаданные (EXIF) удаляются, после задания файлы не хранятся. |
webhook_url | string | Публичный URL, куда придёт готовое задание. |
wait | bool | Ждать результат в этом же запросе, по умолчанию false. |
timeout | int | Сколько секунд ждать при wait: 5–300, по умолчанию 120. Если время вышло, ответ 202 с текущим статусом. |
Python, референс и ожидание результата:
import base64, requests
ref = base64.b64encode(open("face.jpg", "rb").read()).decode()
r = requests.post("{{origin}}/v1/images",
headers={"Authorization": "Bearer sk-genaro-…"},
json={"prompt": "этот же человек в деловом костюме, офис", "model": "genaro-pro",
"aspect_ratio": "3:4", "reference_images": [ref], "wait": True},
timeout=320)
job = r.json()["data"][0]
print(job["status"], job["images"][0]["url"] if job["images"] else job["error"])
JavaScript, задание с вебхуком:
const r = await fetch("{{origin}}/v1/images", {
method: "POST",
headers: { Authorization: "Bearer sk-genaro-…", "Content-Type": "application/json" },
body: JSON.stringify({
prompt: "уютная кофейня, тёплый свет",
model: "genaro-plus",
aspect_ratio: "16:9",
webhook_url: "https://example.com/hook?token=секрет",
}),
});
const { data } = await r.json();
console.log(data[0].id, data[0].status);
Объект задания
| Поле | Тип | Описание |
|---|---|---|
id | string | Идентификатор вида img_…. |
object | string | Всегда image.job. |
status | string | queued, running, succeeded, failed, canceled. |
model, prompt, aspect_ratio, upscale | Параметры запроса. | |
credits | int | Стоимость задания. |
created, finished | string | Время создания и завершения, finished пустое до конца работы. |
source | string | api, compat или web. |
queue_position | int | Место в очереди, только при queued. |
images | array | url, thumbnail_url (webp), width, height. Пусто, пока нет результата и после удаления файлов. |
expired | bool | true, если файлы удалены вами или по сроку хранения. |
error | object | {"code": "generation_failed", "message": "…"} при failed, иначе null. |
Получить результат
Без wait опрашивайте GET /v1/images/{id} раз в 2–3 секунды или используйте вебхук.
while True:
j = requests.get(f"{{origin}}/v1/images/{job_id}", headers=H).json()
if j["status"] in ("succeeded", "failed", "canceled"):
break
time.sleep(2)
Ссылки на изображения не требуют ключа: не публикуйте их, если картинка приватная. Статус failed означает, что кредиты вернулись в лимит часа, причина лежит в error. Запрос можно отправить снова.
Список заданий
GET /v1/images?limit=20&before=ID отдаёт ваши задания, новые первыми. limit 1–100, по умолчанию 20. Для следующей страницы передайте в before id последнего элемента.
{"data": [ /* объекты заданий */ ], "has_more": true}
Отмена и удаление
POST /v1/images/{id}/cancel | Отменяет задание в очереди, кредиты возвращаются. Ответ — объект задания. Задание в работе отменить нельзя: 409 not_cancellable. |
DELETE /v1/images/{id} | Удаляет файлы завершённого задания. Ответ: {"id": "img_…", "deleted": true}. Для незавершённого: 409 in_progress. |
Остаток кредитов
GET /v1/usage
{
"source": "subscription",
"credits_per_hour": 250,
"credits_used": 12,
"credits_left": 238,
"window_resets_at": "2026-11-06T13:00:00Z",
"subscription_ends": "2026-12-06T12:00:00Z",
"plan": "Про"
}
Без активной подписки source равен none, а новые задания получают 402 subscription_required.
Вебхуки
Если указан webhook_url, после завершения (успех или ошибка) мы отправим POST с JSON задания: это тот же объект, что возвращает GET /v1/images/{id}. Ответ с кодом меньше 500 считается доставкой, при ошибке будет до трёх попыток: сразу, через 5 и через 30 секунд. Адрес должен быть публичным, порты только 80, 443, 8080 и 8443, локальные и внутренние сети блокируются, редиректы не выполняются, ответа мы ждём до 10 секунд.
Подписи у вебхуков нет. Чтобы убедиться, что вызов настоящий, зашейте секрет в URL (…/hook?token=…) и перепроверяйте статус через GET.
Идемпотентность
Передайте заголовок Idempotency-Key: <уникальная строка> в POST /v1/images. Повтор запроса с тем же ключом вернёт те же задания и ничего не спишет второй раз, так что повторять при таймаутах сети безопасно.
OpenAI-совместимость
POST /v1/images/generations повторяет формат OpenAI Images API и всегда ждёт результат, до 170 секунд. Работают OpenAI SDK и no-code платформы (n8n, Make, Flowise): укажите наш адрес как базовый и ваш ключ.
| Поле | Описание |
|---|---|
prompt | Обязательное. |
model | Наш id. Также принимаются dall-e-3 (→ genaro-pro), dall-e-2 (→ genaro-fast), gpt-image-1 (→ genaro-text). По умолчанию genaro-fast. |
n | 1–4. |
size | Например 1792x1024, переводится в ближайший формат. |
response_format | url (по умолчанию) или b64_json. |
quality | Принимается и не влияет на результат. |
curl {{origin}}/v1/images/generations \
-H "Authorization: Bearer sk-genaro-…" \
-H "Content-Type: application/json" \
-d '{"model": "genaro-pro", "prompt": "уютная кофейня, тёплый свет", "size": "1792x1024"}'
from openai import OpenAI
client = OpenAI(base_url="{{origin}}/v1", api_key="sk-genaro-…")
image = client.images.generate(model="genaro-pro", prompt="уютная кофейня, тёплый свет", size="1792x1024")
print(image.data[0].url)
Ответ: {"created": 1762430400, "data": [{"url": "…", "revised_prompt": "…"}]}. Если генерация не успела, вернётся 504 timeout с полем job_id: заберите результат через GET /v1/images/{id}.
Ошибки
Тело ошибки: {"error": {"code": "...", "type": "...", "message": "..."}}. Текст сообщения можно показывать пользователю, логику стоит строить по code.
| HTTP | code | Когда | Что делать |
|---|---|---|---|
| 400 | invalid_request | Неверные параметры, сообщение указывает поле. | Исправить запрос. |
| 400 | invalid_model | Нет такой модели. | Взять id из /v1/models. |
| 400 | content_policy | Запрос отклонён фильтром. | Изменить запрос. Пять нарушений блокируют аккаунт. |
| 401 | missing_api_key, invalid_api_key | Нет ключа или он отозван. | Проверить ключ. |
| 402 | subscription_required | Нет активной подписки. | Оформить или продлить. |
| 403 | email_not_verified | Почта не подтверждена. | Открыть ссылку из письма. |
| 403 | account_suspended | Аккаунт заблокирован. | Написать в поддержку. |
| 404 | not_found | Нет такого задания у этого аккаунта. | Проверить id. |
| 409 | not_cancellable, in_progress | Действие невозможно в текущем статусе. | Дождаться завершения. |
| 413 | payload_too_large | Тело запроса больше 40 МБ. | Уменьшить референсы. |
| 429 | quota_exceeded | Не хватает кредитов часа. | Ждать Retry-After. |
| 429 | rate_limited | Слишком много запросов. | Ждать Retry-After, снизить частоту. |
| 502 | generation_failed | Модель не справилась, только в совместимом методе. | Повторить, кредиты вернулись. |
| 503 | service_unavailable, busy | Сервис недоступен или очередь переполнена. | Повторить позже. |
| 504 | timeout | Совместимый метод не дождался результата. | Забрать по job_id. |
В основном API отказ модели приходит статусом failed у задания (чтение при этом отвечает 200), а кредиты возвращаются.
Правила использования
Запрещены откровенный контент для взрослых, любые сексуальные сцены с участием несовершеннолетних, дипфейки реальных людей без согласия, мошенничество и нарушение прав третьих лиц. Подробности — в условиях использования. Не перепродавайте и не публикуйте свой ключ.