Octo API · HTTP /v1 · для инженеров

Octo API
в вашем приложении

HTTP-контракт для backend: ходы, пространства, MCP, память, маршрутизация и биллинг. Справочник: dash.octomatica.ru/v1/docs.

Схема одного хода

вызов ответ. Метод и поле в подписи взяты из справочника /v1; подписи без них описывают роль шага.

Один ход Octo API: клиент, приложение, Octo, провайдеры инференса, внешние API1. Действие клиента в интерфейсе приложения: ваш собственный API: сообщение, кнопка, загрузка файла. 2. Backend вызывает Octo API: POST /v1/turns · Authorization: Bearer · {space, text, end_user_ref, file_ids}. 3.1. Инференс у провайдера: модель по политике пространства; недоступна: следующий кандидат. 3.2. Внешние API и инструменты: allow: web, research, code, … · сторонние mcp_servers[]. 3.3. Внутренние API приложения через ваш MCP: mcp_servers[]: {name, url, headers} · вызов с вашей схемой ввода. 3.4. Файлы и память пространства: чтение и запись; созданные файлы попадут в files[]. 4. Результат возвращается в приложение: вебхук turn.completed, X-OOIH-Signature · или GET /v1/turns/{turn_id}. 5. Приложение обновляет UI и контент: из result, files[] и данных, изменённых на шаге 3.3. 6. Клиент видит результат: новое состояние экрана, а не только текст ответа.3 · ЦИКЛ АГЕНТА: ПОВТОРЯЕТСЯ, ПОКА ЗАДАЧА НЕ РЕШЕНААгент действует во внешних и во внутренних API и меняет данные, из которых ваше приложение строит интерфейс.Итог хода: изменённое состояние приложения, файлы и текст ответа.A · КЛИЕНТКлиентбраузер, мобильноеприложение, ботB · ВАША ПЛАТФОРМАПриложениеbackend и UI,внутренние APIи данныеC · OCTOOctoAPI, агент, память,файлы, политики,маршрутизация, биллингD · ИНФЕРЕНСПровайдерымодели, выбранныеполитикой OctoE · ВНЕШНИЕAPI и MCPсервисы, поиск,сторонние MCP-серверы1Действие клиента в интерфейсе приложенияваш собственный API: сообщение, кнопка, загрузка файла2Backend вызывает Octo APIPOST /v1/turns · Authorization: Bearer · {space, text, end_user_ref, file_ids}202 {turn_id, state: "queued"}3.1Инференс у провайдерамодель по политике пространства; недоступна: следующий кандидатответ модели: текст или вызов инструмента3.2Внешние API и инструментыallow: web, research, code, … · сторонние mcp_servers[]данные для следующего шага3.3Внутренние API приложения через ваш MCPmcp_servers[]: {name, url, headers} · вызов с вашей схемой вводарезультат или ошибка валидации: агент исправляет аргументы3.4Файлы и память пространствачтение и запись; созданные файлы попадут в files[]4Результат возвращается в приложениевебхук turn.completed, X-OOIH-Signature · или GET /v1/turns/{turn_id}5Приложение обновляет UI и контентиз result, files[] и данных, изменённых на шаге 3.36Клиент видит результатновое состояние экрана, а не только текст ответа

Агент как сервис или API модели

Что остаётся на вашей стороне в каждом варианте.

ЗадачаAPI моделиOcto API
Единица вызоваЗапрос completion, синхронный ответ или поток токеновХод в пространстве: 202 и turn_id, выполнение асинхронно
Цикл инструментовВаш код: разбор вызовов инструментов, выполнение, повторный запросЦикл ведёт агент; вы публикуете операции через MCP
СостояниеИстория передаётся в каждом запросе, обрезка и суммаризация на васСессия и память живут в пространстве
Модель и провайдерЗашиты в код; отказ провайдера обрабатываете выПолитика пространства с резервными кандидатами
Структурированный выводJSON mode и валидация текста ответаВызов вашего инструмента с вашей схемой ввода
ФайлыКодирование во входе, отдельный файловый API провайдераХранилище пространства, файлы результата в files[]
УчётСчёт каждого провайдера в токенахЭнергия с одного баланса, разбивка по end_user_ref

Запрос и ответ

Base URL
https://dash.octomatica.ru/v1
Авторизация
Authorization: Bearer octo_live_… на каждом запросе; ключ только на сервере
Ошибки
{"error":{code, message, details, trace_id}} и заголовок X-Trace-Id
Схема
/api/openapi.json
ЗапросPOST /v1/turns
POST /v1/turns
Authorization: Bearer octo_live_…
Content-Type: application/json
Idempotency-Key: 6f1c…-uuid

{
  "space": "api-1a2b3c4d5e6f",
  "text": "Сверь заказ 1042 со складом",
  "end_user_ref": "customer-42",
  "file_ids": ["9f3c…"],
  "metadata": {"order": 1042},
  "webhook_url": "https://app.example.com/octo"
}

