> ## Documentation Index
> Fetch the complete documentation index at: https://docs.apimart.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Grok Imagine 2.0 Ext: генерация изображений

>  - Асинхронный text-to-image; опрос результата по task_id
- 1–12 изображений за запрос; тарификация по фактически доставленным ($0.08 / шт.)
- Только вывод url; без image-to-image / streaming
- Ссылки на изображения действительны 72 часа 

<Info>
  **Text-to-image · асинхронные задачи.** Отправьте `POST /v1/images/generations`, затем опрашивайте [Получить статус задачи](/ru/api-reference/tasks/status).\
  Имя модели фиксировано: `grok-imagine-2.0-ext`. **Не поддерживается**: референсные изображения, `stream` и значения `response_format`, кроме `url`.
</Info>

<Warning>
  Не помещайте API-ключи в браузерные бандлы (`VITE_*` / `NEXT_PUBLIC_*`, LocalStorage и т.п.). Из браузера вызывайте свой BFF; ключ APIMart храните на сервере.
</Warning>

<RequestExample>
  ```bash cURL theme={null}
  curl --request POST \
    --url https://api.apimart.ai/v1/images/generations \
    --header 'Authorization: Bearer <token>' \
    --header 'Content-Type: application/json' \
    --header 'Accept: application/json' \
    --header 'Idempotency-Key: 8eacb46d-ef4e-4f4e-82de-830bd8bc67e2' \
    --header 'X-APIMart-Response-Version: 2026-07-27' \
    --data '{
      "model": "grok-imagine-2.0-ext",
      "prompt": "A red apple on a white ceramic plate, clean studio product photo",
      "n": 1,
      "size": "1:1",
      "resolution": "quality",
      "response_format": "url"
    }'
  ```

  ```python Python theme={null}
  import requests
  import uuid

  url = "https://api.apimart.ai/v1/images/generations"

  payload = {
      "model": "grok-imagine-2.0-ext",
      "prompt": "A red apple on a white ceramic plate, clean studio product photo",
      "n": 1,
      "size": "1:1",
      "resolution": "quality",
      "response_format": "url",
  }

  headers = {
      "Authorization": "Bearer <token>",
      "Content-Type": "application/json",
      "Accept": "application/json",
      "Idempotency-Key": str(uuid.uuid4()),
      "X-APIMart-Response-Version": "2026-07-27",
  }

  response = requests.post(url, json=payload, headers=headers)

  print(response.status_code, response.json())
  ```

  ```javascript JavaScript theme={null}
  const url = "https://api.apimart.ai/v1/images/generations";

  const payload = {
    model: "grok-imagine-2.0-ext",
    prompt: "A red apple on a white ceramic plate, clean studio product photo",
    n: 1,
    size: "1:1",
    resolution: "quality",
    response_format: "url",
  };

  const headers = {
    Authorization: "Bearer <token>",
    "Content-Type": "application/json",
    Accept: "application/json",
    "Idempotency-Key": crypto.randomUUID(),
    "X-APIMart-Response-Version": "2026-07-27",
  };

  fetch(url, {
    method: "POST",
    headers: headers,
    body: JSON.stringify(payload),
  })
    .then(async (response) => {
      console.log(response.status, await response.json());
    })
    .catch((error) => console.error("Error:", error));
  ```
</RequestExample>

<ResponseExample>
  ```json 202 theme={null}
  {
    "code": 202,
    "request_id": "2026081111342261665927mpb4IPDb",
    "data": {
      "id": "task_01KZQE5CM0Y3KZ6M1N1BK619MX",
      "object": "generation.task",
      "type": "image",
      "status": "pending",
      "progress": 0,
      "poll_url": "/v1/tasks/task_01KZQE5CM0Y3KZ6M1N1BK619MX"
    }
  }
  ```

  ```json 400 theme={null}
  {
    "request_id": "20260811...",
    "error": {
      "message": "`response_format` for grok-imagine-2.0-ext only supports `url` (got: b64_json)",
      "type": "invalid_response_format",
      "param": "",
      "code": "invalid_response_format"
    }
  }
  ```

  ```json 401 theme={null}
  {
    "error": {
      "code": 401,
      "message": "Ошибка аутентификации. Проверьте ваш API-ключ",
      "type": "authentication_error"
    }
  }
  ```

  ```json 402 theme={null}
  {
    "error": {
      "code": 402,
      "message": "Недостаточно средств. Пополните баланс и повторите попытку",
      "type": "payment_required"
    }
  }
  ```

  ```json 429 theme={null}
  {
    "error": {
      "code": 429,
      "message": "Слишком много запросов. Повторите попытку позже",
      "type": "rate_limit_error"
    }
  }
  ```
