# Chat Completions

```
POST https://api.agentapi.ru/v1/ai/chat/completions
```

Основной эндпоинт. Совместим с OpenAI Chat Completions API, включая стриминг и вызов
инструментов.

## Параметры

Принимаются оба варианта написания: `max_tokens` и `maxTokens`, `top_p` и `topP` и так далее.
Если указаны оба — приоритет у camelCase.

| Параметр | Тип | Описание |
|---|---|---|
| `messages` | array | **Обязательный.** Массив сообщений диалога |
| `model` | string | Слаг модели, например `openai/gpt-4.1` |
| `models` | string[] | Список моделей для fallback-роутинга: при отказе первой берётся следующая |
| `temperature` | number | 0–2. Выше — разнообразнее |
| `max_tokens` | number | ≥ 1. Лимит генерируемых токенов |
| `max_completion_tokens` | number | ≥ 1. Альтернатива `max_tokens` |
| `top_p` | number | 0–1. Nucleus sampling |
| `frequency_penalty` | number | −2…2. Штраф за частоту повторов |
| `presence_penalty` | number | −2…2. Штраф за повторное появление |
| `stop` | string \| string[] | Стоп-последовательности |
| `stream` | boolean | Включить SSE-стриминг |
| `seed` | number | Сид для воспроизводимости |
| `response_format` | object | Например `{"type": "json_object"}` |
| `tools` | array | Определения инструментов (function calling) |
| `tool_choice` | string \| object | `auto`, `none`, `required` или конкретный инструмент |
| `logit_bias` | object | Смещения вероятностей по id токенов |
| `logprobs` | boolean | Возвращать логарифмы вероятностей |
| `top_logprobs` | number | 0–20 |
| `user` | string | Идентификатор конечного пользователя |
| `session_id` | string | ≤ 128 символов. Группировка запросов |
| `metadata` | object | Произвольные строковые пары для трекинга |
| `provider` | object | Предпочтения роутинга, например `{"order": ["openai"]}` |
| `plugins` | array | Дополнительные плагины, например веб-поиск |
| `reasoning` | boolean \| object | Настройка reasoning. `true` эквивалентно `{"effort": "medium"}` |
| `stream_options` | object | `{"include_usage": true}` — добавить `usage` в поток |

### Сообщения

| Поле | Тип | Описание |
|---|---|---|
| `role` | string | `system`, `user`, `assistant` или `tool` |
| `content` | string | Текст сообщения |
| `tool_call_id` | string | Для роли `tool` — id вызова, на который отвечаем |
| `tool_calls` | array | Для роли `assistant` — вызовы инструментов |

