---
title: Изображения
description: Вызов POST /v1/images/generations — промпт, число картинок и размер, форма ответа и то, что генерация считается в изображениях, а не в токенах.
keywords: изображения, генерация, images, b64_json, size, n
group: gateway
---

## Быстро {#quick keywords="curl, python, node, промпт"}

Одна операция делает изображения по текстовому промпту. Конверты запроса, ответа и отказа — OpenAI-совместимые.

:::code-group
```bash title=curl
curl https://api.kumorouter.com/v1/images/generations \
  -H "Authorization: Bearer $KUMO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "<model>",
    "prompt": "Маяк в тумане, тушь на бумаге",
    "n": 1,
    "size": "1024x1024"
  }'
```
```python title=Python
import base64
import os

import requests

response = requests.post(
    "https://api.kumorouter.com/v1/images/generations",
    headers={"Authorization": f"Bearer {os.environ['KUMO_API_KEY']}"},
    json={
        "model": "<model>",
        "prompt": "Маяк в тумане, тушь на бумаге",
        "n": 1,
        "size": "1024x1024",
    },
    timeout=300,
)

for index, entry in enumerate(response.json()["data"]):
    if "b64_json" in entry:
        with open(f"image-{index}.png", "wb") as file:
            file.write(base64.b64decode(entry["b64_json"]))
    else:
        print(entry["url"])
```
```javascript title=Node
const response = await fetch("https://api.kumorouter.com/v1/images/generations", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.KUMO_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "<model>",
    prompt: "Маяк в тумане, тушь на бумаге",
    n: 1,
    size: "1024x1024",
  }),
});

const body = await response.json();
const images = body.data.map((entry) =>
  entry.b64_json ? Buffer.from(entry.b64_json, "base64") : entry.url,
);
```
:::

## Члены запроса {#request keywords="prompt, n, size, model"}

| Член | Что это |
| --- | --- |
| `model` | Обязателен. Публичное имя модели, которой генерировать. |
| `prompt` | Обязателен. Текст, по которому делается изображение; до 32 000 символов. |
| `n` | Сколько изображений сделать, от 1 до 10. Без него — одно. |
| `size` | Размер как `ШИРИНАxВЫСОТА`, например `1024x1024`. |

Других членов у этой операции нет. Правки и вариации она не обслуживает.

## Ответ {#response keywords="created, data, b64_json, url"}

| Член ответа | Что это |
| --- | --- |
| `created` | Когда изображения были сделаны, отметкой времени Unix в секундах. |
| `data` | Готовые изображения, в том порядке, в каком их отдал поставщик. |

Член `data` несёт `b64_json` — байты изображения в base64 — либо `url`, по которому изображение можно забрать. Оба члена необязательны, поэтому клиент читает тот, который пришёл, а не тот, которого он ждал.

```json title=Ответ
{
  "created": 1756900000,
  "data": [{ "b64_json": "iVBORw0KGgoAAAANSUhEUg..." }]
}
```

Отказ приходит в OpenAI-совместимом конверте: `error.message`, `error.type` и `error.code`, а `param` здесь всегда `null` — поля запроса эта поверхность не называет.

## Как это считается {#billing keywords="изображения, единицы, лимиты, оценка"}

Генерация изображений считается **в изображениях, а не в токенах**, и списывается через ту же цепочку допуска, резерва и расчёта, что и любая другая модельная поверхность.

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

> [Как устроены потолки →](/ru/limits)

## Что дальше {#next keywords="ошибки, лимиты, каталог"}

:::cards
- [Ошибки](/ru/errors) — конверт отказа и коды ответа.
- [Лимиты](/ru/limits) — потолки запросов и токенов.
- [Каталог моделей](/ru/models) — какие модели умеют генерировать изображения.
- [Справочник API](/ru/api-reference) — операция член за членом, прямо из описания API.
:::
