📚 База знаний в API
Что это. Раздел публичного API, через который база знаний проекта наполняется и читается программно: папки, документы, поиск, загрузка файлов, массовые операции и синхронизация с внешним источником.
Когда нужно.
- Держать базу знаний в актуальном состоянии автоматически: выгружать в неё регламенты, инструкции и статьи из внешней системы (Confluence, Notion, репозиторий с Markdown).
- Отдавать в базу знаний контент, который генерирует ваша система, чтобы AI отвечал по нему клиентам.
- Забирать документы в свою систему — например, для отчёта или резервной копии.
Где находится
Публичные пути раздела начинаются с /v1/knowledge-base/, в Swagger UI они собраны в разделе Knowledge Base.
Ниже описано, что делает каждая операция, какие у неё поля и ограничения. Полные адреса и схемы тел берите в Swagger UI: набор публичных маршрутов расширяется, и спецификация собирается на лету. Если операции в спецификации нет, значит наружу она пока не опубликована и доступна только в интерфейсе.
Идентификатор проекта в запросах не передаётся — он определяется по API-ключу.
Права
| Действие | Требуемое право |
|---|---|
| Чтение папок, дерева, документов, поиск | KNOWLEDGE_BASE_READ |
| Создание и переименование папок, создание и изменение документов, загрузка файла | KNOWLEDGE_BASE_WRITE |
| Удаление папок и документов, массовое удаление | KNOWLEDGE_BASE_DELETE |
| Массовый импорт из внешнего источника | KNOWLEDGE_BASE_MANAGE |
Подробнее про права — на странице Scopes.
Документы автоматически разбиваются на фрагменты и индексируются для AI. Индексация идёт фоном, поэтому только что созданный или изменённый документ становится доступен AI с небольшой задержкой.
📁 Папки
| Операция | Что делает |
|---|---|
| Список папок | Постраничный список всех папок проекта, по умолчанию 20 на страницу |
| Создать папку | Создаёт папку в корне или внутри другой папки |
| Получить папку | Возвращает папку по идентификатору |
| Переименовать папку | Меняет только название |
| Удалить папку | Удаляет папку вместе со всем содержимым |
Поля папки:
| Поле | Обязательно | Описание |
|---|---|---|
name | да | Название папки, до 64 символов |
parentFolderId | нет | Родительская папка. Не передан — папка создаётся в корне. Задаётся только при создании |
Папка в ответе содержит id, projectId, parentId, name, createdAt, updatedAt.
Удаление папки рекурсивное: вместе с ней исчезают вложенные папки и все документы внутри. Восстановить их нельзя — версий и корзины у базы знаний нет.
🌳 Дерево
Дерево отдаётся двумя операциями:
| Операция | Что возвращает |
|---|---|
| Корень дерева | Папки верхнего уровня и документы, лежащие вне папок |
| Содержимое папки | Вложенные папки и документы внутри конкретной папки |
Ответ в обоих случаях одинаковый: объект с полями folders (список папок) и documents (список документов).
📄 Документы
| Операция | Что делает |
|---|---|
| Список документов | Постраничный список документов проекта |
| Создать документ | Создаёт документ в корне или в папке |
| Получить документ | Возвращает документ целиком, вместе с содержимым |
| Изменить документ | Полностью заменяет состояние документа |
| Удалить документ | Удаляет документ и его фрагменты из индекса |
Параметры списка: page (нумерация с нуля), size (по умолчанию 20), sort — например sort=updatedAt,desc.
Поля документа:
| Поле | Обязательно | Описание |
|---|---|---|
title | да | Название, до 64 символов |
content | да | Содержимое в формате Markdown. Верхнего предела длины нет |
folderId | нет | Папка документа. Не передан или null — документ лежит в корне |
Документ в ответе содержит id, projectId, folderId, title, content, authorId, createdAt, updatedAt.
Метод изменения — не частичное обновление: если не передать folderId, документ переедет в корень, а не останется в своей папке. Передавайте все поля.
Автор документа берётся из того, кто вызвал метод. Если ни название, ни папка, ни содержимое не изменились, документ не переиндексируется — повторная отправка того же текста ничего не стоит.
При индексации документ режется на фрагменты по заголовкам Markdown, и фрагмент никогда не пересекает границу заголовка. Чем аккуратнее разбит текст, тем точнее AI находит нужный кусок.
🔍 Поиск
Поиск принимает обязательный параметр query и необязательные page и size (по умолчанию 20).
Это поиск по названиям документов, а не по содержимому: текст внутри документа не ищется. Совпадение нечёткое — близкие по написанию названия тоже находятся. Смысловой поиск по содержимому работает внутри AI и наружу не публикуется.
Результаты возвращаются от новых документов к старым; сортировку задать нельзя.
📎 Загрузка файла
Загрузка выполняется как multipart/form-data:
| Поле формы | Обязательно | Описание |
|---|---|---|
file | да | Файл в формате PDF, DOCX, TXT или MD, непустой, не больше 1 МБ |
title | нет | Название документа. Если не передать — берётся имя файла без расширения |
folderId | нет | Папка, в которую положить документ. Не передан — корень |
- Из PDF и DOCX извлекается только текст: изображения, таблицы-картинки и оформление не сохраняются.
- TXT и MD читаются в кодировке UTF-8.
- Файл другого формата отклоняется с ошибкой
Unsupported file format. - Те же ограничения действуют и в интерфейсе: «Неподдерживаемый формат. Допустимы: PDF, DOCX, TXT, MD», «Файл пустой», «Файл слишком большой (максимум 1 МБ)».
🧹 Массовые операции
Для больших наборов документов есть четыре операции: массовое удаление документов, массовый перенос документов, массовое удаление папок и массовый перенос папок.
| Что важно знать | Как работает |
|---|---|
| Атомарность | Каждая пачка выполняется одной транзакцией: успешный ответ означает, что применилась вся пачка целиком |
| Результат | В ответе приходит поле count — сколько объектов реально затронуто |
| Пропуски | Несуществующие идентификаторы молча пропускаются и в count не попадают; перенос туда, где документ уже лежит, тоже не считается |
| Корень проекта | Пустое значение целевой папки означает «перенести в корень проекта» |
| Папки | Удаление папок рекурсивное. Перенести папку в саму себя или в свою же подпапку нельзя — вернётся 400 |
В интерфейсе это те же действия: «Выбрать все», «Снять выделение», «Удалить выбранные», «Переместить в…», с итогом вида «Удалено документов: N из M».
🔄 Массовый импорт из внешнего источника
Требуемое право — KNOWLEDGE_BASE_MANAGE.
Этот метод предназначен для синхронизации базы знаний с внешним источником: одним запросом вы отправляете пачку документов, а Fixorix сам решает, что создать, что обновить, что удалить и что оставить как есть. Экрана в интерфейсе у него нет — только API.
Как работает идемпотентность
Каждый документ опознаётся по тройке проект + source + externalId:
- документа с таким ключом ещё нет → он создаётся;
- документ есть, и название, содержимое или папка изменились → он обновляется;
- документ есть и ничего не изменилось → он пропускается, повторная индексация не запускается;
- элемент с
op: "DELETE"→ документ удаляется; если его уже нет — элемент просто пропускается.
Благодаря этому повторный запуск синхронизации безопасен: одна и та же пачка, отправленная дважды, не создаёт дублей.
Тело запроса
| Поле | Обязательно | Описание |
|---|---|---|
source | да | Имя внешнего источника, до 32 символов. Например confluence. Разделяет пространства идентификаторов: документы из разных источников не пересекаются |
items | да | Элементы пачки. Пустой список не принимается |
Поля элемента:
| Поле | Обязательно | Описание |
|---|---|---|
externalId | да | Устойчивый идентификатор документа в вашей системе, до 512 символов |
op | нет | UPSERT (значение по умолчанию) или DELETE |
title | для UPSERT | Название, до 64 символов |
content | для UPSERT | Содержимое в Markdown |
folderPath | нет | Путь папок списком сегментов. Недостающие папки создаются автоматически, пустой путь — корень. Каждый сегмент до 64 символов |
metadata | нет | Произвольные поля вашего источника («строка → строка»): ссылка, теги, slug. Передаются дальше вместе с фрагментами документа, служебные поля не перетирают |
Ответ
{
"created": 12,
"updated": 3,
"deleted": 1,
"skipped": 84,
"failed": [
{ "externalId": "guides/legacy", "error": "..." }
]
}
Элементы обрабатываются по одному, и ошибка одного документа не отменяет всю пачку: он попадает в failed со своим externalId и текстом ошибки, а остальные применяются. Такой элемент можно повторить отдельным запросом.
Пример тела запроса
{
"source": "confluence",
"items": [
{
"externalId": "space/PAY/page/1024",
"op": "UPSERT",
"title": "Способы оплаты",
"content": "## Карты\nПринимаем карты Мир...",
"folderPath": ["Продукт", "Оплата"],
"metadata": { "url": "https://wiki.example.com/PAY/1024" }
},
{
"externalId": "space/PAY/page/77",
"op": "DELETE"
}
]
}
Как выстроить синхронизацию
- Заведите отдельный API-ключ с правом
KNOWLEDGE_BASE_MANAGE(и только с ним). - Выберите устойчивый
externalId— такой, который не меняется при переименовании страницы: идентификатор страницы или путь к файлу. - При первом запуске отправьте все документы, дальше — только изменившиеся и удалённые. Неизменившиеся документы можно отправлять всегда: они попадут в
skipped. - Отправляйте документы пачками (несколько сотен элементов), а не по одному — так вы экономите лимит запросов.
- После каждого запуска проверяйте
failedи логируйте его.
Ограничения
- Поиск работает только по названию документа. Найти документ по фразе из текста нельзя ни в API, ни в интерфейсе.
- Версий документов нет. Изменение перезаписывает содержимое, удаление необратимо, откатиться некуда.
- Не видно, какой документ попал в ответ AI. Связь «ответ бота ↔ статья» наружу не публикуется.
- У импортированных документов нет автора — в колонке «Автор» в интерфейсе будет прочерк.
- Название документа и каждый сегмент пути папок — не длиннее 64 символов; более длинные значения нужно обрезать на своей стороне.
- Импорт работает только с документами. Удалить папку через импорт нельзя — для этого есть отдельная операция удаления папки.
- Файл — не больше 1 МБ и только PDF, DOCX, TXT или MD.
- Формат ответов неровный: успешные ответы всегда приходят с кодом
200(даже создание и удаление), а тело ошибок зависит от кода — часть ошибок приходит обычным текстом, часть с пустым телом. Ориентируйтесь на HTTP-статус, а не на тело.
Кто что может
| Действие | Минимальная роль |
|---|---|
| Выпустить API-ключ с правами базы знаний | Администратор |
| Читать документы в интерфейсе | Участник |
| Создавать, загружать и править документы в интерфейсе | Редактор |
| Удалять документы и папки в интерфейсе | Администратор |
По API роль участника не проверяется: важен только набор прав самого ключа.
Если импорт возвращает ошибки в failed, сохраните externalId и текст ошибки и напишите в поддержку — по ним видно, на каком именно документе спотыкается синхронизация.