Skip to content

Справочник API: FAQ и Wiki ​

Управление записями FAQ и страницами Wiki в базе знаний: импорт, поиск, редактирование и восстановление версий.

Обе группы — подресурсы содержимого KB: чтение — Viewer+ и KB read (API key retrieve/full); запись — «создатель KB OR Admin+» и KB write (API key ingest/full); обе ограничены белым списком KB. Межбазовый поиск по Wiki POST /wiki-search не содержит KB в пути: Viewer+ и API key retrieve/full; внутри handler проверяются allow-list каждой целевой базы и права Viewer на общие базы.

FAQ (/api/v1/knowledge-bases/:id/faq) ​

GET /api/v1/knowledge-bases/:id/faq/entries ​

Назначение: список записей FAQ.

Параметр запросаТипОбязательныйОписание
page / page_sizeintНетПагинация
tag_idintНетseq_id одиночного тега (устаревшее)
tag_idsstringНетUUID тегов через запятую
keywordstringНетКлючевое слово
search_fieldstringНетstandard_question/similar_questions/answers (по умолчанию все поля)
sort_orderstringНетasc (по умолчанию по времени обновления в порядке убывания)
is_enabledboolНетФильтр по состоянию включения: true — только включённые, false — только отключённые, без параметра возвращаются все; другие значения — 400

Ответ: 200 {"success":true,"data":{список FAQEntry с пагинацией}}

bash
curl "$BASE/api/v1/knowledge-bases/kb-1/faq/entries?page=1&is_enabled=false" -H "Authorization: Bearer $TOKEN"

GET /api/v1/knowledge-bases/:id/faq/entries/export ​

Назначение: экспорт FAQ. Параметры запроса: format (csv по умолчанию / json).

Ответ: 200 загрузка файла (text/csv или application/json).

bash
curl -OJ "$BASE/api/v1/knowledge-bases/kb-1/faq/entries/export?format=csv" -H "Authorization: Bearer $TOKEN"

GET /api/v1/knowledge-bases/:id/faq/entries/:entry_id ​

Назначение: детали записи FAQ (entry_id — целочисленный seq_id).

Ответ: 200 {"success":true,"data":{FAQEntry}}

bash
curl $BASE/api/v1/knowledge-bases/kb-1/faq/entries/12 -H "Authorization: Bearer $TOKEN"

POST /api/v1/knowledge-bases/:id/faq/entries ​

Назначение: массовый upsert / импорт (асинхронная задача). Метод Handler UpsertEntries.

ПолеТипОбязательноеОписание
entries[]FAQEntryPayloadДа (binding:"required")Массив записей
modestringДа (binding:"oneof=append replace")Добавление или замена
knowledge_idstringНетID сущности знания FAQ
task_idstringНетПользовательский ID задачи; допускаются только буквы, цифры, _, -; максимум 128 символов, иначе 400
dry_runboolНетТолько проверка без записи в базу

Ответ: 200 {"success":true,"data":{"task_id"}}

bash
curl -X POST $BASE/api/v1/knowledge-bases/kb-1/faq/entries -H "X-API-Key: $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"mode":"append","entries":[{"standard_question":"Как вернуть деньги?","answers":["Свяжитесь со службой поддержки"]}]}'

POST /api/v1/knowledge-bases/:id/faq/entry ​

Назначение: создать одну запись FAQ. Тело запроса (types.FAQEntryPayload):

ПолеТипОбязательноеОписание
standard_questionstringДа (binding:"required")Стандартный вопрос
similar_questions[]stringНетПохожие вопросы
negative_questions[]stringНетНегативные примеры вопросов
answers[]stringНетСписок ответов
answer_strategystringНетall / random
tag_idint64Нетseq_id тега
tag_namestringНетИмя тега
is_enabled / is_recommended*boolНетВключение/рекомендация

Ответ: 200 {"success":true,"data":{FAQEntry}}

bash
curl -X POST $BASE/api/v1/knowledge-bases/kb-1/faq/entry -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"standard_question":"Как вернуть деньги?","answers":["Возврат возможен в течение 7 дней"]}'

PUT /api/v1/knowledge-bases/:id/faq/entries/:entry_id ​

Назначение: обновить одну запись FAQ (тело запроса как при создании).

Ответ: 200 {"success":true,"data":{FAQEntry}}

bash
curl -X PUT $BASE/api/v1/knowledge-bases/kb-1/faq/entries/12 -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"standard_question":"Как вернуть деньги?","answers":["Возврат возможен в течение 30 дней"]}'

