> Расположение: Методы API → Инференс
> Краткое содержание: Ответ модели в формате OpenAI
> Это Markdown-версия конкретной страницы. Для контекста за её пределами (правила API, полный перечень методов, авторизация) ОБЯЗАТЕЛЬНО открой [llms.txt](https://vcpay.ru/ai/docs/llms.txt) перед ответом — это сэкономит токены и предотвратит неполный ответ.

# Ответ модели в формате OpenAI

**Метод**: `POST`

**Путь**: `/v1/chat/completions`

Совместим с OpenAI Chat Completions: штатный пакет `openai` работает, если указать `base_url="https://llm.vcpay.ru/v1"`. Модель выбирается полем `model` — именем из каталога.

С `"stream": true` ответ приходит событиями SSE по мере генерации, последним событием — `data: [DONE]`.

Здесь перечислены поля, работу которых мы проверяем. Остальные поля формата OpenAI модель может принять, но их поведение зависит от модели и не входит в наш контракт.

## Тело запроса

**Обязательно**

Формат: `application/json`

### Схема

- `model: string` (required) — Имя модели из каталога, например `claude-sonnet-5`. Пример: `"claude-sonnet-5"`
- `messages: array of object` (required) — Диалог по порядку, от первой реплики к последней.
  - `role: string` (required) — Кто говорит. `system` — инструкция модели.
    Значения: `system`, `user`, `assistant`
  - `content: string` (required) — Текст реплики.
- `max_tokens: integer` (min: 1) — Потолок токенов ответа. Размышления модели входят в него.
- `stream: boolean` (default: false) — Отдавать ответ событиями SSE по мере генерации.

### Пример

```json
{
  "model": "claude-sonnet-5",
  "messages": [
    {
      "role": "user",
      "content": "Привет! Ответь одним словом."
    }
  ]
}
```

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

```bash
curl "https://llm.vcpay.ru/v1/chat/completions" \
  -H "Authorization: Bearer ВАШ_КЛЮЧ" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "claude-sonnet-5",
  "messages": [
    {
      "role": "user",
      "content": "Привет! Ответь одним словом."
    }
  ]
}'
```

## Ответы

### 200: Ответ модели. При `"stream": true` — поток событий `text/event-stream`, каждое событие — фрагмент ответа.

**Схема ответа:**

- `id: string` (required) — Идентификатор ответа.
- `object: string` (required) — Всегда `chat.completion`.
- `created: integer` (required) — Момент ответа, Unix-время в секундах.
- `model: string` (required) — Модель, которая ответила. Может прийти полным именем вендора, например `anthropic/claude-haiku-4.5`.
- `choices: array of object` (required) — Варианты ответа. Без особых настроек — один.
  - `index: integer` (required) — Номер варианта.
  - `message: object` (required) — Реплика модели.
    - `role: string` (required) — Всегда `assistant`.
    - `content: string` (required) — Текст ответа.
  - `finish_reason: string` (required) — Почему ответ закончился. `stop` — модель договорила, `length` — упёрлись в `max_tokens`.
- `usage: object` (required) — Токены запроса. По ним считается расход.
  - `prompt_tokens: integer` (required) — Токенов на входе.
  - `completion_tokens: integer` (required) — Токенов на выходе, включая размышления модели. У моделей с размышлениями их заметно больше, чем видно по тексту ответа.
  - `total_tokens: integer` (required) — Сумма входа и выхода.

**Пример ответа:**

```json
{
  "id": "gen-1760261400-abc123",
  "object": "chat.completion",
  "created": 1760261400,
  "model": "claude-sonnet-5",
  "choices": [
    {
      "index": 0,
      "finish_reason": "stop",
      "message": {
        "role": "assistant",
        "content": "Привет!"
      }
    }
  ],
  "usage": {
    "prompt_tokens": 12,
    "completion_tokens": 3,
    "total_tokens": 15
  }
}
```

### 401: Ключ неизвестен, отключён или удалён — или ключу нечего тратить: исчерпан его потолок либо кончились деньги на счёте компании.

**Схема ответа при ошибке:**

- `error: object` (required) — Что случилось.
  - `message: string` (required) — Текст отказа для человека. В конце — номер запроса в скобках, его стоит приложить к обращению в поддержку.
  - `type: string` — Класс отказа.
  - `code: string` — Код отказа. Сейчас чаще пустой — ветвитесь по HTTP-коду.

**Пример ответа:**

```json
{
  "error": {
    "code": "",
    "message": "Invalid token (request id: 202610120924426549346618268d9d6u9fxTwQg)",
    "type": "new_api_error"
  }
}
```

### 403: Запрос не помещается в остаток ключа, или ключу не разрешена эта модель.

**Схема ответа при ошибке:**

- `error: object` (required) — Что случилось.
  - `message: string` (required) — Текст отказа для человека. В конце — номер запроса в скобках, его стоит приложить к обращению в поддержку.
  - `type: string` — Класс отказа.
  - `code: string` — Код отказа. Сейчас чаще пустой — ветвитесь по HTTP-коду.

**Пример ответа:**

```json
{
  "error": {
    "code": "",
    "message": "This token has no access to model claude-opus-5",
    "type": "new_api_error"
  }
}
```

### 429: Слишком много запросов. Повторите с задержкой и увеличивайте её при повторных отказах.

### 503: Такой модели нет — вероятна опечатка в имени. Сверьтесь с каталогом.

**Схема ответа при ошибке:**

- `error: object` (required) — Что случилось.
  - `message: string` (required) — Текст отказа для человека. В конце — номер запроса в скобках, его стоит приложить к обращению в поддержку.
  - `type: string` — Класс отказа.
  - `code: string` — Код отказа. Сейчас чаще пустой — ветвитесь по HTTP-коду.

**Пример ответа:**

```json
{
  "error": {
    "code": "",
    "message": "No available channel for model claude-sonet-5",
    "type": "new_api_error"
  }
}
```

