
## Гарантированный JSON-ответ

Параметр `response_format` заставляет модель вернуть машиночитаемый ответ вместо свободного текста. Есть два уровня строгости: `json_object` гарантирует корректный JSON произвольной формы, `json_schema` — соответствие заданной схеме.

## Режим `json_object`

При `response_format: {"type": "json_object"}` модель возвращает корректный JSON в поле `content`. Вайбкод автоматически добавляет в системное сообщение инструкцию вернуть только JSON. Структуру результата опишите явно в системном сообщении:

```bash
curl -X POST https://vibecode.bitrix24.tech/v1/chat/completions \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "bitrix/bitrixgpt-5.5",
    "messages": [
      {"role": "system", "content": "Классифицируй лид. Верни JSON: {\"quality\": \"high|medium|low\", \"score\": 0-100}"},
      {"role": "user", "content": "ООО Вектор, бюджет 2 миллиона в месяц"}
    ],
    "response_format": {"type": "json_object"}
  }'
```

Ответ:

```json
{
  "id": "chatcmpl-acdb112cf9cdf9f9",
  "object": "chat.completion",
  "model": "bitrix/bitrixgpt-5.5",
  "choices": [
    {
      "index": 0,
      "finish_reason": "stop",
      "message": {
        "role": "assistant",
        "content": "{\"quality\":\"high\",\"score\":92}"
      }
    }
  ],
  "usage": {"prompt_tokens": 56, "completion_tokens": 14, "total_tokens": 70}
}
```

## Режим `json_schema`

`response_format: {"type": "json_schema", "json_schema": {...}}` гарантирует, что ответ модели **строго соответствует** заданной JSON Schema — модель не может вернуть лишние поля, пропустить обязательные или перепутать типы. Это строже, чем `json_object`, который гарантирует только корректный JSON.

Режим доступен не на всех моделях. Актуальный список — в ответе [`GET /v1/me`](/docs/keys-auth), поле `ai.structuredOutputs.models`.

## Поля `json_schema`

| Поле | Тип | Обяз. | Описание |
|------|-----|:-----:|---------|
| `name` | string | да | Имя схемы. До 64 символов, допустимы `a-zA-Z0-9_-` |
| `schema` | object | да | Сама JSON Schema |
| `strict` | boolean | нет | `true` — строгая проверка соответствия схеме. Рекомендуемое значение |
| `description` | string | нет | Описание схемы для модели, помогает ей верно истолковать поля |

## Пример со схемой

```bash
curl -X POST https://vibecode.bitrix24.tech/v1/chat/completions \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "bitrix/openai/gpt-oss-120b",
    "messages": [
      {"role": "system", "content": "Верни строгий JSON по схеме."},
      {"role": "user", "content": "Привет"}
    ],
    "response_format": {
      "type": "json_schema",
      "json_schema": {
        "name": "hello_response",
        "strict": true,
        "schema": {
          "type": "object",
          "properties": {"message": {"type": "string"}},
          "required": ["message"],
          "additionalProperties": false
        }
      }
    }
  }'
```

Поле `choices[0].message.content` содержит строку, которая разбирается в объект, точно соответствующий схеме — например `{"message":"Привет"}`.

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

`400 model_does_not_support_structured_outputs` — модель не поддерживает `json_schema`. В поле `structuredOutputsModels` приходит список подходящих моделей:

```json
{
  "error": {
    "message": "Model 'openai/o3' does not support response_format=json_schema. Use one of: bitrix/bitrixgpt-5.5, bitrix/bitrixgpt-5.5-thinking, openai/gpt-4o, bitrix/openai/gpt-oss-120b, openai/gpt-4o-mini.",
    "type": "invalid_request_error",
    "code": "model_does_not_support_structured_outputs",
    "param": "response_format.type",
    "structuredOutputsModels": ["bitrix/bitrixgpt-5.5", "bitrix/bitrixgpt-5.5-thinking", "openai/gpt-4o", "bitrix/openai/gpt-oss-120b", "openai/gpt-4o-mini", "openai/o3-mini"]
  }
}
```

