API Reference
Усі кінцеві точки мають префікс /api/v1, якщо не зазначено інше. Автентифікація через JWT Bearer токен.
Інтерактивна документація доступна на /docs (Swagger UI), коли сервер запущено. Swagger генерується зі схем маршрутів Fastify, зареєстрованих у src/app.ts, URL-адреса сервера OpenAPI — /api/v1, а згенерована специфікація підтримує англійську, російську та українську через /docs/json?lang=en|ru|uk.
Відповіді на помилки
У відповідях на помилки використовується один конверт:
{
"error": "ValidationError",
"message": "Request validation failed",
"statusCode": 422,
"details": {}
}
details є необов’язковим і відображається лише тоді, коли маршрут або middleware має структуровану діагностику.
Автентифікація
Реєстрація
POST /api/v1/auth/register
Тіло: { "email": string, "password": string, "name": string, "departmentId": string }
Відповідь: { "token": string, "user": { id, email, name, role, departmentId } }
Реєстрації завжди використовують дефолтну роль employee. Клієнтський role не приймається.
Вхід
POST /api/v1/auth/login
Тіло: { "email": string, "password": string }
Відповідь: { "token": string, "user": { id, email, name, role, departmentId } }
Refresh token
POST /api/v1/auth/refresh
Заголовок: Authorization: Bearer <token>
Відповідь: { "token": string }
Забув пароль
POST /api/v1/auth/forgot-password
Тіло: { "email": string }
Відповідь завжди { "ok": true }, щоб уникнути enumeration акаунтів. Поточна реалізація логує reset-токен скидання та залишає доставку пошти як integration point для email-застосунку.
Скинути пароль
POST /api/v1/auth/reset-password
Тіло: { "token": string, "newPassword": string }
newPassword має містити принаймні 8 символів і містити принаймні одну літеру та одну цифру.
Відповідь: { "ok": true }
Управління базою знань
Список баз знань
GET /api/v1/knowledge/bases
Запит: ?departmentId=<id> (необов’язковий; дозволений лише в межах ефективного відділу абонента)
Auth: будь-який автентифікований користувач
Отримати базу знань
GET /api/v1/knowledge/bases/:id
Auth: будь-який автентифікований користувач із department-scope доступом
Створити базу знань
POST /api/v1/knowledge/bases
Тіло: { "name": string, "departmentId": string, "description"?: string }
Auth: будь-який автентифікований користувач із department-scope доступом
Оновити базу знань
PATCH /api/v1/knowledge/bases/:id
Тіло: { "name"?: string, "description"?: string|null }
Auth: будь-який автентифікований користувач із department-scope доступом
Оновити конфігурацію RAG бази знань
PATCH /api/v1/knowledge/bases/:id/config
Тіло: { "ragWeights": { "vector": number, "keyword": number } }
Авторизація: дозвіл canUploadDocuments
Видалити базу знань
DELETE /api/v1/knowledge/bases/:id
Авторизація: дозвіл canDeleteDocuments
Список документів
GET /api/v1/knowledge/documents
Запит: ?knowledgeBaseId=<id>&status=<status>&type=<type>
Auth: будь-який автентифікований користувач
Завантажити документ (файл)
POST /api/v1/knowledge/upload
Content-Type: multipart/form-data
Поля: file (binary), knowledgeBaseId (рядок), title (рядок)
Auth: будь-який автентифікований користувач із department-scope доступом
Допустимі формати: PDF, DOCX, TXT, зображення (PNG, JPG)
Створити документ (URL)
POST /api/v1/knowledge/documents
Тіло: { "knowledgeBaseId": string, "title": string, "type": "url", "originalUrl": string }
Auth: будь-який автентифікований користувач із department-scope доступом
Оновити документ
PATCH /api/v1/knowledge/documents/:id
Тіло: { "title"?: string, "originalUrl"?: string|null, "metadata"?: object }
Auth: будь-який автентифікований користувач із department-scope доступом
Отримати документ
GET /api/v1/knowledge/documents/:id
Відповідь включає метадані документа та чанки, якщо авторизовано. Auth: будь-який автентифікований користувач із department-scope доступом
Повторно обробити документ
POST /api/v1/knowledge/documents/:id/reprocess
Re-enqueues документ на ingestion. Auth: будь-який автентифікований користувач із department-scope доступом
Видалити документ
DELETE /api/v1/knowledge/documents/:id
Авторизація: дозвіл canDeleteDocuments
Схвалення (HITL)
Перелік схвалень, що очікують на розгляд
GET /api/v1/approvals
Запит: ?departmentId=<id>&limit=<n>&offset=<n>
Автентифікація: дозвіл canApprove (в межах відділу для неглобальних користувачів)
Отримати схвалення
GET /api/v1/approvals/:id
Відповідь включає джерела RAG, які використовуються для відповіді.
Авторизація: дозвіл canApprove
Схвалити повідомлення
POST /api/v1/approvals/:id/approve
Тіло: { "editedContent"?: string } (додаткове редагування перед затвердженням)
Авторизація: дозвіл canApprove
Відхилити повідомлення
POST /api/v1/approvals/:id/reject
Тіло: { "reason"?: string }
Авторизація: дозвіл canApprove
Батч-схвалення/відхилення
POST /api/v1/approvals/batch
Тіло: { "decisions": [{ "approvalId": string, "action": "approve"|"reject", "editedContent"?: string, "reason"?: string }] }
Максимум 50 рішень на запит.
Авторизація: дозвіл canApprove
Ескалація
POST /api/v1/approvals/:id/escalate
Тіло: { "escalatedToId": string, "reason"?: string }
Авторизація: дозвіл canEscalate
Розмови
Список розмов
GET /api/v1/conversations
Запит: ?departmentId=<id>&channel=<channel>&status=<status>&limit=<n>&offset=<n>
Auth: дозвіл canApprove (для неглобальних користувачів department scope)
Отримати повідомлення
GET /api/v1/conversations/:id/messages
Запит: ?cursor=<message-id>&limit=<n>
Auth: дозвіл canApprove (для неглобальних користувачів department scope)
Профілі співробітників
Список профілів
GET /api/v1/employee-profiles
Auth: будь-який автентифікований користувач. Результати обмежені ефективним обсягом відділу абонента; глобальні користувачі можуть фільтрувати за departmentId.
Отримати профіль
GET /api/v1/employees/:userId/profile
Аутентифікація: власний профіль або профіль у межах ефективного department scope викликача.
Оновити профіль
PATCH /api/v1/employees/:userId/profile
Тіло: { "summary"?: string, "currentProjects"?: string[], "preferences"?: object, "frequentIntents"?: string[], "accessLevel"?: string, "metadata"?: object }
Авторизація: користувачі можуть оновлювати власний профіль; дозвіл canManageEmployeeProfiles потрібен для інших видимих профілів.
Простори імен
Список просторів імен
GET /api/v1/namespaces
Auth: будь-який автентифікований користувач (в межах відділу)
Отримати простір імен
GET /api/v1/namespaces/:id
Auth: будь-який автентифікований користувач (в межах відділу)
Створити простір імен
POST /api/v1/namespaces
Тіло: { "name": string, "departmentId": string, "systemPrompt"?: string, "persona"?: object, "config"?: object }
Додатково config.agentRunner вибирає адаптер простору імен.
Авторизація: дозвіл canManageNamespaces
Оновити простір імен
PATCH /api/v1/namespaces/:id
Тіло: { "name"?: string, "systemPrompt"?: string|null, "persona"?: object, "config"?: object }
Авторизація: дозвіл canManageNamespaces
Видалити простір імен
DELETE /api/v1/namespaces/:id
Авторизація: дозвіл canManageNamespaces
Наміри
Список імен намірів
GET /api/v1/intents
Запит: ?namespaceId=<id>&limit=<n>&offset=<n>
Auth: будь-який автентифікований користувач із department-scope доступом простору імен
Отримати матрицю довіри
GET /api/v1/intents/trust
Запит: ?namespaceId=<id>
Авторизація: дозвіл canManageNamespaces
Додати приклад наміру
POST /api/v1/intents/examples
Тіло: { "namespaceId": string, "intentName": string, "exampleText": string }
Авторизація: дозвіл canManageNamespaces
Класифікувати текст
POST /api/v1/intents/classify
Тіло: { "text": string, "namespaceId": string }
Auth: будь-який автентифікований користувач
Тестування RAG
Чернетка запиту
POST /api/v1/rag/draft
Тіло: { "departmentId": string, "text": string }
Відповідь: { "answer": string, "sources": array, "injectionDetected": boolean, "injectionReason"?: string }
Авторизація: дозвіл canViewKnowledge
Відділи
Список відділів
GET /api/v1/departments
Запит: ?search=<text>&includeArchived=<bool>&limit=<n>&offset=<n>
Auth: будь-який автентифікований користувач; результати обмежені ефективними відділами користувача.
Отримати відділ
GET /api/v1/departments/:id
Auth: будь-який автентифікований користувач із доступом до цього відділу
Створити відділ
POST /api/v1/departments
Тіло: { "name": string, "slug"?: string, "color"?: string, "description"?: string|null, "settings"?: object }
Авторизація: дозвіл canManageDepartments
Оновити відділ
PATCH /api/v1/departments/:id
Тіло: { "name"?: string, "color"?: string, "description"?: string|null, "settings"?: object }
Авторизація: дозвіл canManageDepartments
Архівувати відділ
POST /api/v1/departments/:id/archive
Soft-архівує відділ.
Авторизація: дозвіл canArchiveDepartments
Користувачі
Список користувачів
GET /api/v1/users
Запит: ?role=<role>&departmentId=<id>&search=<text>&limit=<n>&offset=<n>
Авторизація: дозвіл canViewAllUsers
Створити користувача
POST /api/v1/users
Тіло: { "email": string, "password": string, "name": string, "phone"?: string|null, "role"?: Role, "departmentId": string }
Авторизація: дозвіл canCreateUsers
Отримати користувача
GET /api/v1/users/:id
Auth: власний або дозвіл canViewAllUsers у межах ефективного відділу
Оновити користувача
PATCH /api/v1/users/:id
Тіло: { "name"?: string, "phone"?: string|null, "role"?: Role, "roleId"?: string, "departmentId"?: string, "isActive"?: boolean }
Auth: користувачі можуть оновлювати власні поля профілю; дозвіл canManageUsers потрібен для змін ролі, відділу або активного стану.
Деактивувати користувача
DELETE /api/v1/users/:id
Soft-деактивація користувача та анулювання сеансів.
Авторизація: дозвіл canManageUsers
Ефективний доступ
GET /api/v1/users/:id/effective-access
Повертає об’єкт ролі, перевизначення дозволів і обчислені ефективні дозволи/відділи.
Auth: власний або дозвіл canViewAllUsers у межах ефективного відділу
Аудит користувачів
GET /api/v1/users/:id/audit
Авторизація: permission canViewAudit
Перевизначення дозволів
POST /api/v1/users/:id/permissions/grant
POST /api/v1/users/:id/permissions/revoke
DELETE /api/v1/users/:id/permissions/grant/:permission
DELETE /api/v1/users/:id/permissions/revoke/:permission
Надати/скасувати приймає { "permission": string } або { "departmentId": string }.
Авторизація: дозвіл canManageUsers
Ролі та дозволи
Каталог дозволів
GET /api/v1/permissions
Повертає метадані згрупованих дозволів для редакторів ролей. Auth: будь-який автентифікований користувач
Список ролей
GET /api/v1/roles
Запит: ?search=<text>&includeSystem=<bool>&limit=<n>&offset=<n>
Авторизація: дозвіл canViewRoles
Створити роль
POST /api/v1/roles
Тіло: { "name": string, "slug"?: string, "allDepartments"?: boolean, "departmentIds"?: string[], "permissions"?: string[] }
Авторизація: дозвіл canManageRoles
Отримати роль
GET /api/v1/roles/:id
Авторизація: дозвіл canViewRoles
Оновити роль
PATCH /api/v1/roles/:id
Тіло: { "name"?: string, "slug"?: string, "allDepartments"?: boolean, "departmentIds"?: string[], "permissions"?: string[] }
Авторизація: дозвіл canManageRoles
Видалити роль
DELETE /api/v1/roles/:id
Системні ролі та ролі, призначені користувачам, не можна видалити.
Авторизація: дозвіл canManageRoles
Журнали аудиту
Список журналів аудиту
GET /api/v1/audit
Запит: ?action=<action>&entityType=<type>&userId=<id>&limit=<n>&offset=<n>
Авторизація: permission canViewAudit
Trace-и
Отримати trace
GET /api/v1/traces/:trace_id
Відповідь: AgentRun із зверненнями до пошуку. Автентифікація: будь-який автентифікований користувач (в межах відділу для неглобальних користувачів)
Analytics dashboard
GET /api/v1/analytics/dashboard
Запит: ?days=<1-90>&departmentId=<id>&from=<datetime>&to=<datetime>
Автентифікація: будь-який автентифікований користувач (в межах відділу для неглобальних користувачів)
Поточний користувач
Отримати поточного користувача
GET /api/v1/me
Повертає поточного користувача, відділ, підсумок профілю, об’єкт ролі, діючі дозволи/відділи та логічні значення можливостей інтерфейсу користувача. Auth: будь-який автентифікований користувач
Змінити пароль
POST /api/v1/me/change-password
Тіло: { "currentPassword": string, "newPassword": string }
Повертає новий JWT після інкремента tokenVersion.
Auth: будь-який автентифікований користувач
Вийти з усіх сеансів
POST /api/v1/me/logout-all
Інвалідує існуючі маркери та відключає активні сеанси WebSocket. Auth: будь-який автентифікований користувач
Аватар
POST /api/v1/me/avatar
DELETE /api/v1/me/avatar
Upload приймає один image-файл через multipart (PNG, JPG або WebP, максимум 2 МБ) і зберігає /static/avatars/<user-id>.<ext>.
Auth: будь-який автентифікований користувач
Health
Health check
GET /api/v1/health
Авторизація не потрібна.
Завдання агента
Список завдань агента
GET /api/v1/agent-tasks
Запит: ?namespaceId=<id>&departmentId=<id>&status=<status>&adapterType=<type>&from=<datetime>&to=<datetime>&limit=<n>&offset=<n>
Значення статусу: queued, running, done, failed, timeout
Відповідь: { items: AgentTask[], total: number, limit: number, offset: number }
Auth: будь-який автентифікований користувач
Отримати деталі завдання агента
GET /api/v1/agent-tasks/:id
Відповідь містить вкладений масив toolCalls із покроковим трасуванням виконання (назва кроку, статус, вхідні дані, вихідні дані, тривалість Ms, повідомлення про помилку).
Auth: будь-який автентифікований користувач
Статистика завдань агента
GET /api/v1/agent-tasks/stats
Запит: ?namespaceId=<id>&departmentId=<id>&adapterType=<type>&from=<datetime>&to=<datetime>
Відповідь: { stats: [{ adapterType, namespaceId, total, successRate, avgDurationMs, avgCostUsd, byStatus }] }
Auth: будь-який автентифікований користувач
Плагіни інтеграції
Список доступних плагінів
GET /api/v1/plugins
Повертає вбудовані та зареєстровані метадані плагіна. Auth: будь-який автентифікований користувач
Список плагінів простору імен
GET /api/v1/namespaces/:id/plugins
Auth: дозвіл canManagePlugins або canManageNamespaces
Увімкнути плагін простору імен
POST /api/v1/namespaces/:id/plugins/:pluginId
Тіло: { "config"?: object, "enabled"?: boolean }
Конфігурацію перевірено на відповідність схемі Zod плагіна.
Auth: дозвіл canManagePlugins або canManageNamespaces
Оновити плагін простору імен
PATCH /api/v1/namespaces/:id/plugins/:pluginId
Тіло: { "config"?: object, "enabled"?: boolean }
Auth: дозвіл canManagePlugins або canManageNamespaces
Вимкнути плагін простору імен
DELETE /api/v1/namespaces/:id/plugins/:pluginId
Позначає namespace-plugin вимкненим і видаляє з runtime-кешу реєстру.
Auth: дозвіл canManagePlugins або canManageNamespaces
Шаблони документів
Список шаблонів
GET /api/v1/document-templates
Запит: ?category=<category>&departmentId=<id>&limit=<n>&offset=<n>
Auth: будь-який автентифікований користувач, department-scope
Створити шаблон
POST /api/v1/document-templates
Тіло: { "namespaceId": string, "departmentId"?: string|null, "name": string, "description"?: string|null, "category"?: "contract"|"proposal"|"letter"|"invoice"|"custom", "templateBody": string, "variables"?: array, "outputFormat"?: "md"|"html"|"docx"|"pdf" }
Авторизація: дозвіл canManageTemplates
Оновити шаблон
PATCH /api/v1/document-templates/:id
Body приймає ті самі редаговані поля, що й create, за винятком namespaceId.
Авторизація: дозвіл canManageTemplates
Видалити шаблон
DELETE /api/v1/document-templates/:id
Авторизація: дозвіл canManageTemplates
Створити документ
POST /api/v1/document-templates/:id/generate
Тіло: { "input"?: object, "preview"?: boolean, "outputFormat"?: "md"|"html"|"docx"|"pdf", "saveToKnowledgeBaseId"?: string|null }
Реалізовані експорти md, html і docx. pdf зарезервовано, наразі повертає 501.
Авторизація: дозвіл canGenerateDocuments
Історія генерацій
GET /api/v1/document-generations
GET /api/v1/document-generations/:id
Фільтри запиту: ?userId=<id>&templateId=<id>&limit=<n>&offset=<n>.
Користувачі бачать власну історію генерацій, якщо вони не мають дозволу на керування шаблонами для відділу.
Сповіщення
Список сповіщень
GET /api/v1/notifications
Запит: ?unreadOnly=<bool>&limit=<n>&offset=<n>
Відповідь включає items, pagination і unreadCount.
Auth: будь-який автентифікований користувач
Позначити прочитаним
PATCH /api/v1/notifications/:id/read
Авторизація: лише власник
Позначити все як прочитане
POST /api/v1/notifications/read-all
Auth: будь-який автентифікований користувач
Видалити сповіщення
DELETE /api/v1/notifications/:id
Авторизація: лише власник
WebSocket
Події завдань агента
ws://<host>/ws/agent-tasks
Підписатись на live-події lifecycle agent tasks по namespace.
Автентифікація: Перше повідомлення має бути auth handshake першого повідомлення JSON:
{ "action": "auth", "token": "<jwt>" }
Успіх: сервер відповідає { "event": "authenticated", "payload": {} }. Усі інші повідомлення до автентифікації відхиляються, а з’єднання закривається.
Повідомлення клієнта (після авторизації):
{ "action": "subscribe", "namespaceId": "<id>" }— підписатися на простір імен{ "action": "unsubscribe", "namespaceId": "<id>" }— скасувати підписку на простір імен (без namespaceId — відписатись від усіх)
Події сервера:
| Подія | Payload |
|-------|---------|
| agent-task.created | { taskId, jobId, namespaceId, adapterType, status: "queued" } |
| agent-task.started | { taskId, jobId, namespaceId, adapterType, status: "running" } |
| agent-task.tool-call | { taskId, ..., progress, toolCall: { id, stepName, status, inputData, outputData, durationMs } } |
| agent-task.completed | { taskId, ..., status: "done", output, durationMs } |
| agent-task.failed | { taskId, ..., status: "failed"|"timeout", errorMessage } |
Автентифікація: токен JWT, надсилається через first-message handshake (ніколи через параметр запиту).
Події сповіщень
ws://<host>/ws/notifications
Використовує те саме JWT first-message handshake, що й події завдання агента. Сервер надсилає лише події сповіщень поточного користувача.
Адміністратор
Bull Board queue dashboard
GET /admin/queues
Технічний queue-monitoring UI. Показує всі черги BullMQ (agent-tasks, wa-inbound, wa-outbound, tg-inbound, tg-outbound, knowledge-ingest, memory-extraction).
Авторизація: дозвіл canEditSettings
Кінцеві точки каналу
WhatsApp
GET /api/v1/whatsapp/status # Connection status
GET /api/v1/whatsapp/webhook # Meta verification (hub.challenge)
POST /api/v1/whatsapp/webhook # Inbound messages from Meta
Telegram
GET /api/v1/telegram/status # Bot status