# AgentAPI — полная документация
> AgentAPI — единый шлюз к 300+ AI-моделям (OpenAI, Anthropic, Google и другие) с API, совместимым с OpenAI. Один ключ, базовый URL https://api.agentapi.ru/v1/ai, оплата в рублях по факту токенов.
Все страницы https://agentapi.ru/docs в порядке оглавления, у каждой указан её адрес.
---
URL: https://agentapi.ru/docs
# AgentAPI
AgentAPI — единый шлюз к 300+ AI-моделям. Один ключ, один базовый URL, оплата в рублях.
API совместим с форматом OpenAI, поэтому большинство существующих клиентов, SDK и плагинов
для редакторов работают без изменений в коде — достаточно поменять `base_url` и ключ.
## Что нужно знать сразу
| | |
|---|---|
| **Base URL** | `https://api.agentapi.ru/v1/ai` |
| **Аутентификация** | `x-api-key: agentapi-…` или `Authorization: Bearer agentapi-…` |
| **Формат ключа** | `agentapi-` + 48 hex-символов |
| **Форматы API** | OpenAI Chat Completions, OpenAI Responses, Anthropic Messages, Embeddings |
| **Модели** | формат `провайдер/модель` — `openai/gpt-4.1`, `anthropic/claude-3.5-sonnet` |
| **Оплата** | предоплаченный баланс в рублях, списание по факту токенов |
| **Swagger** | [api.agentapi.ru/v1/docs](https://api.agentapi.ru/v1/docs) |
> Обратите внимание на сегмент `/ai` в базовом URL — он обязателен.
> `https://agentapi.ru/v1` (без `api.` и без `/ai`) не существует: основной домен отдаёт сайт.
## Быстрый старт
```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": "Привет!"}]
}'
```
Подробнее — [Быстрый старт](https://agentapi.ru/docs/quickstart).
## Контракт запроса
```mermaid
flowchart TD
A["POST /v1/ai/chat/completions
ключ + model + messages"] --> B{"stream?"}
B -- "нет" --> C["200 · application/json
текст в choices.message.content"]
B -- "да" --> D["200 · text/event-stream
SSE-кадры, финал DONE"]
A -.-> E["401 · проблема с ключом"]
A -.-> F["400 · параметры или баланс"]
A -.-> G["429 · превышен лимит запросов"]
A -.-> H["502 · модель недоступна"]
```
Что важно учесть на стороне клиента:
- **Ключ передаётся заголовком** — `x-api-key` или `Authorization: Bearer`, оба варианта
равнозначны. См. [Аутентификация](https://agentapi.ru/docs/authentication).
- **Ключ показывается один раз** при создании и не может быть восстановлен. См.
[API-ключи](https://agentapi.ru/docs/api-keys).
- **Стриминг завершается литералом `data: [DONE]`.** Ошибка, случившаяся после начала потока,
приходит отдельным кадром при уже отданном статусе 200 — проверяйте поле `error` в каждом кадре.
- **Расход списывается с баланса в рублях по факту использованных токенов.** См.
[Биллинг](https://agentapi.ru/docs/billing).
## Совместимость
Один и тот же аккаунт и ключ работают через четыре формата запроса:
| Формат | Эндпоинт | Кому подходит |
|---|---|---|
| OpenAI Chat Completions | [`POST /v1/ai/chat/completions`](https://agentapi.ru/docs/endpoints/chat-completions) | OpenAI SDK, Continue, Cline, Roo Code, LangChain |
| Anthropic Messages | [`POST /v1/ai/messages`](https://agentapi.ru/docs/endpoints/messages) | Anthropic SDK и клиенты Claude |
| OpenAI Responses | [`POST /v1/ai/responses`](https://agentapi.ru/docs/endpoints/responses) | клиенты на Responses API |
| Embeddings | [`POST /v1/ai/embeddings`](https://agentapi.ru/docs/endpoints/embeddings) | векторный поиск, RAG |
Настройка редакторов и плагинов:
[Continue](https://agentapi.ru/docs/integrations/continue) ·
[Cline](https://agentapi.ru/docs/integrations/cline) ·
[Roo Code](https://agentapi.ru/docs/integrations/roo-code) ·
[Claude Code](https://agentapi.ru/docs/integrations/claude-code) ·
[SDK и curl](https://agentapi.ru/docs/integrations/sdk)
## Дальше
1. [Быстрый старт](https://agentapi.ru/docs/quickstart) — первый запрос за 5 минут.
2. [API-ключи](https://agentapi.ru/docs/api-keys) — как создать, где хранить, как отозвать.
3. [Аутентификация](https://agentapi.ru/docs/authentication) — заголовки и ошибки 401.
4. [Модели](https://agentapi.ru/docs/models) — какие слаги использовать.
5. [Ошибки и лимиты](https://agentapi.ru/docs/errors) — коды ответов и rate limit.
6. [Известные ограничения](https://agentapi.ru/docs/limitations) — что пока не поддерживается.
---
URL: https://agentapi.ru/docs/quickstart
# Быстрый старт
От регистрации до первого ответа модели — пять минут.
## 1. Пополните баланс
API-ключ нельзя создать при нулевом балансе — попытка вернёт
`403 Insufficient balance to create an API key`. Пополните счёт в
[профиле](https://agentapi.ru/profile): минимальная сумма — 100 ₽.
## 2. Создайте ключ
В профиле откройте раздел «Ваши API ключи» → «Создать ключ» → задайте имя.
Ключ вида `agentapi-1f3c…` показывается **один раз** — сразу скопируйте его.
Восстановить его потом невозможно: если ключ потерян, удалите его и создайте новый.
Подробнее — [API-ключи](https://agentapi.ru/docs/api-keys).
## 3. Первый запрос
```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": "Назови три факта о Байкале"}
]
}'
```
Ответ:
```json
{
"id": "gen-1753600000-Xf4KpQ2mNvR",
"object": "chat.completion",
"created": 1753600000,
"model": "openai/gpt-4.1",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "1. Байкал — самое глубокое озеро в мире (1642 м)…"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 18,
"completion_tokens": 96,
"total_tokens": 114
}
}
```
Поле `usage` показывает израсходованные токены. Списание с баланса идёт в рублях —
см. [Биллинг](https://agentapi.ru/docs/billing).
## 4. Подключите SDK
AgentAPI совместим с OpenAI SDK. Важно: `base_url` — это `…/v1/ai`, **без** `/chat/completions`
(SDK добавит путь сам).
```python
from openai import OpenAI
client = OpenAI(
api_key="agentapi-ВАШ_КЛЮЧ",
base_url="https://api.agentapi.ru/v1/ai",
)
completion = client.chat.completions.create(
model="openai/gpt-4.1",
messages=[{"role": "user", "content": "Привет!"}],
)
print(completion.choices[0].message.content)
```
```typescript
import OpenAI from "openai";
const client = new OpenAI({
apiKey: "agentapi-ВАШ_КЛЮЧ",
baseURL: "https://api.agentapi.ru/v1/ai",
});
const completion = await client.chat.completions.create({
model: "openai/gpt-4.1",
messages: [{ role: "user", content: "Привет!" }],
});
console.log(completion.choices[0].message.content);
```
Отдельный заголовок `x-api-key` при работе через SDK не нужен: параметр `apiKey`
отправляет `Authorization: Bearer …`, и это принимается.
## 5. Настройте редактор
Тот же ключ работает в плагинах VS Code:
- [Continue](https://agentapi.ru/docs/integrations/continue) — чат, автодополнение, embeddings
- [Cline](https://agentapi.ru/docs/integrations/cline) — агент, правящий файлы
- [Roo Code](https://agentapi.ru/docs/integrations/roo-code) — форк Cline с режимами
- [Claude Code](https://agentapi.ru/docs/integrations/claude-code) — через Anthropic-совместимый эндпоинт
## Частые ошибки на старте
| Симптом | Причина |
|---|---|
| `404 Not Found` | В URL нет сегмента `/ai` либо используется `agentapi.ru` вместо `api.agentapi.ru` |
| Путь вида `…/chat/completions/chat/completions` | В `base_url` передан полный путь до эндпоинта, а не `…/v1/ai` |
| `401 Invalid API key format` | Ключ не начинается с `agentapi-` (например, вставлен ключ OpenAI) |
| `400 Negative or zero balance` | Нулевой или отрицательный баланс — пополните счёт |
| `404` от провайдера на валидном ключе | Неверный слаг модели: нужен `openai/gpt-4.1`, а не `gpt-4.1` |
Полный список — [Ошибки и лимиты](https://agentapi.ru/docs/errors).
---
URL: https://agentapi.ru/docs/api-keys
# API-ключи
## Формат
```
agentapi-4e1d1cb6e9a2bf62c8a70f5d3b19e84c7a25f0d6b8e34179
└───┬───┘└──────────────────────┬──────────────────────┘
префикс 48 hex-символов
```
Полная длина — 57 символов. Регулярное выражение для валидации:
```
^agentapi-[0-9a-f]{48}$
```
Ключ, не начинающийся с `agentapi-`, отклоняется с `401 Invalid API key format`.
## Жизненный цикл
1. **Создание** — требует положительного баланса и уникального имени в рамках аккаунта.
2. **Показ.** Ключ отдаётся в ответе **один раз**. Сохраните его сразу.
3. **Использование** — заголовком `x-api-key` или `Authorization: Bearer`.
4. **Отключение** (`active: false`) — обратимо, ключ перестаёт работать до включения обратно.
5. **Удаление** — необратимо.
Что из этого следует на практике:
- **Просмотреть существующий ключ невозможно** — ни через интерфейс, ни через API. Доступен только
`postfix`, последние 4 символа, чтобы отличать ключи друг от друга в списке.
- **Ключ нельзя восстановить.** Если он утерян — удалите его и создайте новый.
- **Удаление необратимо.** Приложения, использующие этот ключ, немедленно получат 401.
## Управление через интерфейс
Раздел «Ваши API ключи» в [профиле](https://agentapi.ru/profile): создание, просмотр списка,
включение/отключение, удаление.
## Управление через API
Эти эндпоинты относятся к внутреннему API и требуют **JWT-авторизации пользователя**
(не ключа `agentapi-*`). Базовый URL — `https://api.agentapi.ru`, без префикса `/v1`.
JWT передаётся как `Authorization: Bearer ` либо в cookie `x-token`.
### Создать ключ
```
POST /api-key/create
```
```bash
curl https://api.agentapi.ru/api-key/create \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-d '{"apiKeyName": "My App Key"}'
```
Ответ:
```json
{
"key": "agentapi-4e1d1cb6e9a2bf62c8a70f5d3b19e84c7a25f0d6b8e34179",
"hashed": "9f2b7c4e8a1d5f3b6c9e2a7d4f1b8c5e3a6d9f2b7c4e8a1d5f3b6c9e2a7d4f1b",
"postfix": "4179"
}
```
`key` возвращается только в этом ответе.
| Код | Причина |
|---|---|
| 403 | `Insufficient balance to create an API key` — баланс ≤ 0 |
| 404 | `API Key name already exists for this user` — имя занято |
| 404 | `User not found` |
### Список ключей
```
GET /api-key
```
```json
{
"message": "Returns all apiKeys",
"apiKeys": [
{
"id": "3f1a8c02-5b7e-4d61-9a3c-8e2f5d7b1c40",
"apiKeyName": "My App Key",
"postfix": "4179",
"active": true,
"createdAt": "2026-07-20T11:04:18.512Z"
}
]
}
```
Сам ключ и служебные поля в этом ответе не возвращаются — только метаданные.
### Отключить или включить ключ
```
PATCH /api-key/update-activity/:id
```
```bash
curl -X PATCH https://api.agentapi.ru/api-key/update-activity/3f1a8c02-5b7e-4d61-9a3c-8e2f5d7b1c40 \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-d '{"active": false}'
```
Отключённый ключ отдаёт `401 Invalid or inactive API key`. Обратимо: тем же запросом
с `"active": true`.
### Удалить ключ
```
DELETE /api-key/:id
```
Ответ — строка `Removed API key #`. Необратимо.
## Ограничения
У ключей **нет** скоупов, ограничений по моделям, лимитов расхода и срока жизни — только
флаг `active`. Разделение прав между ключами не поддерживается: любой активный ключ
имеет полный доступ к API в рамках баланса аккаунта.
Rate limit также **не привязан к ключу** — он считается по IP-адресу, см.
[Ошибки и лимиты](https://agentapi.ru/docs/errors).
## Рекомендации по безопасности
- Храните ключ в переменных окружения или менеджере секретов, не в репозитории.
- Ключ даёт прямой доступ к балансу аккаунта — утечка приводит к расходу средств.
- Создавайте отдельные ключи под окружения (`dev`, `staging`, `prod`), чтобы отзыв одного
не ломал остальные.
- Не используйте ключ в браузерном или мобильном коде: он будет виден пользователю.
Проксируйте запросы через свой бэкенд.
- При подозрении на утечку — удалите ключ; отключения флагом недостаточно, если ключ
скомпрометирован.
---
URL: https://agentapi.ru/docs/authentication
# Аутентификация
Все эндпоинты инференса требуют API-ключ. Поддерживаются два заголовка — используйте любой.
## Вариант 1: `x-api-key`
Основной вариант платформы.
```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":"Привет!"}]}'
```
## Вариант 2: `Authorization: Bearer`
Именно этот заголовок отправляют OpenAI SDK и большинство плагинов для редакторов, поэтому
они работают без дополнительной настройки заголовков.
```bash
curl https://api.agentapi.ru/v1/ai/chat/completions \
-H "Authorization: Bearer agentapi-ВАШ_КЛЮЧ" \
-H "Content-Type: application/json" \
-d '{"model":"openai/gpt-4.1","messages":[{"role":"user","content":"Привет!"}]}'
```
Значение после `Bearer ` должно быть самим ключом `agentapi-*`. Передавать здесь JWT
пользователя нельзя — эндпоинты инференса принимают только API-ключи.
## Приоритет заголовков
Если присланы оба заголовка, используется **`x-api-key`**; `Authorization` игнорируется.
Дублировать их не нужно — при работе через SDK достаточно штатного параметра `apiKey`.
## Порядок проверок
Ключ проходит проверки в этом порядке, и первая неудачная возвращает 401:
1. Заголовок присутствует → иначе `API key is required in x-api-key or Authorization header`
2. Ключ начинается с `agentapi-` → иначе `Invalid API key format`
3. Ключ существует и активен → иначе `Invalid or inactive API key`
4. Ключ связан с существующим пользователем → иначе `API key not found`
Формат ответа:
```json
{
"statusCode": 401,
"message": "Invalid or inactive API key",
"error": "Unauthorized"
}
```
## CORS
Для внешнего API (`/v1*`) CORS открыт: разрешённые заголовки — `Content-Type`,
`Authorization`, `x-token`, `x-api-key`.
Технически это позволяет обращаться к API прямо из браузера, но **так делать не нужно**:
ключ станет доступен любому пользователю страницы, а вместе с ним — и баланс аккаунта.
Проксируйте запросы через свой сервер.
## Внутреннее API
Управление аккаунтом (`/api-key/*`, `/billing/*`, `/user/*`, `/stats/*`) использует
не API-ключ, а **JWT** — в заголовке `Authorization: Bearer ` либо в cookie `x-token`.
Эти эндпоинты живут на том же хосте, но без префикса `/v1`.
| | Инференс | Управление аккаунтом |
|---|---|---|
| Префикс | `/v1/ai/*` | без префикса |
| Учётные данные | ключ `agentapi-*` | JWT пользователя |
| Заголовок | `x-api-key` или `Authorization: Bearer` | `Authorization: Bearer` или cookie `x-token` |
---
URL: https://agentapi.ru/docs/models
# Модели
## Формат идентификатора
Модель задаётся слагом в формате `провайдер/модель`:
```
openai/gpt-4.1
anthropic/claude-3.5-sonnet
google/gemini-2.0-flash
deepseek/deepseek-chat
```
Слаг без префикса провайдера (`gpt-4.1`) невалиден и приведёт к ошибке от провайдера.
Актуальные слаги смотрите в каталоге [Модели](https://agentapi.ru/models) на сайте.
## Список моделей
```
GET https://api.agentapi.ru/models
```
Эндпоинт публичный — ключ не требуется. Обратите внимание: он **без префикса `/v1`**.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
| `q` | string | — | Поиск по названию или слагу |
| `limit` | number | 10 | Размер страницы |
| `page` | number | 1 | Номер страницы |
| `order` | string | — | Сортировка (см. ниже) |
Значения `order`: `newest`, `most-popular`, `top-weekly`, `pricing-low-to-high`,
`pricing-high-to-low`, `context-high-to-low`, `latency-low-to-high`,
`throughput-high-to-low`.
```bash
curl "https://api.agentapi.ru/models?q=claude&limit=2&order=newest"
```
```json
{
"data": [
{
"id": "anthropic/claude-3.5-sonnet",
"name": "Anthropic: Claude 3.5 Sonnet",
"context_length": 200000,
"pricing": {
"prompt": "0.000003",
"completion": "0.000015"
},
"architecture": {
"input_modalities": ["text", "image"],
"output_modalities": ["text"]
}
}
],
"total": 14,
"total_pages": 7
}
```
Поле `pricing` — справочные тарифы модели за токен. Итоговое списание с баланса идёт
в рублях, см. [Биллинг](https://agentapi.ru/docs/billing).
## Чего в этом списке нет
- **Embedding-модели отфильтрованы.** Всё, что отдаёт `embeddings` в `output_modalities`,
из выдачи исключается. Названия для [эндпоинта embeddings](https://agentapi.ru/docs/endpoints/embeddings)
берите из документации провайдера.
- **Эндпоинта `GET /v1/ai/models` не существует.** Плагины, которые подтягивают список
моделей автоматически, покажут пустой список — слаг нужно вводить руками. Это отражено
в инструкциях по [интеграциям](https://agentapi.ru/docs/integrations/continue).
## Выбор модели по умолчанию
Поле `model` необязательно, но полагаться на это не стоит: без явного указания выбор
модели остаётся на стороне провайдера, а в статистику расходов запрос попадёт под
служебным именем. Всегда указывайте `model` явно.
## Fallback при отказе
Вместо одной модели можно передать приоритетный список — если первая недоступна,
используется следующая:
```json
{
"models": ["openai/gpt-4.1", "anthropic/claude-3.5-sonnet", "deepseek/deepseek-chat"],
"messages": [{"role": "user", "content": "Привет!"}]
}
```
Модель, которая фактически ответила, возвращается в поле `model`.
## Предпочтения провайдера
Один и тот же слаг может обслуживаться разными хостингами. Порядок можно задать:
```json
{
"model": "openai/gpt-4.1",
"messages": [{"role": "user", "content": "Привет!"}],
"provider": {
"order": ["openai", "azure"],
"allow_fallbacks": true
}
}
```
---
URL: https://agentapi.ru/docs/endpoints/chat-completions
# 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).
---
URL: https://agentapi.ru/docs/endpoints/messages
# Messages (формат Anthropic)
```
POST https://api.agentapi.ru/v1/ai/messages
```
Эндпоинт принимает запросы в формате Anthropic Messages API и отдаёт настоящие
Anthropic-ответы, включая корректный SSE с событиями `message_start`,
`content_block_delta` и `message_stop`. Внутри запрос транслируется в вызов провайдера
и обратно.
> **Про путь.** Обратите внимание: эндпоинт — `/v1/ai/messages`, а не `/v1/messages`.
> Клиенты, которые жёстко дописывают `/v1/messages` к базовому URL, требуют отдельной
> настройки — см. [Claude Code](https://agentapi.ru/docs/integrations/claude-code).
## Параметры
| Параметр | Тип | Описание |
|---|---|---|
| `messages` | array | **Обязательный.** Сообщения с ролями `user` / `assistant` |
| `model` | string | Слаг модели, например `anthropic/claude-3.5-sonnet` |
| `max_tokens` | number | Лимит генерации |
| `system` | string | Системная инструкция (отдельным полем, не сообщением) |
| `temperature` | number | 0–1 |
| `top_p` | number | Nucleus sampling |
| `top_k` | number | Ограничение выборки по top-k |
| `stop_sequences` | string[] | Принимается, но **не применяется**, см. [Ограничения](https://agentapi.ru/docs/limitations) |
| `stream` | boolean | Включить SSE |
| `tools` | array | Инструменты в формате Anthropic: `{name, description, input_schema}` |
| `tool_choice` | object | Управление выбором инструмента |
| `thinking` | object | `{"type": "enabled", "budget_tokens": 2048}` |
| `metadata` | object | Произвольные метаданные |
Обратите внимание: здесь параметры именно в snake_case (`max_tokens`, `top_p`) — как
в оригинальном Anthropic API.
## Пример запроса
```bash
curl https://api.agentapi.ru/v1/ai/messages \
-H "x-api-key: agentapi-ВАШ_КЛЮЧ" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-3.5-sonnet",
"max_tokens": 300,
"system": "Отвечай кратко и по делу.",
"messages": [
{"role": "user", "content": "Чем отличается mutex от semaphore?"}
]
}'
```
## Ответ
```json
{
"id": "msg_7c1f9e2a-4b83-4d51-9f26-1a8e5d3c7b40",
"type": "message",
"role": "assistant",
"model": "anthropic/claude-3.5-sonnet",
"content": [
{
"type": "text",
"text": "Mutex допускает владение только одним потоком и требует освобождения тем же потоком. Semaphore — это счётчик, разрешающий одновременный доступ N потокам."
}
],
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": {
"input_tokens": 21,
"output_tokens": 58
}
}
```
| Поле | Описание |
|---|---|
| `id` | Формат `msg_` |
| `type` | Всегда `message` |
| `content[]` | Блоки: `text`, `thinking`, `tool_use` |
| `stop_reason` | `end_turn`, `max_tokens`, `tool_use`, `stop_sequence` |
| `usage` | `input_tokens` / `output_tokens` — терминология Anthropic |
## Стриминг
С `"stream": true` приходит SSE с **именованными** событиями (в отличие от Chat Completions,
где события безымянные):
```
event: message_start
data: {"type":"message_start","message":{"id":"msg_7c1f9e2a","type":"message","role":"assistant","model":"anthropic/claude-3.5-sonnet","content":[],"stop_reason":null,"usage":{"input_tokens":21,"output_tokens":0}}}
event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Mutex"}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" допускает"}}
event: content_block_stop
data: {"type":"content_block_stop","index":0}
event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"output_tokens":58}}
event: message_stop
data: {"type":"message_stop"}
```
Типы дельт:
| `delta.type` | Когда |
|---|---|
| `text_delta` | Обычный текст |
| `thinking_delta` | Блок размышлений при включённом `thinking` |
| `input_json_delta` | Аргументы инструмента приходят по частям |
Ошибка посреди потока:
```
event: error
data: {"type":"error","error":{"type":"api_error","message":"..."}}
```
## Инструменты
Формат Anthropic — `input_schema` вместо `parameters`:
```json
{
"model": "anthropic/claude-3.5-sonnet",
"max_tokens": 512,
"messages": [{"role": "user", "content": "Погода в Иркутске?"}],
"tools": [
{
"name": "get_weather",
"description": "Текущая погода в городе",
"input_schema": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"]
}
}
]
}
```
Ответ содержит блок `tool_use`:
```json
{
"id": "msg_2d5a8f31-9c74-4e60-b1a3-6f9d2c8e5b17",
"type": "message",
"role": "assistant",
"content": [
{
"type": "tool_use",
"id": "toolu_01A9F2",
"name": "get_weather",
"input": {"city": "Иркутск"}
}
],
"stop_reason": "tool_use",
"usage": {"input_tokens": 64, "output_tokens": 22}
}
```
## Режим размышлений
```json
{
"model": "anthropic/claude-3.5-sonnet",
"max_tokens": 2048,
"thinking": {"type": "enabled", "budget_tokens": 1024},
"messages": [{"role": "user", "content": "Реши: 17 × 23 без калькулятора"}]
}
```
В ответе появится блок `{"type": "thinking", "thinking": "…"}` перед текстовым блоком.
## Коды ошибок
| Код | Причина |
|---|---|
| 400 | Невалидные параметры или нулевой баланс |
| 401 | Проблема с ключом |
| 429 | Rate limit |
| 502 | Ошибка провайдера |
---
URL: https://agentapi.ru/docs/endpoints/responses
# Responses (OpenAI Responses API)
```
POST https://api.agentapi.ru/v1/ai/responses
```
Формат OpenAI Responses API: вместо массива `messages` передаётся `input`, а системная
инструкция — отдельным полем `instructions`.
> **Стриминг не поддерживается.** Параметр `stream` принимается, но игнорируется —
> ответ всегда приходит целиком. Если нужен поток, используйте
> [Chat Completions](https://agentapi.ru/docs/endpoints/chat-completions) или
> [Messages](https://agentapi.ru/docs/endpoints/messages).
## Параметры
Здесь параметры в snake_case — как в оригинальном API.
| Параметр | Тип | Описание |
|---|---|---|
| `input` | string \| array | **Основной ввод.** Текст или массив элементов |
| `model` | string | Слаг модели |
| `instructions` | string | Системная инструкция |
| `max_output_tokens` | number | Лимит генерации |
| `temperature` | number | 0–2 |
| `top_p` | number | Nucleus sampling |
| `frequency_penalty` | number | −2…2 |
| `presence_penalty` | number | −2…2 |
| `tools` | array | Инструменты в формате `{type, name, description, parameters}` |
| `tool_choice` | string \| object | Управление выбором инструмента |
| `previous_response_id` | string | Связывание с предыдущим ответом |
| `reasoning` | object | Настройка reasoning |
| `session_id` | string | Группировка запросов |
| `metadata` | object | Метаданные |
| `provider` | object | Предпочтения роутинга |
| `plugins` | array | Дополнительные плагины |
| `user` | string | Идентификатор конечного пользователя |
| `stream` | boolean | Принимается, но не действует |
## Пример запроса
```bash
curl https://api.agentapi.ru/v1/ai/responses \
-H "x-api-key: agentapi-ВАШ_КЛЮЧ" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-4.1",
"instructions": "Ты лаконичный ассистент.",
"input": "Перечисли три принципа SOLID",
"max_output_tokens": 200
}'
```
## Ответ
```json
{
"id": "resp_6a2f9c14",
"object": "response",
"created_at": 1753601180,
"model": "openai/gpt-4.1",
"status": "completed",
"output": [
{
"type": "message",
"role": "assistant",
"content": [
{
"type": "output_text",
"text": "1. Single Responsibility — у класса одна причина для изменения.\n2. Open/Closed — открыт для расширения, закрыт для модификации.\n3. Liskov Substitution — подтип заменяет базовый тип без нарушения контракта."
}
]
}
],
"usage": {
"input_tokens": 19,
"output_tokens": 74,
"total_tokens": 93
}
}
```
Текст лежит в `output[0].content[0].text` — глубже, чем в Chat Completions.
Терминология токенов — `input_tokens` / `output_tokens`.
## Инструменты
В отличие от Chat Completions, описание инструмента здесь плоское — без вложенного
объекта `function`:
```json
{
"model": "openai/gpt-4.1",
"input": "Погода в Иркутске?",
"tools": [
{
"type": "function",
"name": "get_weather",
"description": "Текущая погода в городе",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"]
}
}
]
}
```
## Коды ошибок
| Код | Причина |
|---|---|
| 400 | Невалидные параметры или нулевой баланс |
| 401 | Проблема с ключом |
| 429 | Rate limit |
| 502 | Ошибка провайдера |
---
URL: https://agentapi.ru/docs/endpoints/embeddings
# Embeddings
```
POST https://api.agentapi.ru/v1/ai/embeddings
```
Векторные представления текста — для семантического поиска, RAG и кластеризации.
Совместим с OpenAI Embeddings API.
## Параметры
| Параметр | Тип | Описание |
|---|---|---|
| `input` | string \| string[] | **Обязательный.** Текст или массив текстов |
| `model` | string | **Обязательный.** Модель с поддержкой embeddings, например `openai/text-embedding-3-small` |
| `encoding_format` | string | `float` (по умолчанию) или `base64` |
| `dimensions` | number | Размерность вектора, если модель это поддерживает |
| `input_type` | string | Подсказка типа входа: `query` или `document` |
| `user` | string | Идентификатор конечного пользователя |
| `provider` | object | Предпочтения роутинга |
> В отличие от остальных эндпоинтов, здесь **строгая валидация**: неизвестные поля
> вызывают `400`. Поддерживаются оба написания — `encoding_format` и `encodingFormat`,
> `input_type` и `inputType`.
## Пример запроса
```bash
curl https://api.agentapi.ru/v1/ai/embeddings \
-H "x-api-key: agentapi-ВАШ_КЛЮЧ" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/text-embedding-3-small",
"input": "Байкал — самое глубокое озеро в мире"
}'
```
```python
from openai import OpenAI
client = OpenAI(
api_key="agentapi-ВАШ_КЛЮЧ",
base_url="https://api.agentapi.ru/v1/ai",
)
result = client.embeddings.create(
model="openai/text-embedding-3-small",
input=["Первый документ", "Второй документ"],
)
for item in result.data:
print(item.index, len(item.embedding))
```
## Ответ
```json
{
"id": "emb-1753601440-Lp7",
"object": "list",
"model": "openai/text-embedding-3-small",
"data": [
{
"object": "embedding",
"index": 0,
"embedding": [-0.0142, 0.0318, -0.0071, 0.0455, "…ещё 1532 значения"]
}
],
"usage": {
"prompt_tokens": 11,
"total_tokens": 11
}
}
```
При массиве на входе элементы `data` идут в том же порядке, а `index` соответствует
позиции во входном массиве.
## Пакетная обработка
Передавайте массив вместо отдельных запросов — это быстрее и дешевле по накладным расходам:
```json
{
"model": "openai/text-embedding-3-small",
"input": [
"Первый документ",
"Второй документ",
"Третий документ"
]
}
```
## Уменьшение размерности
Некоторые модели позволяют сократить вектор — меньше памяти в векторной базе при
небольшой потере качества:
```json
{
"model": "openai/text-embedding-3-small",
"input": "Текст",
"dimensions": 512
}
```
## Rate limit
Этот эндпоинт **исключён из общего ограничения** запросов в минуту — пакетная
индексация не упирается в лимит. Ограничением остаётся баланс аккаунта.
## Коды ошибок
| Код | Причина |
|---|---|
| 400 | Отсутствует `model`/`input`, неизвестное поле, или нулевой баланс |
| 401 | Проблема с ключом |
| 502 | Ошибка провайдера, либо модель не поддерживает embeddings |
Модели с поддержкой embeddings **не отображаются** в общем списке
[`GET /models`](https://agentapi.ru/docs/models) — он их отфильтровывает. Названия берите из документации
провайдера.
---
URL: https://agentapi.ru/docs/integrations/continue
# Continue (VS Code / JetBrains)
[Continue](https://continue.dev) — открытый ассистент для VS Code и JetBrains: чат,
автодополнение и правки в редакторе. Поддерживает провайдер `openai` с произвольным
`apiBase`, поэтому AgentAPI подключается без плагинов и прокси.
## Какой эндпоинт для какой роли
```mermaid
flowchart LR
subgraph IDE["Continue в редакторе"]
C1["Чат"]
C2["Автодополнение
(tab)"]
C3["@codebase
индексация"]
C4["Rerank"]
end
C1 --> E1["POST /v1/ai/chat/completions"]
C2 --> E1
C3 --> E2["POST /v1/ai/embeddings"]
C4 -.->|"не поддерживается"| X["нет эндпоинта rerank"]
E1 --> A["api.agentapi.ru"]
E2 --> A
```
## Настройка
Откройте `~/.continue/config.yaml` (в новых версиях — кнопка настроек в панели Continue).
```yaml
name: AgentAPI
version: 1.0.0
schema: v1
models:
- name: GPT-4.1
provider: openai
model: openai/gpt-4.1
apiBase: https://api.agentapi.ru/v1/ai
apiKey: agentapi-ВАШ_КЛЮЧ
roles:
- chat
- edit
- apply
- name: Claude 3.5 Sonnet
provider: openai
model: anthropic/claude-3.5-sonnet
apiBase: https://api.agentapi.ru/v1/ai
apiKey: agentapi-ВАШ_КЛЮЧ
roles:
- chat
- edit
- name: Автодополнение
provider: openai
model: openai/gpt-4.1-mini
apiBase: https://api.agentapi.ru/v1/ai
apiKey: agentapi-ВАШ_КЛЮЧ
roles:
- autocomplete
- name: Embeddings
provider: openai
model: openai/text-embedding-3-small
apiBase: https://api.agentapi.ru/v1/ai
apiKey: agentapi-ВАШ_КЛЮЧ
roles:
- embed
```
Три обязательных момента:
1. **`provider: openai`** — именно `openai`, даже для моделей Claude или Gemini: AgentAPI
отдаёт OpenAI-совместимый формат для всех моделей.
2. **`apiBase` заканчивается на `/v1/ai`** — без `/chat/completions`. Continue допишет
путь сам.
3. **`model` — полный слаг** с префиксом провайдера: `openai/gpt-4.1`, не `gpt-4.1`.
### Старый формат `config.json`
Если у вас версия с JSON-конфигом:
```json
{
"models": [
{
"title": "GPT-4.1",
"provider": "openai",
"model": "openai/gpt-4.1",
"apiBase": "https://api.agentapi.ru/v1/ai",
"apiKey": "agentapi-ВАШ_КЛЮЧ"
}
],
"tabAutocompleteModel": {
"title": "Автодополнение",
"provider": "openai",
"model": "openai/gpt-4.1-mini",
"apiBase": "https://api.agentapi.ru/v1/ai",
"apiKey": "agentapi-ВАШ_КЛЮЧ"
},
"embeddingsProvider": {
"provider": "openai",
"model": "openai/text-embedding-3-small",
"apiBase": "https://api.agentapi.ru/v1/ai",
"apiKey": "agentapi-ВАШ_КЛЮЧ"
}
}
```
## Индексация проекта (`@codebase`)
Роль `embed` из конфига выше включает семантический поиск по коду. Эндпоинт embeddings
**не подпадает под rate limit**, поэтому первичная индексация большого репозитория не
упирается в ограничение запросов — но токены оплачиваются, так что для крупных
монорепозиториев оцените стоимость заранее.
## Параметры генерации
Ограничения задаются как обычно и **применяются**:
```yaml
models:
- name: GPT-4.1
provider: openai
model: openai/gpt-4.1
apiBase: https://api.agentapi.ru/v1/ai
apiKey: agentapi-ВАШ_КЛЮЧ
defaultCompletionOptions:
temperature: 0.2
maxTokens: 2048
```
## Что не заработает
| Возможность | Причина |
|---|---|
| Выпадающий список моделей | Внешнего `GET /v1/ai/models` нет — модели описываются в конфиге вручную |
| Rerank-модели | Эндпоинта переранжирования у AgentAPI нет. Не указывайте роль `rerank` |
| Прикрепление изображений в чате | `content` принимает только строку, см. [Ограничения](https://agentapi.ru/docs/limitations) |
## Диагностика
| Симптом | Что проверить |
|---|---|
| `404` в логах Continue | В `apiBase` пропущен `/ai`, либо указан `agentapi.ru` вместо `api.agentapi.ru` |
| Путь `…/chat/completions/chat/completions` | В `apiBase` записан полный путь эндпоинта |
| `401 Invalid API key format` | В `apiKey` не ключ `agentapi-*` |
| `400 Negative or zero balance` | Пустой баланс — пополните счёт |
| `502` при валидном ключе | Неверный слаг модели — проверьте в каталоге [Моделей](https://agentapi.ru/models) |
Логи: **Output → Continue** в панели VS Code.
---
URL: https://agentapi.ru/docs/integrations/cline
# Cline (VS Code)
[Cline](https://github.com/cline/cline) — автономный агент в VS Code: читает и правит
файлы, запускает команды в терминале. Поддерживает провайдер «OpenAI Compatible»,
через него и подключается AgentAPI.
## Настройка
1. Установите расширение **Cline** из Marketplace.
2. Откройте панель Cline → значок настроек (⚙).
3. Заполните поля:
| Поле | Значение |
|---|---|
| **API Provider** | `OpenAI Compatible` |
| **Base URL** | `https://api.agentapi.ru/v1/ai` |
| **API Key** | `agentapi-ВАШ_КЛЮЧ` |
| **Model ID** | `anthropic/claude-3.5-sonnet` |
Base URL заканчивается на `/v1/ai` — Cline сам добавляет `/chat/completions`.
Model ID вводится вручную полным слагом: список моделей автоматически не подгружается,
так как внешнего `GET /v1/ai/models` у AgentAPI нет.
## Выбор модели
Cline ведёт длинные многоходовые диалоги с большим контекстом (содержимое файлов,
история вызовов инструментов), поэтому расход токенов заметно выше, чем в обычном чате.
Разумные варианты:
| Модель | Когда |
|---|---|
| `anthropic/claude-3.5-sonnet` | Базовый выбор: хорошо следует инструкциям агента |
| `openai/gpt-4.1` | Альтернатива с большим контекстом |
| `deepseek/deepseek-chat` | Существенно дешевле для простых задач |
Проверяйте расход в [статистике](https://agentapi.ru/docs/billing) после первых сессий.
## Настройка контекста
В расширенных настройках Cline стоит задать:
- **Max output tokens** — ограничивает длину одного ответа; параметр доходит до API
и применяется.
- **Auto-approve** — держите выключенным, пока не убедитесь в поведении модели:
агент исполняет команды в терминале.
## Про вызов инструментов
Cline описывает инструменты текстом системного промпта и разбирает ответ модели сам,
не полагаясь на native function calling. Поэтому агентный цикл работает на любой
достаточно сильной модели.
## Что учесть
| Особенность | Следствие |
|---|---|
| Нет списка моделей | Model ID вводится руками |
| Изображения в контексте | Не поддерживаются: `content` принимает только строку (см. [Ограничения](https://agentapi.ru/docs/limitations)) |
| Rate limit по IP | 60 запросов в минуту на IP. Активный агентный цикл может упереться — при 429 подождите минуту |
## Диагностика
| Симптом | Что проверить |
|---|---|
| `404 Not Found` | В Base URL пропущен `/ai` или указан не тот хост |
| `401 Invalid API key format` | Ключ должен начинаться с `agentapi-` |
| `400 Negative or zero balance` | Пополните баланс |
| `502` | Неверный Model ID — сверьтесь с каталогом [Моделей](https://agentapi.ru/models) |
| `429` | Лимит 60 запросов/минуту по IP |
---
URL: https://agentapi.ru/docs/integrations/roo-code
# Roo Code (VS Code)
[Roo Code](https://github.com/RooCodeInc/Roo-Code) — форк Cline с режимами работы
(Code, Architect, Ask, Debug) и возможностью назначить разную модель каждому режиму.
Подключается через провайдер «OpenAI Compatible».
## Настройка
1. Установите расширение **Roo Code** из Marketplace.
2. Панель Roo Code → ⚙ → **Providers**.
3. Заполните:
| Поле | Значение |
|---|---|
| **API Provider** | `OpenAI Compatible` |
| **Base URL** | `https://api.agentapi.ru/v1/ai` |
| **API Key** | `agentapi-ВАШ_КЛЮЧ` |
| **Model** | `anthropic/claude-3.5-sonnet` |
Base URL — до `/v1/ai`, без `/chat/completions`. Модель вводится вручную полным слагом.
## Разные модели под разные режимы
Главное преимущество Roo Code — можно не платить за флагманскую модель там, где хватает
дешёвой. Создайте несколько профилей конфигурации (**Providers → +**), в каждом тот же
Base URL и ключ, но своя модель, и назначьте профиль режиму:
| Режим | Что делает | Разумная модель |
|---|---|---|
| **Code** | Пишет и правит код | `anthropic/claude-3.5-sonnet` |
| **Architect** | Планирует, не трогая файлы | `openai/gpt-4.1` |
| **Ask** | Отвечает на вопросы по коду | `deepseek/deepseek-chat` |
| **Debug** | Ищет причину ошибки | `anthropic/claude-3.5-sonnet` |
## Индексация кодовой базы
Если включаете семантический поиск, укажите там же embedding-модель:
| Поле | Значение |
|---|---|
| **Embedding Provider** | `OpenAI Compatible` |
| **Base URL** | `https://api.agentapi.ru/v1/ai` |
| **API Key** | `agentapi-ВАШ_КЛЮЧ` |
| **Model** | `openai/text-embedding-3-small` |
Эндпоинт embeddings не лимитируется по числу запросов, но токены оплачиваются —
для больших репозиториев оцените стоимость заранее.
## Что учесть
| Особенность | Следствие |
|---|---|
| Нет списка моделей | Слаг вводится вручную — внешнего `GET /v1/ai/models` нет |
| Изображения | Не поддерживаются, см. [Ограничения](https://agentapi.ru/docs/limitations) |
| Rate limit | 60 запросов/минуту **по IP**, общий для всех профилей и ключей |
## Диагностика
| Симптом | Что проверить |
|---|---|
| `404` | Пропущен `/ai` в Base URL или неверный хост |
| `401` | Ключ не начинается с `agentapi-` |
| `400 Negative or zero balance` | Пустой баланс |
| `502` | Неверный слаг модели |
| `429` | Лимит по IP — подождите минуту |
---
URL: https://agentapi.ru/docs/integrations/claude-code
# Claude Code и Anthropic SDK
AgentAPI отдаёт Anthropic-совместимый эндпоинт
[`POST /v1/ai/messages`](https://agentapi.ru/docs/endpoints/messages) с настоящим Anthropic SSE. Но путь
содержит сегмент `/ai`, и это создаёт нюанс, который надо понимать до настройки.
## Почему нельзя просто подменить base URL
Anthropic SDK и Claude Code дописывают к базовому URL фиксированный путь `/v1/messages`.
Нужный адрес — `/v1/**ai**/messages`, где лишний сегмент стоит **посередине**. Подставить
его через базовый URL невозможно:
```mermaid
flowchart TD
A["ANTHROPIC_BASE_URL=
https://api.agentapi.ru"] --> A1["→ /v1/messages"] --> A2["404 ❌"]
B["ANTHROPIC_BASE_URL=
https://api.agentapi.ru/ai"] --> B1["→ /ai/v1/messages"] --> B2["404 ❌"]
C["Нужно попасть в"] --> C1["/v1/ai/messages ✅"]
```
Поэтому ниже — три рабочих варианта в порядке простоты.
## Вариант 1: прямые HTTP-запросы (работает сразу)
Если вы пишете код сами, а не подключаете готовый клиент, — просто вызывайте эндпоинт
по полному пути. Никаких обходных путей не нужно.
```bash
curl https://api.agentapi.ru/v1/ai/messages \
-H "x-api-key: agentapi-ВАШ_КЛЮЧ" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-3.5-sonnet",
"max_tokens": 300,
"system": "Отвечай кратко.",
"messages": [{"role": "user", "content": "Привет!"}]
}'
```
```python
import os, requests
response = requests.post(
"https://api.agentapi.ru/v1/ai/messages",
headers={"x-api-key": os.environ["AGENTAPI_KEY"]},
json={
"model": "anthropic/claude-3.5-sonnet",
"max_tokens": 300,
"messages": [{"role": "user", "content": "Привет!"}],
},
timeout=120,
)
data = response.json()
print(data["content"][0]["text"])
```
Формат ответа — [Messages](https://agentapi.ru/docs/endpoints/messages).
## Вариант 2: Anthropic SDK с явным путём
SDK можно оставить ради типов и обработки ошибок, обойдя сборку пути через
низкоуровневый `post`:
```typescript
import Anthropic from "@anthropic-ai/sdk";
import type { Message } from "@anthropic-ai/sdk/resources/messages";
const client = new Anthropic({
apiKey: process.env.AGENTAPI_KEY,
baseURL: "https://api.agentapi.ru",
});
// Путь указывается целиком, поэтому `/v1/messages` не подставляется автоматически.
const message = await client.post("/v1/ai/messages", {
body: {
model: "anthropic/claude-3.5-sonnet",
max_tokens: 300,
messages: [{ role: "user", content: "Привет!" }],
},
});
console.log(message.content);
```
```python
import os
from anthropic import Anthropic
client = Anthropic(
api_key=os.environ["AGENTAPI_KEY"],
base_url="https://api.agentapi.ru",
)
message = client.post(
"/v1/ai/messages",
body={
"model": "anthropic/claude-3.5-sonnet",
"max_tokens": 300,
"messages": [{"role": "user", "content": "Привет!"}],
},
cast_to=object,
)
print(message)
```
Штатные вызовы `client.messages.create(...)` при этом **не** заработают — они собирают
путь сами. Учтите и то, что `post` — низкоуровневый метод: его сигнатура может меняться
между версиями SDK.
## Вариант 3: Claude Code через локальный прокси
Claude Code настраивается только переменной `ANTHROPIC_BASE_URL` и жёстко дописывает
`/v1/messages`, поэтому напрямую подключить его нельзя. Нужен локальный прокси,
переписывающий путь.
Минимальный вариант на Node.js (без зависимостей):
```javascript
// agentapi-proxy.mjs — запуск: node agentapi-proxy.mjs
import { createServer } from "node:http";
const UPSTREAM = "https://api.agentapi.ru";
const API_KEY = process.env.AGENTAPI_KEY;
if (!API_KEY) throw new Error("Задайте AGENTAPI_KEY");
createServer(async (req, res) => {
// /v1/messages -> /v1/ai/messages, остальное проксируем как есть.
const path = req.url.startsWith("/v1/messages")
? req.url.replace("/v1/messages", "/v1/ai/messages")
: req.url;
const chunks = [];
for await (const chunk of req) chunks.push(chunk);
const upstream = await fetch(`${UPSTREAM}${path}`, {
method: req.method,
headers: {
"content-type": "application/json",
"x-api-key": API_KEY,
},
body: chunks.length ? Buffer.concat(chunks) : undefined,
});
res.writeHead(upstream.status, {
"content-type":
upstream.headers.get("content-type") ?? "application/json",
"cache-control": "no-cache",
});
// Ответ может быть SSE, поэтому передаём его потоком, а не целиком.
if (upstream.body) {
for await (const chunk of upstream.body) res.write(chunk);
}
res.end();
}).listen(8787, () => console.log("Прокси: http://localhost:8787"));
```
Запуск:
```bash
export AGENTAPI_KEY=agentapi-ВАШ_КЛЮЧ
node agentapi-proxy.mjs
```
В другом терминале:
```bash
export ANTHROPIC_BASE_URL=http://localhost:8787
export ANTHROPIC_AUTH_TOKEN=agentapi-ВАШ_КЛЮЧ
export ANTHROPIC_MODEL=anthropic/claude-3.5-sonnet
claude
```
Прокси слушает только localhost и подставляет ключ сам — не публикуйте его в сеть.
### Альтернатива на LiteLLM
Если прокси уже есть в инфраструктуре, тот же результат даёт
[LiteLLM](https://docs.litellm.ai):
```yaml
# litellm-config.yaml — запуск: litellm --config litellm-config.yaml
model_list:
- model_name: claude-3.5-sonnet
litellm_params:
model: openai/anthropic/claude-3.5-sonnet
api_base: https://api.agentapi.ru/v1/ai
api_key: os.environ/AGENTAPI_KEY
```
Здесь используется OpenAI-совместимый эндпоинт, который подставляется базовым URL без
проблем, а Anthropic-формат для клиента обеспечивает сам LiteLLM.
## Что было бы правильным решением
Нюанс с путём — следствие того, что внешний модуль смонтирован как `/v1` + контроллер
`ai`. Достаточно добавить алиас `POST /v1/messages` на тот же обработчик, и Claude Code
с Anthropic SDK заработают без прокси. Сейчас такого алиаса нет — если он важен для вашего
сценария, напишите на [agent@agentapi.ru](mailto:agent@agentapi.ru).
## Диагностика
| Симптом | Причина |
|---|---|
| `404` на `/v1/messages` | Ожидаемо: правильный путь — `/v1/ai/messages` |
| `401 Invalid API key format` | В `ANTHROPIC_AUTH_TOKEN` не ключ `agentapi-*` |
| Claude Code не видит модель | В `ANTHROPIC_MODEL` нужен полный слаг: `anthropic/claude-3.5-sonnet` |
| `400 Negative or zero balance` | Пополните баланс |
---
URL: https://agentapi.ru/docs/integrations/sdk
# SDK и прямые запросы
AgentAPI совместим с OpenAI Chat Completions, поэтому подходит любой клиент, который
позволяет задать base URL. Ключевое правило одно.
> **Base URL — `https://api.agentapi.ru/v1/ai`.**
> Без `/chat/completions` на конце: SDK добавляет путь сам. Если передать полный путь,
> запрос уйдёт на `…/v1/ai/chat/completions/chat/completions` и вернёт 404.
## OpenAI SDK (TypeScript)
```bash
npm install openai
```
```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: "user", content: "Привет!" }],
max_tokens: 500,
});
console.log(completion.choices[0].message.content);
```
Стриминг:
```typescript
const stream = await client.chat.completions.create({
model: "openai/gpt-4.1",
messages: [{ role: "user", content: "Расскажи о Байкале" }],
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}
```
## OpenAI SDK (Python)
```bash
pip install openai
```
```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": "user", "content": "Привет!"}],
max_tokens=500,
)
print(completion.choices[0].message.content)
print(completion.usage.total_tokens, completion.usage.prompt_tokens)
```
Стриминг:
```python
stream = client.chat.completions.create(
model="openai/gpt-4.1",
messages=[{"role": "user", "content": "Расскажи о Байкале"}],
stream=True,
)
for chunk in stream:
delta = chunk.choices[0].delta.content
if delta:
print(delta, end="", flush=True)
```
## Vercel AI SDK
```bash
npm install ai @ai-sdk/openai-compatible
```
```typescript
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
import { streamText } from "ai";
const agentapi = createOpenAICompatible({
name: "agentapi",
baseURL: "https://api.agentapi.ru/v1/ai",
apiKey: process.env.AGENTAPI_KEY,
});
const result = streamText({
model: agentapi("openai/gpt-4.1"),
prompt: "Объясни event loop в двух абзацах",
});
for await (const chunk of result.textStream) {
process.stdout.write(chunk);
}
```
## LangChain
```python
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="openai/gpt-4.1",
api_key="agentapi-ВАШ_КЛЮЧ",
base_url="https://api.agentapi.ru/v1/ai",
)
print(llm.invoke("Привет!").content)
```
Embeddings для векторного поиска:
```python
from langchain_openai import OpenAIEmbeddings
embeddings = OpenAIEmbeddings(
model="openai/text-embedding-3-small",
api_key="agentapi-ВАШ_КЛЮЧ",
base_url="https://api.agentapi.ru/v1/ai",
)
vector = embeddings.embed_query("Байкал")
print(len(vector))
```
## Go
```bash
go get github.com/sashabaranov/go-openai
```
```go
package main
import (
"context"
"fmt"
"os"
openai "github.com/sashabaranov/go-openai"
)
func main() {
config := openai.DefaultConfig(os.Getenv("AGENTAPI_KEY"))
config.BaseURL = "https://api.agentapi.ru/v1/ai"
client := openai.NewClientWithConfig(config)
resp, err := client.CreateChatCompletion(
context.Background(),
openai.ChatCompletionRequest{
Model: "openai/gpt-4.1",
Messages: []openai.ChatCompletionMessage{
{Role: openai.ChatMessageRoleUser, Content: "Привет!"},
},
},
)
if err != nil {
fmt.Printf("Ошибка: %v\n", err)
return
}
fmt.Println(resp.Choices[0].Message.Content)
}
```
## Без SDK: fetch
```typescript
const response = await fetch(
"https://api.agentapi.ru/v1/ai/chat/completions",
{
method: "POST",
headers: {
"x-api-key": process.env.AGENTAPI_KEY!,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "openai/gpt-4.1",
messages: [{ role: "user", content: "Привет!" }],
}),
},
);
if (!response.ok) {
throw new Error(`AgentAPI ${response.status}: ${await response.text()}`);
}
const data = await response.json();
console.log(data.choices[0].message.content);
```
Ручной разбор SSE:
```typescript
const response = await fetch(
"https://api.agentapi.ru/v1/ai/chat/completions",
{
method: "POST",
headers: {
"x-api-key": process.env.AGENTAPI_KEY!,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "openai/gpt-4.1",
messages: [{ role: "user", content: "Привет!" }],
stream: true,
}),
},
);
const reader = response.body!.getReader();
const decoder = new TextDecoder();
let buffer = "";
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split("\n");
// Последняя строка может быть неполной — оставляем её в буфере.
buffer = lines.pop() ?? "";
for (const line of lines) {
if (!line.startsWith("data: ")) continue;
const payload = line.slice(6);
if (payload === "[DONE]") continue;
const chunk = JSON.parse(payload);
// Ошибки приходят внутри потока при статусе 200.
if (chunk.error) throw new Error(chunk.error.message);
process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}
}
```
## Что стоит помнить
| | |
|---|---|
| Слаг модели | С префиксом провайдера: `openai/gpt-4.1`, не `gpt-4.1` |
| Заголовок | `apiKey` в SDK уходит как `Authorization: Bearer` — этого достаточно |
| Расход | Токены — в `usage` ответа, рублёвые списания — в [транзакциях](https://agentapi.ru/docs/billing) |
| Ошибки | Не в OpenAI-формате `{error: {type, code}}` — см. [Ошибки](https://agentapi.ru/docs/errors) |
| Изображения | Не поддерживаются, см. [Ограничения](https://agentapi.ru/docs/limitations) |
---
URL: https://agentapi.ru/docs/errors
# Ошибки и лимиты
## Формат ошибок
Большинство ошибок приходят в стандартном формате:
```json
{
"statusCode": 401,
"message": "Invalid or inactive API key",
"error": "Unauthorized"
}
```
Ошибки валидации содержат массив в `message`:
```json
{
"statusCode": 400,
"message": [
"temperature must not be greater than 2",
"messages should not be empty"
],
"error": "Bad Request"
}
```
> Формат отличается от OpenAI: ответ **не** обёрнут в объект `error` с полями
> `type` и `code`. Библиотеки, ожидающие OpenAI-формат ошибок, покажут сообщение,
> но не смогут разобрать его тип.
## Коды ответов
### 400 — Bad Request
| Сообщение | Причина |
|---|---|
| `Negative or zero balance. Available: 0.00 RUB. Please top up your account.` | Баланс исчерпан. Пополните счёт в [профиле](https://agentapi.ru/profile) |
| массив сообщений валидации | Параметр вне допустимого диапазона или отсутствует обязательное поле |
| `content must be a string` | Передан массив блоков в `content` — мультимодальный ввод не поддерживается |
| `property X should not exist` | Неизвестное поле в запросе к `/v1/ai/embeddings` (там строгая валидация) |
Баланс проверяется **до** отправки запроса провайдеру. Он может стать отрицательным
после списания за уже выполненный запрос — блокируется только следующий.
### 401 — Unauthorized
| Сообщение | Причина |
|---|---|
| `API key is required in x-api-key or Authorization header` | Заголовок не передан |
| `Invalid API key format` | Ключ не начинается с `agentapi-` |
| `Invalid or inactive API key` | Ключ не найден или отключён (`active = false`) |
| `API key not found` | Ключ не связан с пользователем |
### 403 — Forbidden
`Insufficient balance to create an API key` — при попытке создать ключ с нулевым балансом.
### 404 — Not Found
Чаще всего означает **неверный URL**, а не отсутствующий ресурс:
| Что запрошено | Проблема |
|---|---|
| `https://agentapi.ru/v1/...` | Основной домен отдаёт сайт. Нужен `api.agentapi.ru` |
| `https://api.agentapi.ru/v1/chat/completions` | Пропущен сегмент `/ai` |
| `https://api.agentapi.ru/v1/messages` | Правильный путь — `/v1/ai/messages` |
### 429 — Too Many Requests
```json
{
"statusCode": 429,
"message": "ThrottlerException: Too Many Requests"
}
```
### 502 — Bad Gateway
Ошибка на стороне провайдера. Формат **отличается** от остальных — без поля `statusCode`:
```json
{
"message": "Provider returned error: model not found"
}
```
Типичные причины: неверный слаг модели, модель временно недоступна, запрос отклонён
провайдером. Для устойчивости используйте
[fallback-роутинг](https://agentapi.ru/docs/models) через `models[]`.
### Ошибки внутри стрима
Если генерация оборвалась после начала стриминга, HTTP-статус уже равен 200 — заголовки
отправлены до первого токена. Ошибка приходит кадром:
```
data: {"error":{"message":"..."}}
```
Для формата Anthropic — именованным событием:
```
event: error
data: {"type":"error","error":{"type":"api_error","message":"..."}}
```
Поэтому проверяйте поле `error` в каждом кадре, а не только код ответа.
> Сейчас в теле такого кадра сообщение может сериализоваться как пустой объект
> (`{"error":{"message":{}}}`) — см. [Ограничения](https://agentapi.ru/docs/limitations).
## Rate limit
| | |
|---|---|
| Лимит | 60 запросов за 60 секунд |
| Ключ подсчёта | **IP-адрес**, не API-ключ |
| Исключение | `POST /v1/ai/embeddings` — не лимитируется |
Важные следствия:
- Лимит считается по IP, поэтому несколько приложений с одного сервера (или из-за одного
NAT) расходуют **общий** лимит, даже с разными ключами.
- Разные ключи одного аккаунта не дают независимых лимитов.
- Стриминговый запрос — это один запрос независимо от длительности.
Ограничения на количество токенов в минуту нет: фактический потолок — баланс аккаунта
и лимиты самого провайдера.
## Рекомендации по обработке
| Код | Стратегия |
|---|---|
| 400 (баланс) | Не повторять. Уведомить о пополнении |
| 400 (валидация) | Не повторять. Исправить запрос |
| 401 | Не повторять. Проверить ключ |
| 429 | Повтор с экспоненциальной задержкой |
| 502 | Повтор 1–2 раза; при повторе — сменить модель через `models[]` |
Пример повторов только для восстановимых ошибок:
```typescript
async function withRetry(fn: () => Promise, attempts = 3): Promise {
for (let i = 0; i < attempts; i++) {
try {
return await fn();
} catch (error) {
const status = (error as { status?: number }).status;
// Повторяем только то, что может пройти со второй попытки.
if (status !== 429 && status !== 502) throw error;
if (i === attempts - 1) throw error;
await new Promise((r) => setTimeout(r, 2 ** i * 1000));
}
}
throw new Error("unreachable");
}
```
---
URL: https://agentapi.ru/docs/billing
# Биллинг
Модель оплаты — предоплаченный баланс в рублях. Списание происходит по факту
использованных токенов, без подписок и минимальных платежей.
## Как считается стоимость
Оплачивается фактическое использование: и входные, и выходные токены. Стоимость зависит от
выбранной модели — тарифы указаны в каталоге [Моделей](https://agentapi.ru/models).
Списание происходит в рублях после выполнения запроса. Точную сумму по каждому запросу
видно в [транзакциях](#транзакции).
## Сколько израсходовал запрос
Количество токенов приходит в поле `usage` ответа:
```json
{
"usage": {
"prompt_tokens": 24,
"completion_tokens": 71,
"total_tokens": 95
}
}
```
При стриминге `usage` приходит в последнем кадре перед `data: [DONE]`.
Рублёвую сумму списания смотрите в транзакциях — она появляется там после запроса.
## Списание при стриминге
Стриминг не ждёт расчёта: токены отдаются клиенту сразу, а списание происходит по
завершении генерации.
Если клиент оборвал соединение до конца ответа, запрос может остаться несписанным.
## Баланс
```
GET https://api.agentapi.ru/billing/balance
```
Требует JWT (не API-ключ), см. [Аутентификация](https://agentapi.ru/docs/authentication).
```bash
curl https://api.agentapi.ru/billing/balance \
-H "Authorization: Bearer $JWT"
```
```json
{ "balance": 1500.5 }
```
Баланс проверяется перед каждым запросом: при `balance <= 0` приходит
`400 Negative or zero balance`. Баланс может уйти в минус после списания за уже
выполненный запрос — блокируется только следующий.
## Транзакции
```
GET https://api.agentapi.ru/billing/transactions?limit=50&offset=0
```
```json
{
"transactions": [
{
"id": "8c3f1a95-2d47-4e18-b6a0-9f5e2c7d3b81",
"type": "debit",
"amount": "0.035000",
"currency": "RUB",
"description": "Chat completion: openai/gpt-4.1",
"promptTokens": 24,
"completionTokens": 71,
"totalTokens": 95,
"model": "openai/gpt-4.1",
"createdAt": "2026-07-27T09:15:42.108Z"
}
],
"total": 428
}
```
Тип `debit` — списание за использование, `credit` — пополнение. Поле `amount` — сумма
в рублях, `model` — модель, за которую списано.
## Статистика
```
GET https://api.agentapi.ru/billing/stats?startDate=2026-07-01&endDate=2026-07-27
```
```json
{
"totalSpent": 214.87,
"totalRequests": 1043,
"averageCost": 0.206
}
```
Расход по дням:
```
GET https://api.agentapi.ru/stats/usage?period=30d
```
`period` — `7d`, `30d` или `90d`.
```json
{
"summary": {
"totalTokens": 1842905,
"totalCost": 214.87,
"currency": "RUB",
"period": "30d"
},
"daily": [
{ "date": "2026-07-26", "tokens": 84120, "cost": 9.74, "requests": 47 },
{ "date": "2026-07-27", "tokens": 12508, "cost": 1.43, "requests": 9 }
]
}
```
За всё время:
```
GET https://api.agentapi.ru/stats/lifetime
```
```json
{ "totalTokens": 14820355, "totalCost": 1734.02 }
```
Статистика агрегируется **по аккаунту**. Разбивки по отдельным ключам нет — если нужно
разделять расходы по проектам, используйте поле `metadata` или `session_id` в запросах
и считайте на своей стороне.
## Пополнение
Через интерфейс [профиля](https://agentapi.ru/profile) (YooKassa). Лимиты — от 100 ₽ до 100 000 ₽ за платёж.
Пополнение необходимо и для **создания** ключа: при нулевом балансе создание вернёт
`403 Insufficient balance to create an API key`.
## Как сократить расходы
- **Выбирайте модель под задачу.** Разница в цене между флагманскими и компактными
моделями — порядок и больше. Цены за токен видны в каталоге [Моделей](https://agentapi.ru/models).
- **Ограничивайте `max_tokens`.** Оплачивается и ввод, и вывод.
- **Следите за длиной контекста.** В многоходовом диалоге вся история пересылается
заново на каждом шаге — обрезайте старые сообщения.
- **Прогоните репрезентативные запросы** и посмотрите транзакции и статистику, прежде чем
выводить фичу в продакшн.
---
URL: https://agentapi.ru/docs/limitations
# Известные ограничения
Список того, что сейчас работает не так, как можно ожидать от OpenAI-совместимого API.
Написан честно, чтобы вы не отлаживали чужие баги как свои.
## Мультимодальный ввод не поддерживается
Поле `content` в сообщении принимает **только строку**. Массив блоков, которым OpenAI
передаёт изображения, отклоняется валидацией:
```json
{
"messages": [{
"role": "user",
"content": [
{"type": "text", "text": "Что на картинке?"},
{"type": "image_url", "image_url": {"url": "data:image/png;base64,..."}}
]
}]
}
```
```json
{
"statusCode": 400,
"message": ["content must be a string"],
"error": "Bad Request"
}
```
Следствие: vision-возможности недоступны даже у моделей, которые их поддерживают, а
плагины с прикреплением скриншотов (Cline, Roo Code, Continue) не смогут отправить
изображение.
**Обходного пути на стороне API нет.** Описывайте изображение текстом либо распознавайте
его отдельным сервисом.
## `/v1/ai/responses` не умеет стриминг
Параметр `stream` принимается без ошибки, но **игнорируется** — ответ всегда приходит
целиком. Клиент, ожидающий поток, будет ждать полной генерации.
Для стриминга используйте [Chat Completions](https://agentapi.ru/docs/endpoints/chat-completions) или
[Messages](https://agentapi.ru/docs/endpoints/messages).
## `stop_sequences` в `/v1/ai/messages` не применяется
Поле парсится и проходит валидацию, но до провайдера не доходит — генерация не
остановится на указанной последовательности.
Обход: используйте `stop` в [Chat Completions](https://agentapi.ru/docs/endpoints/chat-completions), где
параметр работает, либо обрезайте ответ на своей стороне.
## Путь Anthropic-эндпоинта нестандартный
Эндпоинт находится по адресу `/v1/ai/messages`, а не `/v1/messages`. Клиенты, жёстко
дописывающие `/v1/messages` к базовому URL (Claude Code, `client.messages.create()` в
Anthropic SDK), напрямую не подключаются.
Рабочие варианты описаны в [Claude Code и Anthropic SDK](https://agentapi.ru/docs/integrations/claude-code).
## Нет списка моделей во внешнем API
Эндпоинта `GET /v1/ai/models` не существует. Плагины и клиенты, подтягивающие модели
автоматически, покажут пустой список — слаг вводится вручную.
Список моделей доступен через `GET /models` (без префикса `/v1`, ключ не требуется),
но этот путь не соответствует ожиданиям OpenAI-клиентов. См. [Модели](https://agentapi.ru/docs/models).
## Ошибка внутри стрима приходит пустой
Если генерация оборвалась после начала стриминга, кадр с ошибкой может не содержать
текста сообщения:
```
data: {"error":{"message":{}}}
```
Причина — сериализация объекта ошибки. HTTP-статус при этом уже 200, поскольку заголовки
отправлены до первого токена.
Практический вывод: проверяйте **наличие** поля `error` в кадрах и не рассчитывайте на
информативный текст. Причину смотрите по коду ответа при повторе того же запроса без
`stream`.
## Формат ошибок отличается от OpenAI
Ответ не обёрнут в объект `error` с полями `type` и `code`:
```json
{ "statusCode": 401, "message": "Invalid or inactive API key", "error": "Unauthorized" }
```
Ошибки провайдера (502) приходят в третьем формате — вообще без `statusCode`:
```json
{ "message": "Provider returned error: model not found" }
```
Библиотеки, разбирающие OpenAI-формат ошибок, покажут текст, но не определят тип.
См. [Ошибки и лимиты](https://agentapi.ru/docs/errors).
## Rate limit считается по IP
60 запросов в минуту привязаны к IP-адресу, **не** к API-ключу. Следствия:
- Несколько сервисов за одним NAT или на одном сервере делят общий лимит.
- Создание дополнительных ключей не увеличивает пропускную способность.
- Ограничение нельзя поднять на уровне аккаунта.
Исключение — `POST /v1/ai/embeddings`, он не лимитируется.
## Статистика только по аккаунту
Расходы агрегируются по пользователю; разбивки по отдельным ключам нет. Чтобы разделять
затраты по проектам, передавайте `session_id` или `metadata` в запросах и считайте на
своей стороне.
## Rerank не поддерживается
Эндпоинта переранжирования нет. В Continue и Roo Code не назначайте роль `rerank`.
---
Если какое-то из ограничений блокирует ваш сценарий — напишите на
[agent@agentapi.ru](mailto:agent@agentapi.ru).