`422 structured_output_truncated` — генерация оборвана по лимиту токенов до полного JSON:

```json
{
  "error": {
    "message": "The model's response was cut off (finish_reason=length) before a complete JSON document was produced, so it does not satisfy the requested response_format. Raise max_tokens, or reduce the schema/prompt size.",
    "type": "invalid_request_error",
    "code": "structured_output_truncated",
    "hint": "For reasoning models, max_tokens must cover the reasoning phase plus the JSON answer.",
    "param": "max_tokens",
    "finishReason": "length",
    "suggestedMaxTokens": 2048
  }
}
```

## Ошибки

| HTTP | Код | Описание |
|------|-----|---------|
| 400 | `model_does_not_support_structured_outputs` | Модель не поддерживает `json_schema`. Список подходящих — в поле `structuredOutputsModels` |
| 422 | `structured_output_truncated` | Модель оборвала генерацию до полного JSON или вернула пустой ответ |

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

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

**Обрезанный ответ даёт `422 structured_output_truncated`.** Если модель оборвала генерацию до полного JSON (`finish_reason: "length"`), запрос с `response_format` возвращает `422` с полями `finishReason` и `suggestedMaxTokens`. Так ведут себя модели с рассуждением: фаза рассуждения расходует бюджет `max_tokens` до того, как модель напишет JSON. Обрабатывайте эту ошибку и повторяйте запрос с увеличенным `max_tokens` — можно взять значение из `suggestedMaxTokens`. Для строгого JSON задавайте `max_tokens` с запасом либо используйте модель без рассуждения.

Поля `suggestedMaxTokens` и `param: "max_tokens"` присутствуют **только** при `finish_reason: "length"` — они указывают, что помогает увеличение бюджета токенов. Если причина завершения любая другая, а корректного JSON так и нет, ответ тоже `422`, но уже без этих двух полей — увеличение `max_tokens` не поможет, возьмите модель без рассуждения. Строка `hint` и поле `finishReason` есть в обеих ветках, `finishReason` может быть `null`.

Если же модель с рассуждением на `json_object` завершилась сама и положила готовый корректный JSON в служебный канал `reasoning_content`, платформа восстанавливает этот JSON и возвращает `200` с ним в `content` — отдельной обработки не требуется.

**Обрезанная попытка тарифицируется.** Ответ `422` приходит после того, как модель отработала, поэтому токены попытки учитываются в статистике расхода [`GET /v1/ai/usage`](/docs/ai/consumption/usage) и в месячной AI-квоте портала. Повтор с увеличенным `max_tokens` — это ещё один оплачиваемый вызов.

**Заниженный `max_tokens` на бесплатной модели с рассуждением поднимается автоматически.** Если у бесплатной модели с рассуждением запрошен структурированный ответ, а `max_tokens` задан явно и ниже нижней границы, платформа поднимает его до этой границы и сообщает об этом на успешном ответе `200`: в теле появляется массив `warnings` с элементом `{"code": "MAX_TOKENS_RAISED", "message": "..."}`. Это не ошибка — читайте `warnings` как необязательное поле. Если `max_tokens` в запросе не задан, правка не применяется.

**В потоковом режиме ошибка (и восстановленный ответ) приходят внутри потока.** Служебное событие `{"error":{"code":"structured_output_truncated"}}` идёт перед `data: [DONE]`. Восстановленный из `reasoning_content` JSON приходит событием потока с полем `content` перед терминальным событием с `finish_reason` — читайте поток до конца.

**`json_object` не проверяет структуру.** Он гарантирует только то, что ответ разберётся как JSON. Набор полей и их типы остаются на усмотрение модели — если структура важна, используйте `json_schema` со `strict: true`.

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

- [Создать чат-комплишен](./completions.md)
- [Потоковая передача](./streaming.md)
- [Вызов функций](./tools.md)
- [Список моделей](/docs/ai/models/list)