POST /api/v1/knowledge-bases/:id/faq/entries/:entry_id/similar-questions ​

Назначение: добавить похожие вопросы. Тело запроса: {"similar_questions":["..."]} (binding:"required,min=1").

Ответ: 200 {"success":true,"data":{FAQEntry}}

bash
curl -X POST $BASE/api/v1/knowledge-bases/kb-1/faq/entries/12/similar-questions \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"similar_questions":["Как оформить возврат"]}'

PUT /api/v1/knowledge-bases/:id/faq/entries/fields ​

Назначение: массовое обновление полей записей (is_enabled/is_recommended/tag_id).

ПолеТипОбязательноеОписание
by_idmap[int64]objectНетОбновление по seq_id записи
by_tagmap[int64]objectНетМассовое обновление по тегу
exclude_ids[]int64НетЗаписи, исключаемые при by_tag

Ответ: 200 {"success":true}

bash
curl -X PUT $BASE/api/v1/knowledge-bases/kb-1/faq/entries/fields -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"by_id":{"12":{"is_enabled":false}}}'

PUT /api/v1/knowledge-bases/:id/faq/entries/tags ​

Назначение: массово изменить теги записей. Тело запроса: {"updates":{"<entry_id>":<tag_id|null>}} (binding:"required,min=1"; null удаляет тег).

Ответ: 200 {"success":true}

bash
curl -X PUT $BASE/api/v1/knowledge-bases/kb-1/faq/entries/tags -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"updates":{"12":3}}'

DELETE /api/v1/knowledge-bases/:id/faq/entries ​

Назначение: массово удалить записи. Тело запроса: {"ids":[int64]} (binding:"required,min=1").

Ответ: 200 {"success":true}

bash
curl -X DELETE $BASE/api/v1/knowledge-bases/kb-1/faq/entries -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"ids":[12,13]}'

POST /api/v1/knowledge-bases/:id/faq/search ​

Назначение: поиск по FAQ (семантика только для чтения; scoped key с retrieve тоже может вызывать).

ПолеТипОбязательноеОписание
query_textstringДа (binding:"required")Запрос
vector_thresholdfloat64НетПорог вектора, по умолчанию 0.7
match_countintНетПо умолчанию 10, максимум 50
first_priority_tag_ids / second_priority_tag_ids[]int64НетФильтр по приоритету тегов
only_recommendedboolНетТолько рекомендуемые записи

Ответ: 200 {"success":true,"data":[FAQEntry (с match_type/score)]}

bash
curl -X POST $BASE/api/v1/knowledge-bases/kb-1/faq/search -H "X-API-Key: $API_KEY" \
  -H 'Content-Type: application/json' -d '{"query_text":"возврат"}'

PUT /api/v1/knowledge-bases/:id/faq/import/last-result/display ​

Назначение: задать состояние отображения панели последнего результата импорта. Тело запроса: {"display_status":"open|close"} (binding:"required,oneof=open close").

Ответ: 200 {"success":true}

bash
curl -X PUT $BASE/api/v1/knowledge-bases/kb-1/faq/import/last-result/display \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' -d '{"display_status":"close"}'

GET /api/v1/faq/import/progress/:task_id ​

Назначение: узнать прогресс импорта/dry-run FAQ (задачи изолированы по пространствам). Права: Viewer+; API key retrieve/ingest/full.

Ответ: 200 {"success":true,"data":{status,progress,failed_entries,...}}

bash
curl $BASE/api/v1/faq/import/progress/task-1 -H "X-API-Key: $API_KEY"

Wiki (/api/v1/knowledgebase/:kb_id/wiki) ​

Обратите внимание: префикс этой группы — /knowledgebase/:kb_id/wiki (в единственном числе, без дефиса). Handler: internal/handler/wiki_page.go. Ответы этой группы в основном сырые объекты (без обёртки success).

GET /api/v1/knowledgebase/:kb_id/wiki/pages ​

Назначение: список страниц Wiki.

Параметр запросаТипОбязательныйОписание
page_typestringНетТипы через запятую
statusstringНетСостояние страницы
querystringНетПолнотекстовый поиск
category_pathstringНетФильтр по пути с разделителем /
folder_idstringНетТочный фильтр по папке (пустая строка = корень)
category_depthintНетГлубина папки
page / page_sizeintНетПагинация (по умолчанию 1/20)
sort_by / sort_orderstringНетПоле сортировки: title, created_at, updated_at, page_type, wiki_path, sort_order, depth; другие значения — по updated_at; по умолчанию updated_at desc

