API поиска по сайту
Те же запросы, что делает виджет. Публичный API без ключа: идентификатор сайта — uuid проекта, CORS открыт для любых доменов.
Базовый адрес: https://api.searchbooster.net/site-search/v1/sites/<uuid>
Во всех запросах можно передать область: scope — имя области из настроек, или host — хост страницы (область выберется по нему).
Настройки виджета
Заголовок раздела «Настройки виджета»GET /config?scope=&host=
{ "name": "Клиника «Здоровье»", "placeholder": "Врач, услуга или вопрос", "accent": "#0E9F6E", "suggested_questions": ["Как подготовиться к МРТ?", "Сколько стоит приём кардиолога?"], "quick_links": [{"title": "Врачи", "url": "https://clinic.ru/doctors/"}], "disclaimer": "Ответ сгенерирован ИИ по материалам сайта.", "contact_url": "https://clinic.ru/contacts/", "contact_text": "Записаться", "ask_enabled": true}Тексты области заменяют общие. Кэшируется на 5 минут.
GET /search?q=&limit=&scope=&host=
| Параметр | Что делает |
|---|---|
q |
Запрос, до 300 байт. Пробел в конце значит, что последнее слово дописано; без него последнее слово ищется и как начало слова. |
limit |
Документов в ответе, 1–30, по умолчанию 10. |
scope, host |
Область. |
{ "query": "узи щитавидной", "corrected": "узи щитовидной", "is_question": false, "results": [ { "url": "https://clinic.ru/services/uzi-thyroid/#prep", "title": "<mark>УЗИ</mark> <mark>щитовидной</mark> железы", "type": "service", "category": "УЗИ", "heading": "Подготовка", "snippet": "Специальная подготовка не нужна…", "sections": [{"heading": "Противопоказания", "url": "https://clinic.ru/services/uzi-thyroid/#contra", "snippet": "…"}], "image": "", "description": "", "attributes": {"price": "1800", "duration": "20 мин"}, "date": "2026-09-01", "pinned": false } ], "took_ms": 42, "vector": true}title,snippetи заголовки разделов — HTML: текст экранирован, найденные слова обёрнуты в<mark>. Вставляйте их как HTML.urlведёт к лучшему разделу страницы;sections— другие подходящие разделы той же страницы.corrected— запрос после исправления опечаток или раскладки, если по нему нашлись результаты: покажите «Показаны результаты по запросу …».is_question— запрос похож на вопрос, имеет смысл предложить ответ ИИ.pinned— документ закреплён правилом.vector— в выдаче участвовал поиск по смыслу.
Ответ ИИ
Заголовок раздела «Ответ ИИ»POST /ask с телом {"question": "…", "history": [{"q": "…", "a": "…"}], "scope": "", "host": ""}. Ответ — поток Server-Sent Events:
| Событие | Данные |
|---|---|
meta |
{"answer_id": "…", "sources": [{"n": 1, "title": "…", "url": "…", "type": "…", "heading": "…", "date": "…", "snippet": "…"}]} — источники приходят первыми, их можно показать сразу |
delta |
{"t": "кусок текста"} — ответ в Markdown со ссылками [1], [2] на sources[n] |
reset |
{} — забудьте полученный текст, ответ начинается заново |
followups |
{"items": ["…", "…"]} — вопросы для продолжения |
error |
{"message": "…"} |
done |
{"found": true, "took_ms": 3100} — found: false, если ответа в материалах сайта нет |
history — предыдущие пары «вопрос — ответ» диалога, учитываются последние три. Короткий уточняющий вопрос («а для детей?») ищется вместе с прошлым вопросом.
const res = await fetch(`${base}/ask`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ question: 'Как подготовиться к МРТ?' }),});const reader = res.body.pipeThrough(new TextDecoderStream()).getReader();let buf = '';for (;;) { const { value, done } = await reader.read(); if (done) break; buf += value; let i; while ((i = buf.indexOf('\n\n')) >= 0) { const block = buf.slice(0, i); buf = buf.slice(i + 2); const event = /^event: (.*)$/m.exec(block)?.[1]; const data = JSON.parse(/^data: (.*)$/m.exec(block)?.[1] ?? '{}'); if (event === 'delta') answer.textContent += data.t; }}Оценка ответа
Заголовок раздела «Оценка ответа»POST /feedback с телом {"answer_id": "…", "vote": 1, "comment": ""} — vote 1 или -1. Ответ 204.
События
Заголовок раздела «События»POST /events с телом {"event": "click", "query": "…", "url": "…", "position": 1, "answer_id": "", "mode": "search"}. Ответ 204. Нужны для статистики поиска по сайту.
| Код | Когда |
|---|---|
400 |
Неизвестная область, неверный JSON. |
404 |
Поиск по сайту для проекта не включён или ещё не проиндексирован. |
429 |
Превышен лимит ответов ИИ. |
502 |
Поиск временно недоступен, повторите запрос. |