→ 202 {"turn_id": "turn_ab12…",
       "state": "queued", "trace_id": "…"}
Location: /v1/turns/turn_ab12…
ОтветGET /v1/turns/{turn_id}
{
  "turn_id": "turn_ab12…",
  "state": "done",
  "current_activity": "…",
  "result": "Расхождение в 2 позициях…",
  "result_truncated": false,
  "error": null,
  "files": [{"file_id": "9f3c…",
    "name": "сверка.xlsx", "source": "agent",
    "url": "/v1/files/9f3c…"}],
  "usage": {"provider": "…", "model": "…",
    "total_tokens": …, "turn_energy": …,
    "linked_energy": …, "linked_calls": …},
  "energy_used": 0.123,
  "metadata": {"order": 1042}
}
  1. queuedturn.queued
  2. runningturn.running
  3. doneturn.completed
  4. failedturn.failed · error
  5. cancelledturn.cancelled
МеханизмКонтракт
ОпросGET /v1/turns/{turn_id} раз в 1-2 с, backoff до 10 с. Клиенту ждать не меньше 180 с; ход без прогресса 2 часа закрывается как failed (stale_reaped) без списания.
ВебхукPOST /v1/webhooks {url, events?, space?, secret?}, секрет показывается один раз; до 10 на ключ. Разово: webhook_url в самом ходе. Только https на публичный адрес.
ПодписьX-OOIH-Signature: t=<unix>,v1=<hex>, где v1 = HMAC-SHA256(secret, "<t>.<raw body>"); отклоняйте t старше 5 минут. Дедупликация по id события.
ДоставкаОтвет 2xx за 10 с. Повторы через 1 мин, 5 мин, 30 мин, 2 ч, 12 ч; затем redeliver. 410 отключает вебхук. Упавший endpoint не блокирует ход.
ИдемпотентностьТот же Idempotency-Key с тем же space и text возвращает исходный ход; с другими: 409 IDEMPOTENCY_CONFLICT.
Файлы на входPOST /v1/spaces/{slug}/files, multipart-поле file, до 200 МБ; затем до 10 file_ids на ход.
Файлы на выходfiles[].source: upload или agent. Скачивание GET /v1/files/{file_id} с Bearer; имя в UTF-8 в filename*.
Пределыmetadata 8 КБ, result 1 МБ (дальше result_truncated), списки до 200 элементов.

В публичном контракте /v1 нет потокового ответа и отдельных эндпоинтов памяти (wiki, recall): результат приходит целиком по опросу или вебхуку.

Чат-интерфейсы

Во всех каналах работает один агент; канал определяет только доставку сообщений. Каждый чат становится отдельным пространством.

КаналГде работает
Telegramличные чаты и группы с @octomatica_bot
Веб-чаткабинет dash.octomatica.ru; приглашения участников на 7 дней
Bitrix24чат-бот в чатах портала
Яндекс Мессенджербот в чатах организации Яндекс 360
APIваш собственный интерфейс
Свой чат
Храните space_id рядом с разговором; сообщение пользователя равно одному ходу, Idempotency-Key равен id сообщения.
Индикатор
current_activity из опроса показывает, что агент делает сейчас.
Стоп
POST /v1/turns/{turn_id}/cancel; после терминального состояния 409 ALREADY_TERMINAL.

Пространства: создание и настройка

Пространство = ядро агента + канал + инструменты + манифест + политика маршрутизации. Память и файлы одного пространства недоступны другому.

МетодТелоЧто задаёт
POST /v1/spaces{title?}201 {space_id: "api-<12 hex>", origin: "api"}. Без переопределения пространство маршрутизируется политикой платформы.
PUT /v1/spaces/{slug}/manifest{manifest}Постоянные инструкции: роль агента, когда вызывать какие инструменты, каким вызовом сдавать результат.
PUT /v1/spaces/{slug}/secrets{secrets: {NAME: value}}Шифруются, не читаются обратно, доступны инструментам как переменные окружения. Имя [A-Z_][A-Z0-9_]*; OOIH_*, OPENAI_*, ANTHROPIC_*, GEMINI_*, OPENROUTER_* отклоняются (RESERVED_SECRET_NAME).
PUT | PATCH /v1/spaces/{slug}/tools{allow, mcp_servers}Встроенные возможности и ваши MCP-серверы (раздел MCP). PATCH меняет только переданные поля.
PUT /v1/spaces/{slug}/policy{orchestration, switch?}Модель пространства (раздел Политики).
GET /v1/spacesДоступные ключу пространства с флагами has_manifest, has_secret, has_tools.

Личное пространство Commander через API не управляется: для приложения создайте отдельное API-пространство.

MCP в вашем приложении

Ваши внутренние операции агент вызывает через ваш MCP-сервер. Права пользователя на операцию проверяет ваш сервер.