</ResponseExample>

## Возможности и ограничения

| Измерение         | Контракт                                                                           |
| ----------------- | ---------------------------------------------------------------------------------- |
| Модель            | Фиксировано `grok-imagine-2.0-ext`                                                 |
| Возможность       | **Только text-to-image**                                                           |
| Режим             | Асинхронная задача                                                                 |
| Количество `n`    | `1`–`12`, по умолчанию `1`                                                         |
| `size`            | 7 соотношений сторон + 5 пиксельных алиасов (ниже)                                 |
| Вывод             | Только `response_format=url` (это же значение по умолчанию)                        |
| Качество          | Публичное поле `resolution`; проверенное значение `quality`                        |
| Не поддерживается | Image-to-image, `stream=true`, публичное `quality`, `style`, `b64_json` / `base64` |
| Тарификация       | Фиксированная цена за единицу; списание за **успешно доставленные** изображения    |

## Аутентификация и рекомендуемые заголовки

<ParamField header="Authorization" type="string" required>
  Bearer-токен. Получите ключ на [странице API Key](https://apimart.ai/keys).

  ```
  Authorization: Bearer YOUR_API_KEY
  ```
</ParamField>

| Header                       | Примечание                                                                                                                                                  |
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Content-Type`               | `application/json` (отправка)                                                                                                                               |
| `Accept`                     | `application/json`                                                                                                                                          |
| `Idempotency-Key`            | Настоятельно рекомендуется. Новый UUID на каждую подтверждённую пользователем генерацию; сетевые повторы **должны повторно использовать** тот же key и body |
| `X-APIMart-Response-Version` | Рекомендуется `2026-07-27` для стабильной формы ответа на submit (`data.id`)                                                                                |

## Параметры запроса

<ParamField body="model" type="string" required>
  Фиксированное значение: `grok-imagine-2.0-ext`
</ParamField>

<ParamField body="prompt" type="string" required>
  Промпт. После trim не должен быть пустым. Выполните trim перед отправкой.
</ParamField>

<ParamField body="n" type="integer" default="1">
  Количество изображений: `1`–`12`. Явный `0` вызывает ошибку. При отсутствии параметра — `1`.
</ParamField>

<ParamField body="size" type="string">
  Соотношение сторон. **Предпочитайте строковые соотношения** (в UI показывайте только соотношения):

  | `size` | Ориентация | Типичное применение             |
  | ------ | ---------- | ------------------------------- |
  | `1:1`  | Квадрат    | Товар, аватар                   |
  | `2:3`  | Портрет    | Постер, полный рост             |
  | `3:2`  | Альбом     | Фото, широкий кадр              |
  | `3:4`  | Портрет    | E-commerce, люди                |
  | `4:3`  | Альбом     | Демонстрационные изображения    |
  | `9:16` | Вертикаль  | Story / обложка короткого видео |
  | `16:9` | Широкий    | Banner, обложка видео           |

  Пиксельные алиасы: `1024x1024` (1:1), `1024x1792` (2:3), `1792x1024` (3:2), `720x1280` (9:16), `1280x720` (16:9).

  Значения вне белого списка возвращают `400 invalid_size` (например `1:2`, `2:1`, `4:5`, `auto`).

  <Note>
    Фактические пиксели для данного соотношения могут отличаться от таблицы алиасов (например, `1:1` может вернуть 1408×1408). Ориентируйтесь на возвращённое изображение; не переписывайте `size` по измеренным пикселям.
  </Note>
</ParamField>

<ParamField body="resolution" type="string">
  Поле режима качества. Проверенное значение: `quality`.

  * Можно опустить (модель по умолчанию в режиме quality), или
  * Явно передать `resolution: "quality"`

  **Не** является уровнем пикселей `1K` / `2K` / `4K`; кадрирование задаётся через `size`.

  <Warning>
    Не отправляйте публичное поле `quality` — получите `400 invalid_quality`. Используйте `resolution`.
  </Warning>
</ParamField>

<ParamField body="response_format" type="string" default="url">
  Допускается только `url`. Можно опустить. `b64_json` / `base64` → `400 invalid_response_format`.
</ParamField>

<ParamField body="webhook" type="string">
  Опциональный публичный HTTPS **base URL**. При терминальном статусе платформа делает POST на `{webhook}/callback`. Только для серверной интеграции — см. [Webhook](#webhook-опционально).
</ParamField>

### Неподдерживаемые параметры

| Параметр                                   | Поведение                                        |
| ------------------------------------------ | ------------------------------------------------ |
| `quality`                                  | `400 invalid_quality` → используйте `resolution` |
| `style`                                    | `400 invalid_style`                              |
| `image_urls` / `image_with_roles`          | `400 invalid_image_input`                        |
| `stream: true`                             | `400 invalid_stream`                             |
| `response_format: "b64_json"` / `"base64"` | `400 invalid_response_format`                    |

Собирайте запросы по белому списку; не пробрасывайте целиком generic-объект формы от других моделей.

## Примеры запросов

### Минимальный

```json theme={null}
{
  "model": "grok-imagine-2.0-ext",
  "prompt": "A red apple on a white ceramic plate, clean studio product photo"
}
```

### Рекомендуемый

```json theme={null}
{
  "model": "grok-imagine-2.0-ext",
  "prompt": "A red apple on a white ceramic plate, clean studio product photo",
  "n": 1,
  "size": "1:1",
  "resolution": "quality",
  "response_format": "url"
}
```

## Ответ на submit

Рекомендуется `X-APIMart-Response-Version: 2026-07-27`. Успех — HTTP **`202`**; ID задачи в **`data.id`** (не полагайтесь на устаревший `data[0].task_id`).

Сохраните:

* `data.id` для опроса
* `request_id` для отладки на стороне шлюза
* `Idempotency-Key` для безопасных повторов, когда исход неизвестен
* исходные параметры запроса для UI / поддержки

## Идемпотентность и безопасные повторы

Генерация изображений тарифицируется — **настоятельно рекомендуется** `Idempotency-Key` (1–191 печатных ASCII-символа; проще всего UUID; хранится \~24 часа).

| Сценарий                              | Поведение                                             | Действие                                        |
| ------------------------------------- | ----------------------------------------------------- | ----------------------------------------------- |
| Тот же key + тот же body уже завершён | Повтор ответа; заголовок `Idempotency-Replayed: true` | Используйте тот же task id                      |
| Тот же key ещё в обработке            | `409 idempotency_in_progress` + `Retry-After`         | Подождите, повторите **с тем же key и body**    |
| Тот же key, другой body               | `409 idempotency_key_reused`                          | Для новой логической задачи нужен новый key     |
| Исход неопределён                     | `409 idempotency_result_indeterminate`                | Не создавайте новый key; разбирайтесь со старым |

При сетевом таймауте POST, когда нельзя понять, принял ли сервер задачу, **не создавайте сразу новый key** — повторите с тем же key / body / версией ответа.

## Опрос задач

```http theme={null}
GET /v1/tasks/{task_id}?language=en
Authorization: Bearer YOUR_API_KEY
Accept: application/json
```

Опциональный `language`: `zh` / `en` / `ko` / `ja` (только локализация сообщений об ошибках). См. [Получить статус задачи](/ru/api-reference/tasks/status).

### Статусы

| `status`                 | Терминальный | Обработка                                                                   |
| ------------------------ | :----------: | --------------------------------------------------------------------------- |
| `pending` / `processing` |      Нет     | Продолжайте опрос (`result` может отсутствовать — это не сбой)              |
| `completed`              |      Да      | Разберите `result.images`                                                   |
| `failed`                 |      Да      | Покажите `error.message`; `cost` равен `0` (предсписание возвращено)        |
| `unknown`                |      Нет     | Короткие повторы; если сохраняется — свяжитесь с поддержкой, указав task id |

Опрашивайте примерно каждые **2 секунды**; лимит около **10 минут** или **120** попыток. При `429` соблюдайте `Retry-After`. Задачи хранятся \~3 дня по умолчанию — сохраняйте task id, если клиентский таймаут истёк.

### Пример завершённой задачи

```json theme={null}
{
  "code": 200,
  "data": {
    "id": "task_01KZQE5CM0Y3KZ6M1N1BK619MX",
    "status": "completed",
    "progress": 100,
    "created": 1786419262,
    "completed": 1786419275,
    "actual_time": 13,
    "estimated_time": 100,
    "cost": 0.08,
    "credits_cost": 0.8,
    "result": {
      "images": [
        {
          "expires_at": 1786505675,
          "url": [
            "https://example.com/image/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.jpg"
          ],
          "image_ids": [
            "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
          ]
        }
      ]
    }
  }
}
```

### Разбор `url` и `image_ids`

```text theme={null}
result.images[]
  ├─ url[]          ← authoritative display/download field (array)
  ├─ image_ids[]    ← optional opaque IDs
  └─ expires_at     ← Unix seconds; multiply by 1000 for JS Date
```

1. Для отображения используйте `url[]`; при `n>1` обходите все элементы
2. Сопоставляйте по индексу только если `image_ids.length === url.length`
3. Отсутствие `image_ids` не мешает отображению
4. Ссылки действуют **72 часа** — скачивайте своевременно; также ориентируйтесь на `expires_at`

## Тарификация

Базовая цена **\$0.08 за изображение** (успешные доставки):

| `n` | Оценка базовой суммы |
| --: | -------------------: |
|   1 |               \$0.08 |
|   4 |               \$0.32 |
|   8 |               \$0.64 |
|  12 |               \$0.96 |

* В UI до отправки показывайте «оценку»; итоговая сумма в USD — **`data.cost`**
* **`data.credits_cost`** — представление в кредитах (сейчас ≈ USD × 10)
* Предсписание по запрошенному количеству; финальный расчёт по успешным (частичный возврат при частичном сбое)
* Полный сбой: `cost=0`, предсписание возвращено
* Не стройте ключи цен из `resolution`; у этой модели фиксированная цена за изображение

## Webhook (опционально)

```json theme={null}
{
  "webhook": "https://your-service.example.com/apimart"
}
```

* Укажите **base URL**; платформа вызывает `{base}/callback`
* Должен быть публичным и проходить проверки SSRF
* Если задан `webhook_secret`, подпись — `hex(HMAC-SHA256(secret, raw_body))` по сырым байтам
* Тело callback совпадает с `data` из запроса статуса задачи (без обёртки `{code,data}`)
* Всё равно держите низкочастотный опрос как fallback

## Частые ошибки

| HTTP | `error.code`              | Причина                         | Действие                                            |
| ---: | ------------------------- | ------------------------------- | --------------------------------------------------- |
|  400 | `invalid_request`         | Пустой prompt / невалидный JSON | Проверьте ввод                                      |
|  400 | `invalid_n`               | `n` вне 1–12                    | Ограничьте количество                               |
|  400 | `invalid_size`            | size не в белом списке          | Фиксированный select                                |
|  400 | `invalid_response_format` | Не `url`                        | Исправьте или опустите                              |
|  400 | `invalid_quality`         | Отправлено публичное `quality`  | Используйте `resolution`                            |
|  400 | `invalid_style`           | Отправлен `style`               | Удалите                                             |
|  400 | `invalid_image_input`     | Референсные изображения         | Смените модель                                      |
|  400 | `invalid_stream`          | `stream=true`                   | Удалите                                             |
|  400 | `invalid_idempotency_key` | Невалидный key                  | Используйте UUID                                    |
|  401 | Ошибка аутентификации     | Невалидный key                  | Исправьте серверные credentials                     |
|  402 | Требуется оплата          | Низкий баланс                   | Пополните                                           |
|  409 | `idempotency_*`           | Конфликт идемпотентности        | См. таблицу выше                                    |
|  429 | Rate limit                | Слишком часто                   | Соблюдайте `Retry-After`                            |
|  5xx | Ошибка сервера            | —                               | Сохраняйте Idempotency-Key; не меняйте key бездумно |

Для UI предпочтительнее `error.message`. Не показывайте конечным пользователям внутренности аутентификации.

## Отличия от 1.5 (кратко)

| Пункт           | Grok Imagine 1.5                      | 2.0 Ext                                               |
| --------------- | ------------------------------------- | ----------------------------------------------------- |
| Модель          | `grok-imagine-1.5-apimart` и др.      | `grok-imagine-2.0-ext`                                |
| Image-to-image  | Поддерживается (см. документацию 1.5) | **Не поддерживается**                                 |
| Количество      | См. документацию 1.5                  | **1–12**                                              |
| Поле качества   | См. документацию 1.5                  | `resolution` (`quality`); никогда публичное `quality` |
| Вывод           | См. документацию 1.5                  | **Только url**                                        |
| TTL ссылок      | См. документацию 1.5 (часто 24 ч)     | **72 часа**                                           |
| Цена за единицу | См. документацию 1.5                  | **\$0.08 / изображение**                              |