Ответ: 200 WikiPageListResponse

bash
curl "$BASE/api/v1/knowledgebase/kb-1/wiki/pages?page=1" -H "Authorization: Bearer $TOKEN"

POST /api/v1/knowledgebase/:kb_id/wiki/pages ​

Назначение: создать страницу. Тело запроса (types.WikiPage): slug, title, content, folder_id, page_type и т. д. (все необязательны; при отсутствии slug генерируется автоматически).

Ответ: 201 WikiPage

bash
curl -X POST $BASE/api/v1/knowledgebase/kb-1/wiki/pages -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"title":"Обзор архитектуры","content":"# Обзор"}'

PUT /api/v1/knowledgebase/:kb_id/wiki/move-page ​

Назначение: переместить страницу в папку. Тело запроса: {"slug":"<slug страницы>","folder_id":"<ID папки|пусто=корень>"} (slug обязателен).

Ответ: 200 WikiPage

bash
curl -X PUT $BASE/api/v1/knowledgebase/kb-1/wiki/move-page -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"slug":"overview","folder_id":"f-1"}'

GET /api/v1/knowledgebase/:kb_id/wiki/pages/*slug ​

Назначение: получить страницу (*slug — путь с подстановкой).

Ответ: 200 WikiPageDetail. Содержит все поля WikiPage и дополнительно in_link_titles, отображающие заголовки страниц, slug которых перечислен в in_links (например, {"concept/example":"Пример заголовка"}). Если разрешить обратные ссылки не удаётся, возвращается пустой объект; отсутствующие цели не попадают в сопоставление. При ошибке запроса заголовков возвращается 500, чтобы не отдавать неполный успешный ответ.

bash
curl $BASE/api/v1/knowledgebase/kb-1/wiki/pages/overview -H "Authorization: Bearer $TOKEN"

PUT /api/v1/knowledgebase/:kb_id/wiki/pages/*slug ​

Назначение: обновить страницу (тело запроса как при создании). Старая версия сначала целиком сохраняется в wiki_page_revisions, version увеличивается, last_edit_source записывается как user (при записи инструментом Agent — agent).

Ответ: 200 WikiPage

bash
curl -X PUT $BASE/api/v1/knowledgebase/kb-1/wiki/pages/overview -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"content":"# Обновлённый обзор"}'

GET /api/v1/knowledgebase/:kb_id/wiki/revisions/*slug ​

Назначение: история версий страницы (migration 000075). Права: Viewer+ + KBAccessRead.

Параметр запросаТипОбязательныйОписание
versionintНетЕсли передан — возвращает полный текст этой версии (для diff); недопустимое значение или < 1 — 400; не найдено — 404 (у версий, записанных до обновления, или у снимков, очищенных политикой хранения, полного текста нет — это нормально)
limitintНетПо умолчанию 50, максимум 200; действует только в режиме списка
offsetintНетСмещение пагинации

Без version возвращается список истории (номера версий в порядке убывания, без основного текста) плюс текущий номер версии страницы; каждая запись содержит edit_source (pipeline / agent / user / revert), editor_id, edited_at.

Хранение истории имеет два предела: мягкий предел в 50 версий отсекает только снимки pipeline и с пустым источником, жёсткий предел в 200 версий действует для всех источников, поэтому ручные правки не вытесняются конвейером.

bash
# Список истории
curl $BASE/api/v1/knowledgebase/kb-1/wiki/revisions/entity/acme-corp -H "Authorization: Bearer $TOKEN"
# Получить полный текст 3-й версии
curl "$BASE/api/v1/knowledgebase/kb-1/wiki/revisions/entity/acme-corp?version=3" -H "Authorization: Bearer $TOKEN"

POST /api/v1/knowledgebase/:kb_id/wiki/revert ​

Назначение: откатить страницу к исторической версии. Права: KB owner или Admin+ + KBAccessWrite.

ПолеТипОбязательноеОписание
slugstringДаЦелевая страница
versionintДаНомер целевой версии (≥ 1)

Откат не уменьшает номер версии: содержимое целевой версии записывается как новая версия, last_edit_source записывается как revert, поэтому откат тоже можно откатить. Откат к текущей версии возвращает 400 (обычно из-за устаревшего списка истории на фронтенде).

Ответ: 200 WikiPage

bash
curl -X POST $BASE/api/v1/knowledgebase/kb-1/wiki/revert -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"slug":"entity/acme-corp","version":3}'

DELETE /api/v1/knowledgebase/:kb_id/wiki/pages/*slug ​

Назначение: удалить страницу.

Ответ: 204 No Content

bash
curl -X DELETE $BASE/api/v1/knowledgebase/kb-1/wiki/pages/overview -H "Authorization: Bearer $TOKEN"

GET /api/v1/knowledgebase/:kb_id/wiki/folders ​

Назначение: список папок. Параметры запроса: parent_id (пусто = корень), page_types (через запятую).

Ответ: 200 WikiFolderListResponse

bash
curl $BASE/api/v1/knowledgebase/kb-1/wiki/folders -H "Authorization: Bearer $TOKEN"

POST /api/v1/knowledgebase/:kb_id/wiki/folders ​

Назначение: создать папку.

ПолеТипОбязательноеОписание
namestringДаИмя папки
parent_idstringНетРодительская папка

Ответ: 201 WikiFolder

bash
curl -X POST $BASE/api/v1/knowledgebase/kb-1/wiki/folders -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"name":"Проектная документация"}'

PUT /api/v1/knowledgebase/:kb_id/wiki/folders/:folder_id ​

Назначение: переименовать/переместить папку. Тело запроса: name, parent_id, move_parent (bool), все необязательны.

Ответ: 200 WikiFolder

bash
curl -X PUT $BASE/api/v1/knowledgebase/kb-1/wiki/folders/f-1 -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"name":"Проектирование архитектуры"}'

DELETE /api/v1/knowledgebase/:kb_id/wiki/folders/:folder_id ​

Назначение: удалить папку.

Ответ: 204 No Content

bash
curl -X DELETE $BASE/api/v1/knowledgebase/kb-1/wiki/folders/f-1 -H "Authorization: Bearer $TOKEN"

GET /api/v1/knowledgebase/:kb_id/wiki/index ​

Назначение: индексная страница Wiki (окна, сгруппированные по типу). Параметры запроса: types (через запятую), limit (1–200, по умолчанию 50), cursor (курсор).

Ответ: 200 WikiIndexResponse

bash
curl $BASE/api/v1/knowledgebase/kb-1/wiki/index -H "Authorization: Bearer $TOKEN"

Удалено

GET /api/v1/knowledgebase/:kb_id/wiki/log (журнал изменений Wiki) был снят вместе с migration 000077_remove_wiki_log, таблица wiki_log_entries удалена. Теперь изменения Wiki единообразно проецируются в поток активности базы знаний — используйте GET /api/v1/knowledge-bases/:id/activity.

GET /api/v1/knowledgebase/:kb_id/wiki/graph ​

Назначение: граф связей страниц.

Параметр запросаТипОбязательныйОписание
modestringНетoverview (по умолчанию) / ego
centerstringНетslug центра в режиме ego (обязателен для ego)
depthintНет1–3, по умолчанию 1
typesstringНетФильтр по page_type
limitintНетПо умолчанию 500, максимум 2000

Ответ: 200 WikiGraphData

bash
curl "$BASE/api/v1/knowledgebase/kb-1/wiki/graph?mode=overview" -H "Authorization: Bearer $TOKEN"

GET /api/v1/knowledgebase/:kb_id/wiki/stats ​

Назначение: статистика Wiki.

Ответ: 200 WikiStats

bash
curl $BASE/api/v1/knowledgebase/kb-1/wiki/stats -H "Authorization: Bearer $TOKEN"

Назначение: поиск страниц. Параметры запроса: q (обязателен), limit (по умолчанию 10).

Семантика сопоставления зависит от диалекта хранилища:

  • Postgres: q сопоставляется как POSIX-регулярное выражение (~*, без учёта регистра).
  • SQLite / Lite: сопоставление как буквальная подстрока LIKE; % / _ экранируются и не считаются подстановочными знаками.

Ответ: 200 {"pages":[WikiPage]}

bash
curl "$BASE/api/v1/knowledgebase/kb-1/wiki/search?q=развёртывание" -H "Authorization: Bearer $TOKEN"

POST /api/v1/wiki-search ​

Назначение: поиск по страницам Wiki через несколько баз знаний (без сессии, не гибридный поиск). Handler: SearchPagesAcross в internal/handler/wiki_page.go. Алгоритм тот же, что и для одиночной базы GET .../wiki/search (заголовок > slug > summary > основной текст); после одного запроса к нескольким базам выполняется глобальное усечение по match_rank. API key: retrieve/full.

ПолеТипОбязательноеОписание
querystringДа (binding:"required")То же, что q для одиночной базы: в Postgres — POSIX-регулярное выражение (без учёта регистра); в SQLite / Lite — буквальная подстрока LIKE
knowledge_base_ids[]stringУсловно обязательныйНесколько баз; нужно указать хотя бы одно из knowledge_base_ids/knowledge_base_id, максимум 32
knowledge_base_idstringНетПоле для совместимости с одиночной базой; объединяется в ids
limitintНетГлобальный top-N, по умолчанию 10, максимум 50

Если в любой из целевых баз не включён wiki → 400. База не существует или нет права на чтение → 404. Выход за белый список API Key → 403. Недопустимое регулярное выражение (Postgres) → 400.

Ответ: 200 {"success":true,"data":[WikiSearchHit]}. Совпадение содержит только навигационные поля + match_snippet, без основного текста; полный текст — через GET /knowledgebase/:kb_id/wiki/pages/{slug}.

Поле ответаТипОписание
idstringID страницы
knowledge_base_idstringБаза-источник; при межбазовом поиске используется для сборки URL чтения страницы
slugstringslug страницы
titlestringЗаголовок
page_typestringТип страницы
aliases[]stringПсевдонимы
summarystringСводка
match_snippetstringПримерно 60 символов вокруг первого совпадения в тексте: 60+совпадение+60; при отсутствии совпадения в тексте опускается. snippet по-прежнему компилирует query как регулярное выражение Go; в SQLite, если query содержит метасимволы регулярных выражений, совпадение в базе возможно, а snippet может быть пустым

content, дерево/ссылки/метаданные и временные метки в результаты поиска не входят. Поиск по одиночной базе GET .../wiki/search по-прежнему возвращает полный WikiPage.

bash
curl -X POST $BASE/api/v1/wiki-search -H "X-API-Key: $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"query":"развёртывание|релиз","knowledge_base_ids":["kb-1","kb-2"],"limit":10}'

POST /api/v1/knowledgebase/:kb_id/wiki/rebuild-links ​

Назначение: перестроить взаимные ссылки страниц. Права на запись. Без тела запроса.

Ответ: 200 {"message":"Links rebuilt successfully"}

bash
curl -X POST $BASE/api/v1/knowledgebase/kb-1/wiki/rebuild-links -H "Authorization: Bearer $TOKEN"

GET /api/v1/knowledgebase/:kb_id/wiki/lint ​

Назначение: отчёт о проверке согласованности Wiki.

Ответ: 200 WikiLintReport

bash
curl $BASE/api/v1/knowledgebase/kb-1/wiki/lint -H "Authorization: Bearer $TOKEN"

POST /api/v1/knowledgebase/:kb_id/wiki/auto-fix ​

Назначение: автоматически исправить проблемы lint. Права на запись. Без тела запроса.

Ответ: 200 {"fixed":N,"message":"Auto-fixed N issues"}

bash
curl -X POST $BASE/api/v1/knowledgebase/kb-1/wiki/auto-fix -H "Authorization: Bearer $TOKEN"

GET /api/v1/knowledgebase/:kb_id/wiki/issues ​

Назначение: список проблем. Параметры запроса: slug (фильтр по странице), status (pending/ignored/resolved).

Ответ: 200 [WikiPageIssue]

bash
curl $BASE/api/v1/knowledgebase/kb-1/wiki/issues -H "Authorization: Bearer $TOKEN"

PUT /api/v1/knowledgebase/:kb_id/wiki/issues/:issue_id/status ​

Назначение: обновить состояние проблемы. Права на запись. Тело запроса: {"status":"pending|ignored|resolved"} (binding:"required"). issue_id должен принадлежать базе знаний из пути, иначе 404.

Ответ: 200 {"message":"Issue status updated successfully"}

bash
curl -X PUT $BASE/api/v1/knowledgebase/kb-1/wiki/issues/i-1/status -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"status":"resolved"}'

Справочник по реализации ​

Регистрация маршрутов: RegisterFAQRoutes и RegisterWikiPageRoutes в internal/router/routes_knowledge.go. Handler: internal/handler/faq.go, internal/handler/wiki_page.go.

Версия v0.8.3 · MIT License