КонфигурацияPUT /v1/spaces/{slug}/tools
{
  "allow": ["web", "files", "code"],
  "mcp_servers": [{
    "name": "shop",
    "url": "https://mcp.shop.example.com",
    "headers": {"Authorization": "Bearer …"}
  }]
}
Результат

Вызов вместо разбора текста

Опишите вывод как инструмент с входной схемой, например submit_report(title, sections), и потребуйте в манифесте сдавать результат им. Ошибка валидации уходит агенту, он повторяет вызов с исправленными аргументами.

Встроенные

allow

null снимает ограничение. Каталог: GET /v1/tools/catalog. Платные: image, media, seo, lizard; с проверкой баланса: higgsfield, elevenlabs.

Доступ

Заголовки и секреты

headers авторизуют Octo на вашем MCP-сервере. Ключи ваших сервисов для встроенного кода кладите в секреты пространства, а не в манифест.

Память

Контекст не растёт бесконечно: в следующую сессию переходит то, что консолидация записала в память пространства.

ЭтапЧто происходитВидно через API
СессияХоды продолжают одну сессию агента, пока контекст ниже порога консолидации.model_state.session: resumable, turns, age_sec; model_state.context: used_tokens, threshold_tokens, used_pct
DreamКонсолидация идёт на копии сессии той же моделью. Устойчивые факты пишутся в память пространства со ссылкой на источник: сессия и диапазон байтов.last_dream_at, estimate.turns_until_dream
Новая сессияСтарая запечатывается. Новая стартует с базовых инструкций, индекса памяти, списка запечатанных сессий и короткого хвоста разговора.session.id меняется
ПервоисточникПо ссылке из памяти агент читает нужный фрагмент запечатанной сессии, не загружая историю целиком.внутри агента
Явная запись«Запомни» пишется во входящие. Dream сверяет: дубликат не меняет память, исправление заменяет факт, противоречие помечается к уточнению.внутри агента
Параллельные ходыСмена сессии сериализована на пространство; конкурирующий ход присоединяется к новой сессии.внутри агента

Маршрутизация и политики

Модель выбирается на старте сессии по политике для каждого вида работы и сохраняется, пока сессия продолжается.

Маршрутизация по провайдерам

Вид работыКто настраивает
orchestrationход агента; пространство может переопределить
coding-plan, coding-design, coding-execоператор платформы (403 OPERATOR_ONLY)
thinkingфиксированная эскалация платформы
без видапо умолчанию пространства
Кандидаты
GET /v1/models отдаёт каталог и fleet_default: вид работы → список моделей, первый предпочтителен. Движки: claude-code, codex, opencode.
Резерв
Модель пропускается с причиной INELIGIBLE, OUT_OF_BUDGET, AT_CAPACITY или UNHEALTHY, запускается следующий кандидат.
На один ход
"model": "opus55" в POST /v1/turns; итог в model_override. Смена движка закрывает сессию через dream.
Факт
usage.provider и usage.model в ответе хода.

Политика пространства

ПереопределениеPUT /v1/spaces/{slug}/policy
{"orchestration": "<id из GET /v1/models>",
 "switch": "force"}

DELETE /v1/spaces/{slug}/policy/orchestration
→ {"cleared": true, "source": "fleet_default"}
switchКогда применяется
softпо умолчанию: на следующем dream, кэш сессии сохраняется; без dream 6 часов, на следующем ходе
forceперед следующим ходом: dream и перезапуск сессии
cancelснимает ожидающее переключение
Состояние
GET /v1/spaces/{slug}/policy: по каждому виду configured, resolved, source, reasons, плюс model_state с pending, forced, capacity.
Отказы
400 UNKNOWN_MODEL, 403 INELIGIBLE. Премиум-модель сверх баланса сохраняется с warning.code: OUT_OF_BUDGET, до пополнения работает резерв.
Ключ
Область доступа: own (только созданные ключом пространства, по умолчанию), space (одно), account (все API-пространства аккаунта).

Единый биллинг

Модели разных провайдеров, инструменты, субагенты и проходы памяти списываются в энергии с одного баланса владельца. Себестоимость провайдера в API не раскрывается.

Поле или методСмысл
energy_usedфактическое списание за весь ход со всеми множителями
usage.turn_energyсобственный запуск агента
usage.linked_energy, linked_callsсубагенты, инструменты, память, вызванные ходом
GET /v1/usagegroup_by=end_user|space|key, scope=account|key → breakdown[{key, energy_used, turns}] для перевыставления счетов своим пользователям
ОграничениеОтвет
баланс владельца исчерпан402 INSUFFICIENT_CREDITS; повтор без пополнения не поможет
дневной лимит ключа: 50 энергии по умолчанию, до 10 000, сброс 00:00 UTC429 QUOTA_EXCEEDED, daily_cap, Retry-After
месячный лимит ключа429, monthly_cap, Retry-After
лимит пользователя: PATCH /v1/spaces/{slug}/end-users/{ref} {total_limit_energy}429, end_user_limit, без Retry-After
оконные лимиты из кабинета429, usage_window, Retry-After