Generations API
Создание генераций, опрос статуса, список задач и загрузка референсов для image-to-image
Generations API — основной эндпоинт IskraGen. Одна и та же схема запроса работает для всех моделей: картинки, видео, озвучка, музыка. Тип медиа и набор параметров определяются выбранной моделью.
Все запросы авторизуются API-ключом (см. Authentication):
Authorization: Bearer isk_live_<prefix>_<secret>
Базовый URL:
https://api.iskragen.ru/v1. Канонический публичный путь —/v1/*. Внутри приложения те же роуты смонтированы под/api/v1/*— это внутренняя деталь, в интеграциях используйте/v1/*.
Модель асинхронная
Генерация — асинхронная операция. POST /v1/generations не ждёт готового медиа: он ставит задачу в очередь, сразу списывает стоимость (hold) и возвращает HTTP 202 с id и статусом PENDING. Готовый результат вы получаете одним из двух способов:
- Polling — опрашивайте
GET /v1/generations/:id, покаstatusне станетSUCCEEDEDилиFAILED. - Webhooks — для длинных задач (видео, музыка) подпишитесь на
generation.succeeded/generation.failedи не опрашивайте вручную.
Жизненный цикл статуса:
PENDING → PROCESSING → SUCCEEDED
↘ FAILED (средства возвращаются на баланс автоматически)
| Статус | Значение |
|---|---|
PENDING | Задача принята и стоит в очереди. |
PROCESSING | Провайдер выполняет генерацию. |
SUCCEEDED | Готово. Результат в outputUrls. |
FAILED | Окончательная ошибка (после всех retry). Списанные средства возвращены. |
POST /v1/generations
Создать генерацию.
Тело запроса
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
modelSlug | string | да | Публичный slug модели IskraGen (например gpt-image-2-text-to-image). Источник правды — каталог (раздел «Discovery» ниже) и «ID модели» в карточке модели. |
prompt | string | да | Текстовый промпт, 1–4000 символов. |
negativePrompt | string | нет | До 2000 символов. |
params | object | нет | Параметры, специфичные для модели (например aspect_ratio, resolution, duration, input_urls). Мёрджатся поверх defaultParams модели. См. раздел «aspect_ratio vs width/height» ниже. |
width | integer | нет | 256–4096. Только для legacy пиксельных моделей (fal/together). Для актуального каталога используйте params.aspect_ratio + params.resolution. |
height | integer | нет | 256–4096. См. width. |
durationSec | integer | нет | 1–600. Длительность для видео/аудио, если модель принимает секунды. |
seed | integer | нет | ≥ 0. Для воспроизводимости. |
idempotencyKey | string | нет | 1–64 символа. Повторный запрос с тем же ключом вернёт ту же генерацию, а не создаст новую. Предпочтительный способ — заголовок Idempotency-Key (см. ниже). |
Заголовки
| Заголовок | Обяз. | Описание |
|---|---|---|
Idempotency-Key | нет | 1–64 символа. Повторный запрос с тем же ключом вернёт ту же генерацию. Если заголовок не передан, используется поле idempotencyKey из тела запроса; если переданы оба и значения различаются — приоритет у заголовка. Значение длиннее 64 символов или пустое → 400. |
curl -X POST https://api.iskragen.ru/v1/generations \
-H "Authorization: Bearer $ISKRAGEN_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-42-retry-1" \
-d '{ "modelSlug": "gpt-image-2-text-to-image", "prompt": "Кот-космонавт" }'
Ответ 202 Accepted
{
"id": "0192f0c4-8a1e-7b3d-9f21-2c5e6a4b7d90",
"status": "PENDING",
"costRub": 6
}
costRub— стоимость, уже зарезервированная (hold) с баланса в момент запроса. ПриFAILEDвозвращается автоматически.id— UUIDv7, передавайте его вGET /v1/generations/:id.
Пример
curl -X POST https://api.iskragen.ru/v1/generations \
-H "Authorization: Bearer $ISKRAGEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"modelSlug": "gpt-image-2-text-to-image",
"prompt": "Кот-космонавт на фоне Сатурна, фотореализм",
"params": { "aspect_ratio": "1:1", "resolution": "1K" }
}'
GET /v1/generations/:id
Получить генерацию по id. Используется для polling'а.
Ответ 200 OK
{
"id": "0192f0c4-8a1e-7b3d-9f21-2c5e6a4b7d90",
"userId": "0192...",
"modelId": "gpt-image-2-text-to-image",
"modelName": "GPT Image 2",
"mediaType": "IMAGE",
"prompt": "Кот-космонавт на фоне Сатурна, фотореализм",
"params": { "aspect_ratio": "1:1", "resolution": "1K" },
"status": "SUCCEEDED",
"outputUrls": ["https://s3.twcstorage.ru/.../result.webp"],
"costRub": 6,
"mediaPriceRub": 6,
"chargeStatus": "SETTLED",
"errorMessage": null,
"errorCode": null,
"startedAt": "2026-07-01T12:00:40.000Z",
"finishedAt": "2026-07-01T12:00:42.000Z",
"createdAt": "2026-07-01T12:00:39.000Z"
}
| Поле | Тип | Описание |
|---|---|---|
status | string | PENDING | PROCESSING | SUCCEEDED | FAILED. |
outputUrls | string[] | Ссылки на результат (S3). Пусто, пока status ≠ SUCCEEDED. |
errorCode / errorMessage | string | null | Заполняются при FAILED. |
mediaPriceRub | number | null | Реальная цена медиа (когда доступна). |
chargeStatus | string | null | Статус списания (HELD / SETTLED / REFUNDED). |
startedAt / finishedAt | string | null | ISO-8601 UTC. |
Пример polling'а (Node.js)
async function waitForResult(id) {
for (;;) {
const res = await fetch(`https://api.iskragen.ru/v1/generations/${id}`, {
headers: { Authorization: `Bearer ${process.env.ISKRAGEN_API_KEY}` },
});
const gen = await res.json();
if (gen.status === "SUCCEEDED") return gen.outputUrls;
if (gen.status === "FAILED") throw new Error(`${gen.errorCode}: ${gen.errorMessage}`);
await new Promise((r) => setTimeout(r, 2000)); // 2 сек между опросами
}
}
GET /v1/generations
Список генераций пользователя, cursor-пагинация (новые первыми).
Query-параметры
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
limit | integer | 20 | 1–100. |
cursor | string | — | Значение nextCursor из предыдущей страницы. |
status | string | — | Фильтр: PENDING | PROCESSING | SUCCEEDED | FAILED. |
modelId | string | — | Один или несколько modelId через запятую. |
Ответ 200 OK
{
"items": [ { "id": "0192...", "status": "SUCCEEDED", "outputUrls": ["..."], "createdAt": "..." } ],
"nextCursor": "0192f0c4-8a1e-7b3d-9f21-2c5e6a4b7d90"
}
Когда nextCursor равен null — страниц больше нет.
Discovery: slug и параметры
Список моделей, их публичные slug'и, дефолтные параметры и JSON-схему параметров отдаёт публичный каталог (без авторизации):
curl https://api.iskragen.ru/v1/catalog
{
"total": 22,
"models": [
{
"slug": "gpt-image-2-text-to-image",
"displayName": "GPT Image 2",
"mediaType": "IMAGE",
"sellPriceRub": 6,
"supportsImg2Img": true,
"defaultParams": { "aspect_ratio": "auto", "resolution": "1K" },
"paramsSchema": { "...": "..." }
}
]
}
slug→ это значение и естьmodelSlugдляPOST /v1/generations.defaultParams— что подставится, если вы не передали поле вparams.paramsSchema— допустимые ключи и значенияparamsдля конкретной модели.
Те же данные человекочитаемо есть в каталоге /models и в карточке каждой модели.
aspect_ratio vs width/height
Это частый источник путаницы. Правило простое:
- Актуальный каталог (KIE-модели) задаёт размер через
params:params.aspect_ratio— соотношение сторон ("1:1","16:9","9:16","4:3","3:4","21:9","5:4","3:2","4:5","2:3","auto").params.resolution— качество ("1K","2K","4K"). Влияет на цену.- Верхнеуровневые
width/heightэтими моделями игнорируются.
- Legacy пиксельные модели (fal/together) используют верхнеуровневые
width/heightв пикселях.
Что поддерживает конкретная модель — смотрите в paramsSchema из каталога или в карточке модели. params всегда переопределяют defaultParams; опущенные поля берутся из дефолтов модели.
aspect_ratio: "auto"→ только1K. В режимеautoдоступно единственное разрешение1K; комбинацияauto+2K/4Kне поддерживается. Задайте явное соотношение сторон, если нужно 2K/4K.
Image-to-image: передача референса
Референс не передаётся в теле POST /v1/generations напрямую. Схема в два шага: сначала файл загружается в хранилище IskraGen через presigned URL, затем его ссылка передаётся в params.
Шаг 1 — получить presigned URL
curl -X POST https://api.iskragen.ru/v1/uploads/presign-input \
-H "Authorization: Bearer $ISKRAGEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "contentType": "image/png", "size": 812345 }'
Ответ 200:
{
"url": "https://s3.twcstorage.ru/...&X-Amz-Signature=...",
"key": "users/<userId>/inputs/<uuid>.png",
"finalUrl": "https://s3.twcstorage.ru/.../inputs/<uuid>.png",
"expiresIn": 900
}
contentType— MIME файла (image/jpeg,image/png,image/webp).size— размер в байтах (лимит модели обычно 10 МБ).urlживётexpiresInсекунд (15 минут).
Шаг 2 — загрузить файл (PUT)
curl -X PUT "$PRESIGNED_URL" \
-H "Content-Type: image/png" \
--data-binary @reference.png
Шаг 3 — создать генерацию, передав finalUrl в params
Имя поля зависит от модели (смотрите paramsSchema в каталоге / карточку модели). Для image-to-image моделей это обычно input_urls (массив ссылок):
curl -X POST https://api.iskragen.ru/v1/generations \
-H "Authorization: Bearer $ISKRAGEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"modelSlug": "gpt-image-2-image-to-image",
"prompt": "Тот же кот, но в стиле акварели",
"params": {
"input_urls": ["https://s3.twcstorage.ru/.../inputs/<uuid>.png"],
"aspect_ratio": "1:1",
"resolution": "1K"
}
}'
Дальше — обычный polling GET /v1/generations/:id.
Ошибки
Ошибки возвращаются в едином формате (подробнее — Errors):
{
"error": {
"code": "INSUFFICIENT_BALANCE",
"message": "Insufficient balance",
"requestId": "req_...",
"timestamp": "2026-07-01T12:00:00.000Z"
}
}
Коды, специфичные для Generations API:
| HTTP | code | Когда |
|---|---|---|
| 400 | VALIDATION_ERROR | Некорректное тело: пустой prompt, width/height вне диапазона и т.п. |
| 401 | AUTHENTICATION_ERROR | Нет/неверный API-ключ. |
| 402 | INSUFFICIENT_BALANCE | Не хватает средств. В details — required и available. |
| 403 | MODEL_NOT_AVAILABLE | Модель существует, но недоступна для новых генераций (не в публичном каталоге). |
| 404 | NOT_FOUND | Модель по modelSlug не найдена, либо id генерации чужой/несуществующий. |
| 429 | RATE_LIMIT_ERROR | Превышен лимит 5 одновременных генераций (PENDING+PROCESSING). Дождитесь завершения текущих. |
Что дальше
- Webhooks — уведомления вместо polling'а для длинных задач.
- Errors — полный формат ошибок и коды.
- Rate limits — лимиты запросов и конкурентности.
- Interactive API Reference — все эндпоинты с тестированием в браузере.