
## Сгенерировать изображение

`POST /v1/images/generations`

Создаёт одну картинку по текстовому описанию моделью BitrixGPT 5.6 Image и возвращает её в формате base64. Платформа изображения не хранит, поэтому сохраните картинку на своей стороне.

Картинка учитывается в AI-квоте портала: в рамках квоты тарифа деньги с баланса не списываются, сверх квоты каждая картинка оплачивается с баланса портала по цене из поля `pricing.perCall` модели в [`GET /v1/models`](/docs/ai/models/list). Неудачный вызов не оплачивается. Формат запроса и ответа совместим с `POST /v1/images/generations` из OpenAI API.

> **Ответ приходит в сыром OpenAI-формате.**
>
> Обёртки `{success, data}`, которая используется в остальных эндпоинтах Вайбкод — `/v1/deals`, `/v1/tasks` и других, — здесь нет.
>
> Так сделано для совместимости с OpenAI SDK. Если у вас единый клиент с проверкой `if (!response.success)`, добавьте для AI Router исключение.

## Поля запроса (body)

| Поле | Тип | Обяз. | Описание |
|------|-----|:-----:|----------|
| `model` | string | да | ID модели генерации изображений — `bitrix/bitrixgpt-5.6-image`. В ответе `GET /v1/models` такую модель отличает `capabilities.image_generation` |
| `prompt` | string | да | Описание картинки, от 1 до 4000 символов |
| `size` | string | нет | Ширина и высота в пикселях через латинскую `x`. Стороны задаются независимо: `1024x1024` — квадрат, `1024x576` — широкая картинка, `576x1024` — вертикальная. Каждая сторона — от 64 до 1024 пикселей. Без этого поля сервис генерации отдаёт картинку 1024×1024 |
| `output_format` | string | нет | Формат картинки: `png`, `jpeg` или `webp` |
| `negative_prompt` | string | нет | Что не должно появиться на картинке, до 4000 символов |
| `seed` | integer | нет | Зерно генерации — целое число от `0`. Одинаковые `prompt`, `size` и `seed` дают в точности ту же картинку, поэтому удачный кадр можно сгенерировать заново |
| `num_inference_steps` | integer | нет | Число шагов генерации, от 1 до 8. По умолчанию `4` |
| `response_format` | string | нет | Принимается только `b64_json` |
| `n` | integer | нет | Число картинок. Принимается только `1` — цена считается за вызов |
| `user` | string | нет | Идентификатор конечного пользователя вашего приложения, до 200 символов. Передаётся модели как есть |

Поле вне этого списка отклоняется с `400 invalid_request`.

## Примеры

### curl — личный ключ

```bash
curl -X POST https://vibecode.bitrix24.tech/v1/images/generations \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "bitrix/bitrixgpt-5.6-image",
    "prompt": "Рыжая лиса сидит на камне у озера, акварель",
    "size": "512x512",
    "output_format": "jpeg"
  }'
```

### curl — OAuth-приложение

```bash
curl -X POST https://vibecode.bitrix24.tech/v1/images/generations \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "bitrix/bitrixgpt-5.6-image",
    "prompt": "Рыжая лиса сидит на камне у озера, акварель",
    "size": "512x512",
    "output_format": "jpeg"
  }'
```

### JavaScript — личный ключ

```javascript
const res = await fetch('https://vibecode.bitrix24.tech/v1/images/generations', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'bitrix/bitrixgpt-5.6-image',
    prompt: 'Рыжая лиса сидит на камне у озера, акварель',
    size: '512x512',
    output_format: 'jpeg',
  }),
})

const result = await res.json()
// Адрес вида data: подходит для атрибута src тега img
const dataUrl = `data:image/jpeg;base64,${result.data[0].b64_json}`
console.log('Картинка готова:', dataUrl.slice(0, 60))
```

### JavaScript — OAuth-приложение

```javascript
const res = await fetch('https://vibecode.bitrix24.tech/v1/images/generations', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'bitrix/bitrixgpt-5.6-image',
    prompt: 'Рыжая лиса сидит на камне у озера, акварель',
    size: '512x512',
    output_format: 'jpeg',
  }),
})

const result = await res.json()
const dataUrl = `data:image/jpeg;base64,${result.data[0].b64_json}`
console.log('Картинка готова:', dataUrl.slice(0, 60))
```

## Поля ответа

| Поле | Тип | Описание |
|------|-----|----------|
| `created` | number | Время создания, Unix-время в секундах |
| `data` | array | Сгенерированные картинки. Один вызов — одна картинка |
| `data[].b64_json` | string | Картинка в `base64` |
| `output_format` | string | Формат картинки. Приходит, когда его сообщает сервис генерации |
| `size` | string | Ширина и высота картинки в пикселях, например `512x512`. Поле приходит, когда размер сообщает сервис генерации |

## Пример ответа

Строка `b64_json` сокращена: в настоящем ответе это картинка целиком, для JPEG 512×512 — около 140 КБ.

```json
{
  "created": 1789740000,
  "data": [
    { "b64_json": "/9j/4AAQSkZJRgABAQAAAQABAAD..." }
  ],
  "output_format": "jpeg",
  "size": "512x512"
}
```

## Пример ответа при ошибке

`400 invalid_request` — сторона картинки больше 1024 пикселей:

```json
{
  "error": {
    "message": "size: each side must be between 64 and 1024 pixels",
    "type": "invalid_request_error",
    "code": "invalid_request"
  }
}
```

## Ошибки

