Справочник по Jenova Agent API
Базовый URL: https://api.jenova.ai/v1
Аутентификация: Bearer token в заголовке Authorization
Содержание
- Обзор
- Быстрый старт
- Основные понятия
- Аутентификация
- Конечные точки API
- Потоковая передача (SSE)
- Интеграция MCP-сервера
- Биллинг
- Ограничения скорости
- Обработка ошибок
- Пагинация
- Локализация
- Конфиденциальность и данные
- Поддержка
Обзор
Создавайте и запускайте готовые к продакшену AI-агенты без необходимости самостоятельно собирать базовый стек. Jenova Agent API объединяет все основные возможности в едином управляемом сервисе:
Полноценный стек агента
- Оркестрация агента: единый уровень оркестрации координирует модели, инструменты, память и извлечение данных в рамках сложных рабочих процессов.
- Память и контекст: неограниченная память диалога и контекст встроены в каждую сессию. Внешнее управление состоянием не требуется.
- Инструменты и MCP: неограниченное количество интеграций инструментов с платформенными инструментами и любым удалённым MCP-сервером — готово из коробки.
- Используйте любую модель: обеспечивайте работу ваших агентов моделями от OpenAI, Anthropic, Google, xAI, Qwen и других через единую интеграцию.
- Полностью управляемое хранилище: управляемые реляционные и векторные базы данных со встроенным RAG. Никакой инфраструктуры разворачивать или масштабировать не нужно.
- Промышленный уровень: используется сотнями тысяч пользователей. Полностью управляемая инфраструктура, стабильные API, созданные для продакшен-трафика.
Быстрый старт
1. Получите ваш API-ключ
Сгенерируйте API-ключ в панели управления разработчика на www.jenova.ai/platform. Ключи имеют формат jnv_sk_* и передаются как Bearer token.
2. Выберите или создайте агента
Выберите готового агента на платформе или создайте собственного агента в панели управления с инструкциями, настройками модели, файлами базы знаний, инструментами и MCP-серверами.
3. Отправьте ваше первое сообщение
Создайте сессию и отправьте сообщение за один вызов:
curl -N -X POST https://api.jenova.ai/v1/messages \
-H "Authorization: Bearer jnv_sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"agent": "my-support-agent",
"user": "user_12345",
"content": "What can you help me with?"
}'
Ответ передаётся потоком в виде Server-Sent Events:
event: stream_started
data: {"session_id":"ses_xyz789","run_id":"run_abc123","agent":"my-support-agent"}
event: stream_delta
data: {"session_id":"ses_xyz789","run_id":"run_abc123","chunk_content":"I can help you with ","seq":1}
event: stream_ended
data: {"session_id":"ses_xyz789","run_id":"run_abc123","success":true,"stop_reason":"end_run","usage":{"cost":"0.0032"}}
Сохраните session_id из stream_started для последующих запросов. Синхронные JSON-ответы описаны в разделе Отправить сообщение.
Основные понятия
Агент
AI-агент, с которым вы взаимодействуете через API. У каждого агента есть уникальный slug (например, my-support-agent), используемый как значение agent в вызовах API.
- Готовые агенты: выбирайте из существующих агентов на платформе.
- Собственные агенты: настраивайте собственного агента в панели управления с инструкциями, моделью, базой знаний, инструментами и MCP-серверами.
Сессия
Независимый поток диалога между конечным пользователем и агентом.
- Идентификатор: ID с префиксом (например,
ses_abc123) - Область действия: для одного и того же агента и конечного пользователя может существовать несколько сессий, каждая с независимым состоянием диалога
- Жизненный цикл: сессии сохраняются неограниченно долго, пока не будут удалены через API. Для одноразовых задач без сохранения данных используйте
POST /messagesсephemeral: true - Изоляция платформы: сессии API отделены от диалогов в веб-приложении Jenova. Конечные пользователи, история сессий и биллинг независимы между API и веб-приложением.
Сообщение
Отдельная запись в истории диалога сессии, возвращаемая конечными точками Сообщений. Каждое сообщение включает структурированный объект from с полями type ("user" или "agent") и name, а также type самого сообщения:
external— сообщение диалога, предназначенное для отображения в качестве содержимого чата.internal— необязательное сообщение, представляющее рабочие шаги агента во время запуска, такие как вызовы инструментов или извлечение данных.
Запуск
Отдельное выполнение агента, создаваемое при отправке сообщения. У запуска есть run_id, он может передавать события потоком, пока активен, и производит одно или несколько завершённых сообщений. У каждой сессии в любой момент времени может быть только один активный запуск.
Конечный пользователь
Поле user привязывает сессии к конечному пользователю в вашем приложении. Используйте стабильный непрозрачный идентификатор, например ваш внутренний ID пользователя или UUID. Избегайте использования email-адресов и другой личной информации, если это не требуется вашим приложением. Сессии, созданные с одинаковым значением user, группируются вместе, что позволяет получать списки сессий по конкретному пользователю.
Если user не указан, сессия привязывается к вашей учётной записи разработчика и позже не может быть отфильтрована по конечному пользователю. В продакшене передавайте user.
Для запросов к существующей сессии user является необязательным механизмом проверки владения. Если вы его укажете, значение должно совпадать со значением user, использованным при создании сессии; в противном случае API возвращает 404 session_not_owned. Передавайте его как параметр запроса в запросах GET и DELETE и в теле JSON в запросах POST и PATCH.
Аутентификация
Аутентифицируйте каждый запрос с помощью Bearer token в заголовке Authorization:
Authorization: Bearer jnv_sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
API-ключи создаются в панели управления разработчика.
User-Agent необязателен. SDK могут задавать его для диагностики, но API этого не требует.
Формат ключа: ключи начинаются с префикса jnv_sk_, за которым следует случайная строка в кодировке base62.
Лимиты: каждая учётная запись разработчика может иметь до 10 активных API-ключей.
Конечные точки API
Сообщения
Отправка сообщений — основной путь API. Используйте POST /messages для первого сообщения; он создаёт сессию и запускает запуск в рамках одного запроса. Используйте POST /sessions/{session_id}/messages при продолжении сохранённого session_id.
Отправить сообщение
POST /messages
Создаёт постоянную сессию и отправляет первое сообщение в рамках одного атомарного запроса. Установите ephemeral: true для одноразового потокового запроса без сохранения данных, который не хранит историю сессии или сообщений, не возвращает ID сессии и не может быть продолжен.
Тело запроса
| Поле | Тип | Обязательный | По умолчанию | Описание |
|---|---|---|---|---|
agent | string | Да | - | Слаг-идентификатор агента |
content | string | Условно | - | Текст сообщения. Обязателен, если не указан file_urls |
file_urls | string[] | Условно | - | URL прикладываемых файлов. Обязателен, если не указан content |
user | string | Нет | - | Идентификатор вашего внешнего конечного пользователя (максимум 255 символов). Если не указан, используется по умолчанию ваша учётная запись разработчика |
session_name | string | Нет | - | Отображаемое имя новой сессии (максимум 200 символов) |
ephemeral | boolean | Нет | false | Одноразовый запрос без сохранения данных, только потоковая передача. Не хранит историю сессии или сообщений, не возвращает ID сессии и не может быть продолжен |
stream | boolean | Нет | true | true для потоковой передачи SSE, false для JSON. Авторизация MCP требует потоковой передачи |
model | string | Нет | - | Разовое переопределение модели только для этого запроса. Используйте стабильный ID модели, например claude-sonnet-5. Не изменяет модель по умолчанию для сессии |
Пример — потоковая передача (по умолчанию)
curl -N -X POST https://api.jenova.ai/v1/messages \
-H "Authorization: Bearer jnv_sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"agent": "my-support-agent",
"user": "user_12345",
"content": "Hello, I need help with my account"
}'
Ответ представляет собой SSE-поток (формат событий см. в разделе Потоковая передача (SSE)). Постоянные запросы включают новый session_id; запросы с ephemeral: true не содержат session_id и должны использовать потоковую передачу.
Пример — JSON (без потоковой передачи)
curl -X POST https://api.jenova.ai/v1/messages \
-H "Authorization: Bearer jnv_sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"agent": "my-support-agent",
"user": "user_12345",
"content": "Hello, I need help with my account",
"stream": false
}'
Ответ
Потоковые ответы передают события SSE, описанные в разделе Потоковая передача (SSE). Ответы без потоковой передачи возвращают JSON-структуру сообщения, показанную в разделе Продолжить сессию, включая stop_reason и usage для завершённого запроса.
Если запуск без потоковой передачи всё ещё обрабатывается спустя 90 секунд, API возвращает 202 Accepted со значением status: "processing", а также session_id, run_id и message. Запуск продолжается после завершения ответа или отключения клиента; проверяйте сообщения сессии либо используйте потоковую передачу для более длительных рабочих процессов.
Ошибки
| Статус | Код | Условие |
|---|---|---|
| 400 | missing_required_field | Требуется поле agent |
| 400 | invalid_payload | Некорректный JSON или поле имеет недопустимый тип |
| 400 | bad_request | Недопустимый режим ephemeral, либо user/session_name превышает максимальную длину |
| 400 | content_or_uploaded_files_required | Не указаны ни content, ни file_urls |
| 400 | content_too_long | Содержимое сообщения превышает максимальную длину в токенах |
| 400 | exceed_max_upload_files | В одном запросе указано более 10 URL файлов |
| 400 | unsupported_file_format | URL файла имеет неподдерживаемое расширение |
| 400 | invalid_file_url | URL файла некорректен или не использует HTTPS |
| 400 | invalid_model_selection | Переопределённая модель не является допустимой production-моделью |
| 402 | insufficient_credits | Недостаточно кредитов для создания сессии или отправки сообщения |
| 404 | agent_not_found | Агент не существует или недоступен для вашей учётной записи |
Продолжить сессию
POST /sessions/{session_id}/messages
Отправляет сообщение в существующую постоянную сессию и получает ответ агента. По умолчанию ответы передаются потоково через SSE; установите stream: false для JSON.
Тело запроса
| Поле | Тип | Обязательный | По умолчанию | Описание |
|---|---|---|---|---|
content | string | Условно | - | Текст сообщения. Обязателен, если не указан file_urls |
file_urls | string[] | Условно | - | URL-адреса вложенных файлов. Обязателен, если не указан content |
stream | boolean | Нет | true | true для потоковой передачи через SSE, false для JSON. Авторизация MCP требует потоковой передачи |
model | string | Нет | - | Разовая замена модели только для этого запроса. Используйте стабильный ID модели, например claude-sonnet-5. Не изменяет модель по умолчанию для сессии |
Пример — потоковая передача (по умолчанию)
curl -N -X POST https://api.jenova.ai/v1/sessions/ses_abc123/messages \
-H "Authorization: Bearer jnv_sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"content": "How do I reset my password?"
}'
Пример — JSON (без потоковой передачи)
curl -X POST https://api.jenova.ai/v1/sessions/ses_abc123/messages \
-H "Authorization: Bearer jnv_sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"content": "How do I reset my password?",
"stream": false
}'
Ответ 200 OK
{
"id": "msg_xyz789",
"session_id": "ses_abc123",
"sequence": 4,
"from": {
"type": "agent",
"name": "my-support-agent"
},
"type": "external",
"time": "2026-05-19T10:31:05Z",
"content": "To reset your password, go to Settings > Security > Change Password...",
"model": "claude-sonnet-5",
"files": [],
"stop_reason": "end_run",
"usage": {
"cost": "0.0015"
}
}
Если в сессии уже есть активный запуск или сообщения в очереди, API возвращает JSON 202 Accepted со значениями status: "queued", session_id, run_id и message_id. Сообщение пользователя обрабатывается активным запуском.
Ошибки
| Статус | Код | Условие |
|---|---|---|
| 400 | invalid_payload | Некорректный JSON или поле имеет неверный тип |
| 400 | content_or_uploaded_files_required | Не указаны ни content, ни file_urls |
| 400 | content_too_long | Содержимое сообщения превышает максимальную длину в токенах |
| 400 | exceed_max_upload_files | Более 10 URL-адресов файлов в одном запросе |
| 400 | unsupported_file_format | URL-адрес файла имеет неподдерживаемое расширение |
| 400 | invalid_file_url | URL-адрес файла имеет неверный формат или не использует HTTPS |
| 400 | invalid_model_selection | Указанная замена модели не является допустимой рабочей моделью |
| 402 | insufficient_credits | Недостаточно кредитов для отправки сообщения |
| 404 | session_not_found | Сессия не существует |
| 404 | session_not_owned | Сессия принадлежит другому разработчику или не соответствует указанному user |
Идемпотентность
POST /messages и POST /sessions/{session_id}/messages принимают необязательный заголовок Idempotency-Key. Используйте уникальный ключ для каждой логической отправки от пользователя, чтобы повторные попытки сети или повторные отправки не создавали дублирующиеся запуски.
curl -N -X POST https://api.jenova.ai/v1/messages \
-H "Authorization: Bearer jnv_sk_xxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: send-user_12345-2026-05-19T10:30:00Z" \
-d '{
"agent": "my-support-agent",
"user": "user_12345",
"content": "Hello"
}'
Без потоковой передачи: повторная попытка возвращает сохранённый ответ 200 или 202 с заголовком Idempotent-Replayed: true.
Потоковая передача: поток не воспроизводится повторно. Повторная попытка во время выполнения или после завершения возвращает ошибку идемпотентности с исходным run_id и, для персистентных запросов, session_id. Используйте GET /sessions/{session_id}/runs/{run_id} для проверки активного запуска или GET /sessions/{session_id}/messages для получения сохранённых результатов.
Пример повторной попытки после завершённой потоковой передачи:
HTTP/1.1 409 Conflict
Content-Type: application/json
{
"error": {
"code": "idempotency_key_reused",
"message": "This Idempotency-Key has already completed. Streaming responses cannot be replayed; use the returned session_id and run_id to retrieve the result."
},
"idempotency": {
"status": "completed",
"session_id": "ses_abc123",
"run_id": "run_abc123"
}
}
Ошибки идемпотентности
| Статус | Код | Условие |
|---|---|---|
| 409 | idempotency_key_reused | Тот же ключ был использован с другим запросом |
| 409 | idempotency_key_in_use | Исходный запрос ещё выполняется |
| 409 | idempotency_key_reused | Исходный потоковый запрос уже завершён и не может быть воспроизведён повторно |
Список сообщений
GET /sessions/{session_id}/messages
Возвращает постраничный список видимых сообщений разговора. Первая страница содержит самые последние сообщения; в рамках каждой страницы сообщения расположены в хронологическом порядке (от старых к новым). sequence — это стабильный порядковый номер в рамках сессии.
Параметры запроса
| Параметр | Тип | По умолчанию | Максимум | Описание |
|---|---|---|---|---|
limit | integer | 20 | 100 | Количество сообщений на странице |
cursor | string | - | - | Курсор пагинации |
Пример
curl "https://api.jenova.ai/v1/sessions/ses_abc123/messages?limit=50" \
-H "Authorization: Bearer jnv_sk_xxx"
Ответ 200 OK
{
"items": [
{
"id": "msg_002",
"session_id": "ses_abc123",
"sequence": 4,
"from": {
"type": "agent",
"name": "my-support-agent"
},
"type": "external",
"time": "2026-05-19T10:31:05Z",
"content": "To reset your password, go to Settings > Security...",
"model": "claude-sonnet-5",
"files": []
}
],
"next_cursor": "",
"has_more": false
}
Объект сообщения
| Поле | Тип | Описание |
|---|---|---|
id | string | ID сообщения (с префиксом msg_) |
session_id | string | ID родительской сессии |
sequence | integer | Стабильный порядковый номер в рамках сессии |
from | object | Объект отправителя с полями type ("user" или "agent") и name |
type | string | Тип сообщения, обычно external для видимых сообщений разговора |
time | string | Временная метка в формате ISO 8601 |
content | string | Текстовое содержимое. Присутствует во внешних сообщениях |
model | string | Стабильный ID модели, сгенерировавшей ответ. Присутствует только в сообщениях агента |
files | array | Прикреплённые или сгенерированные файлы, включённые в сообщение. Каждая запись содержит file_id, name, url, format и size, если известно |
stop_reason | string | Присутствует в завершённых сообщениях агента. Текущее значение — end_run |
agent | string | Slug выполняющего агента, если доступен |
agent_name | string | Отображаемое имя выполняющего агента, если доступно |
Объект файла
| Поле | Тип | Описание |
|---|---|---|
file_id | string | ID файла Jenova, если доступен |
name | string | Имя файла |
url | string | URL файла, если доступен |
format | string | Формат файла в нижнем регистре, например pdf, png или csv |
size | integer | Размер файла в байтах, если известен |
Ошибки
| Статус | Код | Условие |
|---|---|---|
| 400 | bad_request | Недопустимый параметр запроса |
| 404 | session_not_found | Сессия не существует |
| 404 | session_not_owned | Сессия принадлежит другому разработчику или не соответствует переданному user |
Получить сообщение
GET /sessions/{session_id}/messages/{message_id}
Получает одно видимое сообщение по ID.
Ответ 200 OK
Возвращает объект одного сообщения с той же структурой, что и в ответе списка.
Ошибки
| Статус | Код | Условие |
|---|---|---|
| 404 | session_not_found | Сессия не существует |
| 404 | session_not_owned | Сессия принадлежит другому разработчику или не соответствует переданному user |
| 404 | not_found | Сообщение не существует в этой сессии |
Вложения файлов
Передайте общедоступные URL-адреса HTTPS в поле file_urls.
| Лимит | Значение |
|---|---|
| Максимум файлов на сообщение | 10 |
| Максимальный размер файла | 20 МБ на файл |
Поддерживаемые форматы
- Изображения: JPG, JPEG, PNG, WebP
- Документы: PDF, DOCX, XLSX, PPTX, TXT, CSV, RTF, MD, HTML, XML, JSON, LOG
- Код: JS, TS, TSX, JSX, PY, Java, Go, C, CPP, H, HPP, CS, RB, PHP, RS, Swift, KT, Scala, SQL, CSS, YAML, YML
При получении списка сообщений прикреплённые файлы отображаются в массиве files сообщения.
Сессии
Сессии — это постоянные разговоры между конечным пользователем и агентом. Большинство интеграций может создавать их неявно с помощью POST /messages.
Создать сессию
POST /sessions
Создаёт пустую постоянную сессию, привязанную к определённому агенту. Используйте этот метод, когда вам нужен ID сессии до отправки первого сообщения; в остальных случаях предпочтительнее использовать POST /messages.
Примечание: параметр
ephemeralне принимается вPOST /sessions; используйтеPOST /messagesсephemeral: trueдля одноразовых запросов без сохранения данных.
Тело запроса
| Поле | Тип | Обязательный | Описание |
|---|---|---|---|
agent | string | Да | Slug-идентификатор агента |
user | string | Нет | Идентификатор вашего внешнего конечного пользователя (максимум 255 символов). Если не указан, по умолчанию используется ваш аккаунт разработчика |
session_name | string | Нет | Отображаемое имя сессии (максимум 200 символов) |
Пример
curl -X POST https://api.jenova.ai/v1/sessions \
-H "Authorization: Bearer jnv_sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"agent": "my-support-agent",
"user": "user_12345",
"session_name": "Billing inquiry"
}'
Ответ 201 Created
{
"id": "ses_abc123",
"session_name": "Billing inquiry",
"agent": "my-support-agent",
"user": "user_12345",
"model": "claude-sonnet-5",
"created_at": "2026-05-19T10:30:00Z",
"updated_at": "2026-05-19T10:30:00Z"
}
Ошибки
| Статус | Код | Условие |
|---|---|---|
| 400 | invalid_payload | Некорректный JSON или поле имеет недопустимый тип |
| 400 | missing_required_field | Требуется поле agent |
| 400 | bad_request | Был передан параметр ephemeral, либо user/session_name превышает максимально допустимую длину |
| 402 | insufficient_credits | Недостаточно кредитов для создания сессии |
| 404 | agent_not_found | Агент не существует или недоступен для вашего аккаунта |
Список сессий
GET /sessions
Возвращает разбитый на страницы список ваших сессий, упорядоченный по времени последнего обновления.
Параметры запроса
| Параметр | Тип | Описание |
|---|---|---|
limit | integer | Количество элементов на странице (по умолчанию 20, максимум 100) |
cursor | string | Курсор пагинации |
user | string | Фильтр по идентификатору конечного пользователя (максимум 255 символов) |
agent | string | Фильтр по slug агента |
Пример
curl "https://api.jenova.ai/v1/sessions?user=user_12345&limit=10" \
-H "Authorization: Bearer jnv_sk_xxx"
Ответ 200 OK
{
"items": [
{
"id": "ses_abc123",
"session_name": "Billing inquiry",
"agent": "my-support-agent",
"user": "user_12345",
"model": "claude-sonnet-5",
"created_at": "2026-05-19T10:30:00Z",
"updated_at": "2026-05-19T11:15:00Z"
}
],
"next_cursor": "eyJ2IjoxLCJrIjoiY3VyXzAxIn0",
"has_more": true
}
Ошибки
| Статус | Код | Условие |
|---|---|---|
| 400 | bad_request | Недопустимый параметр запроса |
Получить сессию
GET /sessions/{session_id}
Возвращает одну сессию по ID.
Ответ 200 OK
Возвращает объект сессии с той же структурой, что и в ответе на создание.
Ошибки
| Статус | Код | Условие |
|---|---|---|
| 404 | session_not_found | Сессия не существует |
| 404 | session_not_owned | Сессия принадлежит другому разработчику или не соответствует переданному user |
Переименовать сессию
PATCH /sessions/{session_id}
Обновляет отображаемое имя сессии.
Тело запроса
| Поле | Тип | Обязательный | Описание |
|---|---|---|---|
session_name | string | Да | Новое отображаемое имя (максимум 200 символов) |
Ответ 200 OK
Возвращает обновлённый объект сессии.
Ошибки
| Статус | Код | Условие |
|---|---|---|
| 400 | invalid_payload | Некорректный JSON или поле имеет неверный тип |
| 400 | missing_required_field | Поле session_name обязательно |
| 400 | bad_request | Значение session_name превышает максимальную длину |
| 404 | session_not_found | Сессия не существует |
| 404 | session_not_owned | Сессия принадлежит другому разработчику или не соответствует указанному user |
Удалить сессию
DELETE /sessions/{session_id}
Безвозвратно удаляет сессию и все её сообщения. У сессии не должно быть активного запуска.
Ответ 204 No Content
Ошибки
| Статус | Код | Условие |
|---|---|---|
| 404 | session_not_found | Сессия не существует |
| 404 | session_not_owned | Сессия принадлежит другому разработчику или не соответствует указанному user |
| 409 | busy | У сессии есть активный запуск — сначала отмените его |
Операции
Эти конечные точки предназначены для восстановления и редактирования постоянных сессий. В большинстве интеграций требуется только отмена; остальные операции используются, когда вы намеренно хотите изменить или восстановить состояние сессии. Все операции поддерживают необязательную защиту владения через параметр user, описанную в разделе Конечный пользователь.
Отменить активный запуск
POST /sessions/{session_id}/cancel
Отменяет текущий выполняющийся запуск агента. Сообщения, уже завершённые до отмены, не удаляются.
Тело запроса
| Поле | Тип | Обязательный | Описание |
|---|---|---|---|
run_id | string | Нет | Необязательная защита от устаревшего запуска. Если указан и не совпадает с активным запуском, API возвращает 409 stale_run |
Ответ 204 No Content
Ошибки
| Статус | Код | Условие |
|---|---|---|
| 400 | cancel_not_allowed | Нет активного запуска для отмены, либо отмена не разрешена |
| 404 | session_not_found | Сессия не существует |
| 404 | session_not_owned | Сессия принадлежит другому разработчику или не соответствует указанному user |
| 409 | stale_run | Указанный run_id не совпадает с активным запуском |
Откатить активный запуск
POST /sessions/{session_id}/undo
Отменяет активный запуск, ожидает его остановки, а затем удаляет все сообщения, которые он уже добавил. После выдачи команды отката никакие дополнительные выходные данные не сохраняются.
Тело запроса
| Поле | Тип | Обязательный | Описание |
|---|---|---|---|
run_id | string | Нет | Необязательная защита от устаревшего запуска. Если указан и не совпадает с активным запуском, API возвращает 409 stale_run |
Ответ 200 OK
{
"session_id": "ses_abc123",
"run_id": "run_abc123",
"deleted": ["msg_002", "msg_001"]
}
Если запуск отменяется до завершения хотя бы одного сообщения, deleted будет пустым массивом.
Ошибки
| Статус | Код | Условие |
|---|---|---|
| 400 | cancel_not_allowed | Нет активного запуска для отмены (undo), либо отмена не разрешена |
| 404 | session_not_found | Сессия не существует |
| 404 | session_not_owned | Сессия принадлежит другому разработчику или не соответствует указанному user |
| 409 | stale_run | Указанный run_id не совпадает с активным запуском |
| 409 | busy | Сессия временно недоступна, поскольку выполняется другое обновление |
Удалить последние сообщения
POST /sessions/{session_id}/messages/delete
Удаляет N самых последних сообщений из неактивной сессии. Сессия не должна иметь активного запуска.
Тело запроса
| Поле | Тип | Обязательный | Описание |
|---|---|---|---|
count | integer | Да | Количество последних сообщений для удаления с конца (должно быть больше 0) |
Ответ 200 OK
{
"deleted": ["msg_002", "msg_001"]
}
Ошибки
| Статус | Код | Условие |
|---|---|---|
| 400 | bad_request | count отсутствует, равен нулю или отрицателен; либо нет сообщений для удаления |
| 404 | session_not_found | Сессия не существует |
| 404 | session_not_owned | Сессия принадлежит другому разработчику или не соответствует переданному user |
| 409 | busy | У сессии есть активный запуск |
Форк сессии
POST /sessions/{session_id}/fork
Создаёт новую сессию, копируя исходную сессию до определённого сообщения. У исходной сессии не должно быть активного запуска.
Тело запроса
| Поле | Тип | Обязательный | Описание |
|---|---|---|---|
message_id | string | Нет | ID сообщения, до которого выполняется форк. Если не указан, форк выполняется от последнего сообщения |
Ответ 201 Created
Возвращает объект новой созданной сессии с той же структурой, что и при создании сессии.
Ошибки
| Статус | Код | Условие |
|---|---|---|
| 400 | bad_request | message_id недействителен |
| 402 | insufficient_credits | Недостаточно кредитов для форка сессии |
| 404 | not_found | message_id не существует в этой сессии |
| 404 | session_not_found | Сессия не существует |
| 404 | session_not_owned | Сессия принадлежит другому разработчику или не соответствует переданному user |
| 409 | busy | У исходной сессии есть активный запуск |
Получить статус запуска
GET /sessions/{session_id}/runs/{run_id}
Возвращает текущее состояние активного запуска. Используйте этот метод после разрыва SSE-соединения или после ответа на идемпотентный запрос, который вернул run_id. После завершения запуска получите результаты с помощью GET /sessions/{session_id}/messages.
Ответ 200 OK
{
"session_id": "ses_abc123",
"run_id": "run_abc123",
"status": "streaming",
"started_at": "2026-05-19T10:30:00Z",
"updated_at": "2026-05-19T10:30:06Z",
"content": "Partial visible response text so far"
}
Ответ также может включать подсказки о ходе выполнения, пока запуск активен.
Ошибки
| Статус | Код | Условие |
|---|---|---|
| 400 | bad_request | Сессия является эфемерной |
| 404 | session_not_found | Сессия не существует |
| 404 | session_not_owned | Сессия принадлежит другому разработчику или не соответствует переданному user |
| 404 | not_found | Запуск не активен для этой сессии |
Кредиты
Получить баланс
GET /credits/balance
Возвращает ваш текущий баланс кредитов.
Ответ 200 OK
{
"balance": "123.45"
}
Агенты
Создавайте и редактируйте пользовательские агенты в панели управления. Поддержка создания и редактирования агентов через API появится в ближайшее время.
Запланированные/фоновые рабочие процессы в настоящее время не поддерживаются через API. Поддержка появится в ближайшее время.
Список агентов
GET /agents
Возвращает агентов, доступных для вашего API-ключа. Используйте значение agent при создании сессий или отправке сообщений.
Ответ 200 OK
{
"agents": [
{
"agent": "jenova",
"display_name": "Jenova",
"description": "General-purpose Jenova agent"
},
{
"agent": "my-support-agent",
"display_name": "Support Agent",
"description": "Answers customer questions"
}
]
}
| Поле | Тип | Описание |
|---|---|---|
agent | string | Стабильный слаг агента, передаваемый как значение agent |
display_name | string | Отображаемое имя, понятное человеку |
description | string | Описание агента |
Модели
Список моделей
GET /models
Возвращает все модели, доступные для использования в поле model при отправке сообщений.
Ответ 200 OK
{
"models": [
{
"id": "claude-opus-4-8",
"name": "Claude Opus 4.8",
"thinking_variant": "claude-opus-4-8-thinking"
},
{
"id": "claude-opus-4-8-thinking",
"name": "Claude Opus 4.8 (Thinking)"
},
{
"id": "kimi-k2.6",
"name": "Kimi K2.6",
"thinking_variant": "kimi-k2.6-thinking"
}
]
}
| Поле | Тип | Описание |
|---|---|---|
id | string | Стабильный идентификатор модели. Передавайте его как значение model при отправке сообщения |
name | string | Отображаемое имя, понятное человеку |
thinking_variant | string | Идентификатор модели варианта с рассуждениями (thinking/reasoning). Присутствует только у базовых моделей, поддерживающих рассуждения |
Модели с thinking_variant поддерживают расширенные рассуждения. Чтобы включить их, используйте идентификатор варианта непосредственно в поле model.
Если при отправке сообщения model не указана, используется модель агента по умолчанию.
Документация
GET /docs?lang=en
GET /doc?lang=en
Возвращает этот справочник в формате Markdown. Используйте lang, чтобы выбрать язык.
Потоковая передача (SSE)
Если stream не указан или равен true (значение по умолчанию), ответы на сообщения доставляются в виде Server-Sent Events. Используйте события message_completed, чтобы определить, какие сообщения готовы к получению или отображению.
Тайм-аут: соединения SSE остаются открытыми до 60 минут. Запросы без потоковой передачи ожидают до 90 секунд, после чего возвращают 202 Accepted, пока запуск продолжается.
Заголовки подключения
Ответ SSE устанавливает следующие заголовки:
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
X-Accel-Buffering: no
X-Run-Id: run_abc123
X-Run-Id доступен до первого события SSE.
Переподключение и восстановление
Потоки SSE не воспроизводятся повторно. Если соединение прерывается, используйте сохранённые session_id и run_id, чтобы восстановить состояние:
curl "https://api.jenova.ai/v1/sessions/ses_abc123/runs/run_abc123" \
-H "Authorization: Bearer jnv_sk_xxx"
Если запуск ещё активен, этот запрос возвращает текущий статус, частичный текст и последние данные о ходе выполнения. Если возвращается 404 not_found, запуск больше не активен; получите сообщения сессии, чтобы сверить завершённый результат:
curl "https://api.jenova.ai/v1/sessions/ses_abc123/messages?limit=20" \
-H "Authorization: Bearer jnv_sk_xxx"
Формат кадра
Каждый SSE-кадр следует стандартному формату:
event: <event_type>
data: <json_payload>
Каждый кадр завершается двумя символами новой строки.
Типы событий
Потоки включают события жизненного цикла, текстовые дельты, рассуждения, прогресс, предупреждения, завершение сообщения, подключение MCP, ошибки, финальные события и ping. Некоторые типы событий отправляются только когда они релевантны.
Для эфемерных запросов (ephemeral: true) в каждом SSE-событии отсутствует session_id. Используйте только run_id для сопоставления событий внутри этого одного потока.
Для окончательной сверки при постоянных запросах дождитесь события stream_ended, а затем вызовите List Messages.
Общие поля событий, привязанных к запуску:
| Поле | Описание |
|---|---|
session_id | ID сессии. Отсутствует для эфемерных потоков. Получите это значение из stream_started для последующих запросов при использовании постоянного POST /messages |
run_id | ID текущего запуска, если доступен |
stream_started
Отправляется один раз при начале запуска.
| Поле | Описание |
|---|---|
agent | Slug агента сессии, если доступен |
stream_delta
Отправляется многократно по мере генерации агентом видимого текста ответа. Объедините значения chunk_content в порядке seq, чтобы получить потоковый ответ.
event: stream_delta
data: {"session_id":"ses_abc123","run_id":"run_abc123","chunk_content":"To reset your ","seq":1}
| Поле | Описание |
|---|---|
chunk_content | Фрагмент текста |
seq | Монотонный порядковый номер фрагмента в потоке |
stream_thinking
Отправляется многократно, пока агент выдаёт результат размышлений. Используйте это для отдельного индикатора размышлений или представления трассировки; не объединяйте это с финальным текстом ответа.
| Поле | Описание |
|---|---|
content | Фрагмент текста размышлений |
stream_progress
Сообщает о видимой пользователю активности во время генерации, например о чтении документа, поиске в интернете или ожидании действия пользователя. Эти события предназначены для временного отображения в интерфейсе; игнорируйте неизвестные поля. Используйте завершенные сообщения как авторитетную историю сообщений.
Дополнительно: запросы сообщений принимают include_progress: false, чтобы опустить только stream_progress. События жизненного цикла, ping, message_completed, ошибки и финальные события всё равно отправляются, когда это уместно.
| Поле | Описание |
|---|---|
state | Состояние жизненного цикла: running, in-progress, success, failed, skipped, complete, cancelled и другие. Обрабатывайте неизвестные значения корректно |
label | Человекочитаемая метка активности |
Некоторые события прогресса могут включать url, file_name или server_name как необязательные подсказки для отображения.
message_completed
Отправляется каждый раз, когда сообщение завершено и готово для получения или отображения.
Это маркер границы, а не полный объект сообщения. Получите сообщение, если вам нужны содержимое или метаданные.
event: message_completed
data: {"session_id":"ses_abc123","run_id":"run_abc123","message_id":"msg_abc123","sequence":4,"from":{"type":"agent","name":"Jenova"},"type":"external"}
| Поле | Описание |
|---|---|
message_id | ID завершённого сообщения |
sequence | Стабильный порядковый номер внутри сессии |
from | Объект отправителя с полями type (user или agent) и name |
type | Тип сообщения: external или internal |
mcp_connection
Отправляется, когда агенту нужно, чтобы конечный пользователь подключил или авторизовал один или несколько MCP-серверов, прежде чем агент сможет продолжить. Это событие доступно только в режиме streaming.
| Поле | Описание |
|---|---|
connection_server_list | MCP-серверы, которым требуется действие подключения. Каждый сервер содержит mcp_server_id, mcp_server_name и необязательный auth_url |
user_action_deadline_unix | Unix-время, когда истекает действие пользователя для подключения |
mcp_connection_resolved
Отправляется, когда действие пользователя для подключения MCP было выполнено или истекло.
Дополнительных полей, помимо общих полей, привязанных к запуску, нет.
warning
Отправляется для некритичных предупреждений во время запуска.
| Поле | Описание |
|---|---|
message | Человекочитаемое некритичное предупреждение |
code | Необязательный код предупреждения |
stream_error
Отправляется при сбое запуска. За этим может следовать финальное событие stream_ended со значениями success:false и stop_reason:"error".
| Поле | Описание |
|---|---|
code | Код ошибки |
message | Человекочитаемое сообщение об ошибке |
stream_ended
Отправляется один раз при завершении запуска. Это последнее событие в потоке.
event: stream_ended
data: {"session_id":"ses_abc123","run_id":"run_abc123","success":true,"stop_reason":"end_run","usage":{"cost":"0.0032"}}
Пример неудачного завершения:
event: stream_ended
data: {"session_id":"ses_abc123","run_id":"run_abc123","success":false,"stop_reason":"user_cancelled","usage":{"cost":"0.0012"}}
| Поле | Описание |
|---|---|
success | Успешно ли завершился запуск |
stop_reason | Причина завершения запуска: end_run, user_cancelled, user_action_timeout или error |
usage | Объект использования для данного запроса. В настоящее время включает cost, если доступно |
ping
Кадры поддержания активности, отправляемые каждые 15 секунд для предотвращения тайм-аутов на прокси/CDN. Игнорируйте их на стороне клиента.
Интеграция MCP-сервера
Подключайте ваших агентов к внешним инструментам через Model Context Protocol (MCP):
- MCP-серверы, управляемые Jenova: серверы, размещённые Jenova, для поиска, получения контента, генерации документов и других встроенных возможностей
- Удалённые MCP-серверы: другие удалённые MCP-серверы, настроенные для вашего агента
MCP-серверы должны быть настроены в панели управления при создании или редактировании агента. Чтобы использовать собственный MCP-сервер, добавьте его в кастомного агента, а затем вызывайте этого агента через API. API выполняет инструменты, включённые в конфигурации агента; дополнительная настройка в запросах API не требуется.
Когда агент использует инструменты MCP во время формирования ответа, в поток отправляются события о ходе выполнения по мере их возникновения:
event: stream_progress
data: {"session_id":"ses_...","run_id":"run_...","state":"running","label":"Searching Google"}
Если агенту во время запуска нужно, чтобы конечный пользователь подключился к MCP-серверу или авторизовал его, streaming-ответы могут включать события mcp_connection и mcp_connection_resolved. Покажите конечному пользователю список серверов для подключения и откройте предоставленный auth_url, если он есть. Держите SSE-поток открытым, пока пользователь подключает или авторизует сервер.
После авторизации Jenova сохраняет token, окно авторизации показывает страницу завершения, и тот же запуск автоматически продолжается. Конечному пользователю не нужно повторно отправлять сообщение.
Если конечный пользователь не подключится, не авторизует, не пропустит или не отключит напоминания до user_action_deadline_unix, запуск завершится с stop_reason:"user_action_timeout". Вы также можете отменить активный запуск с помощью POST /sessions/{session_id}/cancel.
Сохраните auth_url на стороне клиента. Если клиент отключится во время авторизации, URL останется действительным до user_action_deadline_unix. Для постоянных запросов повторно подключитесь через Get Run Status или получите сообщения после завершения запуска.
Нестриминговые запросы (stream: false) не поддерживают пользовательские действия подключения MCP; используйте streaming для агентов, которым может понадобиться это взаимодействие.
Пропустить подключение MCP
POST /sessions/{session_id}/mcp/connection/skip
Отклоняет ожидающее действие пользователя для подключения MCP и позволяет запуску продолжиться без этого подключения.
Чтобы отключить будущие запросы подключения для одного сервера для того же пользователя API, укажите mcp_server_id и mute. Поддерживаемые значения: 24h и forever.
Тело запроса
| Поле | Тип | Обязательный | Описание |
|---|---|---|---|
run_id | string | Да | ID активного запуска из события mcp_connection |
mcp_server_id | string | Нет | Требуется вместе с mute; используйте mcp_server_id из события |
mute | string | Нет | 24h или forever |
Ответ 204 No Content
Поток отправляет mcp_connection_resolved, после чего запуск продолжается с тем же run_id.
Ошибки
| Статус | Код | Условие |
|---|---|---|
| 400 | bad_request | Отсутствует run_id, нет активного запуска или нет подключения MCP для пропуска |
| 400 | bad_request | Недопустимое значение mute или отсутствует mcp_server_id, когда задан mute |
| 404 | session_not_found | Сессия не существует |
| 404 | session_not_owned | Не соответствует переданному user |
| 409 | stale_run | run_id не соответствует активному запуску |
Биллинг
Все расходы списываются с баланса кредитов разработчика. Просматривайте использование и пополняйте кредиты на www.jenova.ai/platform.
Тарифы
| Операция | Стоимость |
|---|---|
| Create Session | Фиксированная $0.01 за каждую персистентную сессию, включая сессии, создаваемые неявно через POST /messages |
| Fork Session | Фиксированная $0.05 |
| Send Message | Переменная (см. ниже) |
Стоимость сообщения зависит от:
- Модель — разные модели имеют разную стоимость за токен
- Длина контекста — более длинные сессии потребляют больше входных токенов на запрос
- Сложность рабочего процесса — более длинные рабочие процессы и более интенсивное использование инструментов (веб-поиск, генерация файлов, анализ документов) увеличивают общее потребление токенов
Фактическая стоимость возвращается как stream_ended.usage.cost для потоковых запросов и usage.cost для непотоковых JSON-запросов.
Удержания кредитов
Каждый новый запуск сообщения устанавливает удержание $0.50 на балансе кредитов перед началом выполнения. Это резервирует средства для запуска. Сообщения-продолжения, поставленные в очередь в рамках активного запуска, не создают дополнительных удержаний; использование активного запуска проверяется относительно вашего оставшегося баланса.
При завершении запуска удержание пересчитывается по фактической стоимости, а разница освобождается. За отменённые и неудавшиеся запуски взимается плата только за фактически понесённое использование. Если запрос завершается ошибкой до достижения модели, удержание освобождается полностью.
Это означает, что доступный баланс может временно выглядеть ниже во время выполнения запросов. Вам нужно как минимум $0.50 доступного баланса, чтобы отправить сообщение в существующую сессию или отправить эфемерное сообщение. Первый персистентный запрос POST /messages создаёт сессию и требует как минимум $0.51 для покрытия удержания за сообщение плюс платы за создание сессии.
Ограничения скорости
На каждую учётную запись разработчика распространяются три измерения ограничения скорости:
| Измерение | Значение по умолчанию | Описание |
|---|---|---|
| RPM (запросов в минуту) | 60 | Фиксированное окно в минуту |
| RPD (запросов в день) | 1,000 | Фиксированное окно в день |
| Concurrent (одновременные запросы) | 5 | Максимальное количество одновременно выполняемых запросов |
Запросы GET и HEAD не занимают слоты параллельных запросов. cancel, undo и mcp/connection/skip также не занимают слоты параллельных запросов, поэтому эти операции остаются доступными, когда все слоты заняты. Эти запросы по-прежнему учитываются в RPM и RPD.
Заголовки ответа
Аутентифицированные ответы API включают заголовки ограничения скорости:
| Заголовок | Описание |
|---|---|
X-RateLimit-Limit | Ваш лимит RPM |
X-RateLimit-Remaining | Количество оставшихся запросов в текущем минутном окне |
X-RateLimit-Reset | Unix-время сброса текущего окна |
Retry-After | Количество секунд до повторной попытки (только при 429) |
При превышении лимита API возвращает 429 Too Many Requests:
{
"error": {
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded. Please retry after 12 seconds."
}
}
Обработка ошибок
Немедленные ошибки HTTP и ошибки запусков без потоковой передачи следуют единому формату:
{
"error": {
"code": "error_code_string",
"message": "Human-readable description"
}
}
Сообщения об ошибках локализуются в зависимости от параметра lang (см. Локализация).
Ошибки потоковых запусков передаются в виде событий stream_error. Неудачный запуск может также отправить финальное событие stream_ended со значением success:false и установленным stop_reason. Ошибки запусков без потоковой передачи также могут включать объект usage верхнего уровня, если данные о стоимости доступны.
Ошибки, специфичные для конкретных конечных точек, документируются непосредственно в описании каждой конечной точки.
Ошибки запуска после старта
Ошибки запуска возникают после того, как запуск сообщения уже начался. В режиме потоковой передачи они отображаются как события stream_error и могут сопровождаться событием stream_ended со значением success:false. В режиме без потоковой передачи они возвращаются как JSON-ответ с ошибкой и указанным ниже статусом HTTP.
| Код состояния HTTP без потоковой передачи | Код | Описание |
|---|---|---|
| 400 | content_policy_violation | Провайдер модели отклонил запрос по причинам, связанным с политикой контента |
| 404 | session_not_found | Сессия была удалена до того, как запуск успел выполниться |
| 409 | busy | Сессия стала занятой или временно недоступной до начала запуска |
| 413 | total_image_size_exceeded | Совокупный объём изображений превышает лимит размера на один запрос для данной модели |
| 500 | internal_error | Непредвиденный сбой запуска |
| 502 | llm_api_error | Ошибка API провайдера модели или вышестоящей модели |
Пагинация
Конечные точки со списками используют пагинацию на основе курсора:
{
"items": [],
"next_cursor": "eyJ2IjoxLCJrIjoiY3VyXzAyIn0",
"has_more": true
}
| Параметр | Тип | По умолчанию | Максимум | Описание |
|---|---|---|---|---|
limit | integer | 20 | 100 | Количество элементов на странице |
cursor | string | - | - | Непрозрачный курсор из предыдущего значения next_cursor |
Передайте next_cursor в качестве параметра запроса cursor, чтобы получить следующую страницу. Если has_more равно false, дальнейших результатов нет.
Локализация
Все конечные точки принимают необязательный параметр запроса lang для управления языком сообщений об ошибках и любого локализованного контента.
| Источник | Приоритет | Пример |
|---|---|---|
Параметр запроса lang | Наивысший | ?lang=zh |
Заголовок Accept-Language | Резервный вариант | Accept-Language: ja |
| По умолчанию | Наименьший | Английский (en) |
Вы можете добавить ?lang=xx к URL любого запроса:
POST /sessions?lang=zh
GET /sessions/ses_abc123/messages?lang=ja
Поддерживаемые языки: en, zh, ja, ko, es, fr, de, it, pt, ru, id, th, vi
Конфиденциальность и данные
Jenova не использует запросы API, результаты, историю переписки, загруженные файлы, инструкции агентов или базы знаний для обучения моделей Jenova.
Для сторонних провайдеров моделей Jenova использует коммерческие каналы API, настройки учётных записей, договорные обязательства или механизмы отказа, предназначенные для предотвращения использования контента клиентов при обучении моделей провайдеров.
Jenova хранит и обрабатывает данные API с использованием инфраструктуры США. Сторонние провайдеры могут обрабатывать данные в других юрисдикциях, как описано в Политике конфиденциальности и Условиях использования.
Полную информацию см. в Условиях использования, Политике конфиденциальности и Политике использования.
Поддержка
- Панель управления: www.jenova.ai/platform
- Email: [email protected]