> `content` принимает только строку. Массивы блоков (`[{"type": "image_url", …}]`)
> отклоняются с 400 — мультимодальный ввод пока не поддерживается, см.
> [Ограничения](https://agentapi.ru/docs/limitations).

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

```bash
curl https://api.agentapi.ru/v1/ai/chat/completions \
  -H "x-api-key: agentapi-ВАШ_КЛЮЧ" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-4.1",
    "messages": [
      {"role": "system", "content": "Отвечай кратко."},
      {"role": "user", "content": "Что такое CAP-теорема?"}
    ],
    "temperature": 0.3,
    "max_tokens": 200
  }'
```

```typescript
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.AGENTAPI_KEY,
  baseURL: "https://api.agentapi.ru/v1/ai",
});

const completion = await client.chat.completions.create({
  model: "openai/gpt-4.1",
  messages: [
    { role: "system", content: "Отвечай кратко." },
    { role: "user", content: "Что такое CAP-теорема?" },
  ],
  temperature: 0.3,
  max_tokens: 200,
});

console.log(completion.choices[0].message.content);
console.log(completion.usage);
```

```python
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["AGENTAPI_KEY"],
    base_url="https://api.agentapi.ru/v1/ai",
)

completion = client.chat.completions.create(
    model="openai/gpt-4.1",
    messages=[
        {"role": "system", "content": "Отвечай кратко."},
        {"role": "user", "content": "Что такое CAP-теорема?"},
    ],
    temperature=0.3,
    max_tokens=200,
)

print(completion.choices[0].message.content)
```

## Ответ

```json
{
  "id": "gen-1753600412-8Kd2nRxVqLm",
  "object": "chat.completion",
  "created": 1753600412,
  "model": "openai/gpt-4.1",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "CAP-теорема утверждает, что распределённая система не может одновременно гарантировать согласованность (Consistency), доступность (Availability) и устойчивость к разделению сети (Partition tolerance) — при разделении приходится выбирать между C и A."
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 24,
    "completion_tokens": 71,
    "total_tokens": 95
  }
}
```

| Поле | Описание |
|---|---|
| `id` | Идентификатор генерации |
| `object` | Всегда `chat.completion` |
| `created` | Unix-время |
| `model` | Фактически использованная модель (может отличаться при fallback) |
| `choices[].finish_reason` | `stop`, `length`, `tool_calls`, `content_filter` |
| `usage` | Израсходованные токены |

Списание с баланса идёт в рублях — см. [Биллинг](https://agentapi.ru/docs/billing).

## Стриминг

Передайте `"stream": true`. Ответ приходит как `text/event-stream`.

```bash
curl -N https://api.agentapi.ru/v1/ai/chat/completions \
  -H "x-api-key: agentapi-ВАШ_КЛЮЧ" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-4.1",
    "messages": [{"role": "user", "content": "Считай до трёх"}],
    "stream": true
  }'
```

Поток кадров:

```
data: {"id":"gen-1753600500-Qm4","object":"chat.completion.chunk","created":1753600500,"model":"openai/gpt-4.1","choices":[{"index":0,"delta":{"role":"assistant","content":""}}]}

data: {"id":"gen-1753600500-Qm4","object":"chat.completion.chunk","created":1753600500,"model":"openai/gpt-4.1","choices":[{"index":0,"delta":{"content":"Один"}}]}

data: {"id":"gen-1753600500-Qm4","object":"chat.completion.chunk","created":1753600500,"model":"openai/gpt-4.1","choices":[{"index":0,"delta":{"content":", два"}}]}

data: {"id":"gen-1753600500-Qm4","object":"chat.completion.chunk","created":1753600500,"model":"openai/gpt-4.1","choices":[{"index":0,"delta":{"content":", три."},"finish_reason":"stop"}]}

data: {"id":"gen-1753600500-Qm4","object":"chat.completion.chunk","created":1753600500,"model":"openai/gpt-4.1","choices":[],"usage":{"prompt_tokens":12,"completion_tokens":8,"total_tokens":20}}

data: [DONE]
```

Особенности:

- Последний кадр перед `[DONE]` содержит `usage` — он запрашивается всегда, даже если
  вы не передали `stream_options`.
- Признак конца потока — литерал `data: [DONE]`.
- Ошибка **посреди** потока приходит кадром `data: {"error":{"message":…}}`, при том что
  HTTP-статус уже 200 (заголовки отправлены до начала генерации). Обрабатывайте поле
  `error` в каждом кадре, а не только код ответа.

## Вызов инструментов

```bash
curl https://api.agentapi.ru/v1/ai/chat/completions \
  -H "x-api-key: agentapi-ВАШ_КЛЮЧ" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-4.1",
    "messages": [{"role": "user", "content": "Какая погода в Иркутске?"}],
    "tools": [{
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "Текущая погода в городе",
        "parameters": {
          "type": "object",
          "properties": {
            "city": {"type": "string", "description": "Название города"}
          },
          "required": ["city"]
        }
      }
    }],
    "tool_choice": "auto"
  }'
```

Ответ:

```json
{
  "id": "gen-1753600730-Zt9",
  "object": "chat.completion",
  "created": 1753600730,
  "model": "openai/gpt-4.1",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": null,
        "tool_calls": [
          {
            "index": 0,
            "id": "call_9fK2mQ",
            "type": "function",
            "function": {
              "name": "get_weather",
              "arguments": "{\"city\":\"Иркутск\"}"
            }
          }
        ]
      },
      "finish_reason": "tool_calls"
    }
  ],
  "usage": {"prompt_tokens": 68, "completion_tokens": 19, "total_tokens": 87}
}
```

Результат возвращается сообщением с ролью `tool`:

```json
{
  "model": "openai/gpt-4.1",
  "messages": [
    {"role": "user", "content": "Какая погода в Иркутске?"},
    {"role": "assistant", "content": null, "tool_calls": [
      {"index": 0, "id": "call_9fK2mQ", "type": "function",
       "function": {"name": "get_weather", "arguments": "{\"city\":\"Иркутск\"}"}}
    ]},
    {"role": "tool", "tool_call_id": "call_9fK2mQ", "content": "{\"temp_c\": -3, \"sky\": \"снег\"}"}
  ]
}
```

Имена свойств внутри `tools[].function.parameters` (JSON Schema) и ключи `metadata`
передаются без изменений.

## Fallback-роутинг

Вместо одной модели можно передать список — при отказе используется следующая:

```json
{
  "models": ["openai/gpt-4.1", "anthropic/claude-3.5-sonnet"],
  "messages": [{"role": "user", "content": "Привет!"}]
}
```

Фактически ответившая модель указана в поле `model` ответа.

## Коды ошибок

| Код | Причина |
|---|---|
| 400 | Невалидные параметры или нулевой баланс |
| 401 | Ключ отсутствует, неверного формата, отключён или не найден |
| 429 | Превышен rate limit |
| 502 | Ошибка провайдера. Тело: `{"message": "…"}` |

Подробнее — [Ошибки и лимиты](https://agentapi.ru/docs/errors).