| HTTP | Код | Описание |
|------|-----|----------|
| 400 | `invalid_request` | Тело не прошло проверку: неизвестное поле, пустой `prompt`, сторона картинки вне диапазона 64–1024, `n` не равно `1`, `response_format` не `b64_json`. Проверка идёт до квоты и генерации, списания нет |
| 400 | `ai_provider_rejected` | Сервис генерации отклонил запрос своим ответом 400 или 422. Исходный статус приходит в поле `providerStatusCode`. Повторять запрос без изменений бессмысленно |
| 402 | `insufficient_balance` | Предоплатный счёт портала ушёл за овердрафт. Проверяется до генерации |
| 402 | `ai_quota_exhausted` | Месячная AI-квота портала исчерпана, а оплатить картинку сверх квоты нельзя — см. «Известные особенности» |
| 402 | `account_frozen` | Счёт портала заморожен за долг, а картинка выходит за AI-квоту — расход сверх квоты платит баланс. Картинка внутри квоты под заморозкой продолжает работать. Пока сужение отказа не дошло до портала, заморозка закрывает ручку целиком и отвечает конвертом V1 с кодом `ACCOUNT_FROZEN` в верхнем регистре — [состав отказа](/docs/errors) |
| 402 | `company_budget_exhausted` | Исчерпан бюджет расхода компании, который задаёт администратор портала. Поле `scope` называет пробитый бюджет: `USER` — личный бюджет вызывающего, `PORTAL` — бюджет всего портала. Поле `canRequest` говорит, можно ли запросить увеличение. Отказ приходит только на картинках сверх квоты, которые списывают средства с баланса портала |
| 402 | `ai_credentials_not_configured` | На платформе не настроен доступ к сервису генерации |
| 403 | `scope_missing` | API-ключу не хватает скоупа `vibe:ai` |
| 404 | `not_found` | Генерация изображений недоступна вашему ключу или порталу |
| 404 | `ai_model_not_found` | В поле `model` не модель генерации изображений, доступная ключу. Доступные модели — в ответе `GET /v1/models`, у них есть `capabilities.image_generation`. Списания нет |
| 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` |
| 429 | `ai_image_congested` | Сервис генерации занят другими запросами. Запрос не выполнялся, списания нет — повторите через число секунд из заголовка `Retry-After` |
| 429 | `ai_congested` | Пул AI-кластера перегружен. Запрос не выполнялся, списания нет — повторите по заголовку `Retry-After`. Ответ несёт заголовок `X-AI-Admission: shed` |
| 429 | `ai_pacing_limited` | Превышено суточное или недельное окно равномерного расходования квоты. Это не исчерпание квоты — повторите запрос по заголовку `Retry-After`. Подробнее — [«Равномерное расходование»](/docs/ai/consumption/quota#равномерное-расходование-pacing) |
| 429 | `rate_limit_exceeded` | Превышен лимит запросов к AI-эндпоинтам либо сервис генерации ограничил частоту запросов. Во втором случае в ответе есть поле `providerStatusCode`. Время до повтора — в заголовке `Retry-After` |
| 429 | `ai_provider_cooldown` | Сервис генерации временно недоступен, и платформа держит паузу. Запрос не выполнялся, списания нет — повторите через число секунд из `Retry-After` |
| 502 | `ai_provider_unavailable` | Сервис генерации недоступен, ответил внутренней ошибкой или вернул ответ без картинки. Списания нет, повторите запрос |
| 502 | `ai_provider_network` | Платформа не смогла соединиться с сервисом генерации. Списания нет, повторите запрос |
| 503 | `ai_provider_timeout` | Картинка не готова за 60 секунд. Списания нет — повторите через число секунд из `Retry-After` |
| 503 | `ai_cluster_not_configured` | Генерация изображений не настроена на этой установке платформы |

Полный список общих ошибок API — [Ошибки](/docs/errors).

## Известные особенности

**Модель ищется по возможности, а не по имени.** Модель генерации изображений приходит в общем списке `GET /v1/models` вместе с чат-моделями и отличается от них полем `capabilities.image_generation`. Если такой модели в списке нет, генерация изображений вашему ключу или порталу недоступна, и ручка ответит `404`. Вшивать идентификатор модели в код не нужно.

**Только текстовое описание.** Картинку на вход эндпоинт не принимает — поля для изображения-образца в теле запроса нет. Что должно быть на картинке, задаёт `prompt`, чего на ней быть не должно — `negative_prompt`.

**В рамках квоты — без списаний, сверх квоты — по цене за картинку.** Каждая успешная картинка расходует месячную AI-квоту портала. Пока расход укладывается в квоту тарифа, деньги с баланса не списываются. Сверх квоты картинка оплачивается с баланса портала по цене из `pricing.perCall`. Когда квота исчерпана, а оплата сверх неё невозможна, ручка отвечает `402 ai_quota_exhausted`. Поле `reason` различает три случая: `breaker` — сработал часовой предохранитель расходов сверх квоты, `wallet_empty` — на балансе портала нет средств, `wallet_off` — расход сверх квоты для портала недоступен. Поле `resetAt` — момент, когда запросы снова начнут проходить, для `wallet_off` оно может отсутствовать.

**Одновременных запросов ограниченное число.** Сервис генерации обрабатывает ограниченное число запросов одновременно, остальные ждут своей очереди. Когда очередь заполнена, запрос сразу получает `429 ai_image_congested` и в генерацию не попадает. Картинка, которая не готова за 60 секунд, заканчивается ответом `503 ai_provider_timeout`. Чем больше `num_inference_steps` и размер картинки, тем дольше ждёт и ваш запрос, и очередь за ним.

**Картинки не хранятся.** Изображение приходит только в ответе, в поле `data[].b64_json`: ссылок на файлы платформа не выдаёт, повторно скачать картинку с платформы нельзя. Сохраните её сразу после ответа.

## Смотрите также

- [Список моделей](/docs/ai/models/list)
- [Расход и лимиты](/docs/ai/consumption)
- [AI Router](/docs/ai)
