AACSearch / руководство
API-ключи, области доступа, ограничения и кредиты
Как выбрать ключ, что может браузерный ключ и как оплачиваются операции AI.
Каждый запрос к API арендатора содержит API-ключ организации в заголовке
X-NOVA-API-KEY. У ключа одна из двух областей доступа (scope).
Полные ключи
Полный ключ открывает доступ ко всем операциям из справочника API и должен храниться на вашем сервере: индексация и импорт документов, настройка коллекций, синонимов, курирования, поисковых правил, моделей рекомендаций и ассистентов, чтение аналитики, загрузка медиафайлов, генерация эмбеддингов.
Поисковые ключи — ключи для браузера
Поисковый ключ предназначен для размещения на странице витрины магазина, в мобильном
приложении или в виджете. Он даёт доступ только к операциям, отмеченным в контракте как
x-nova-key-scope: search:
| Операция | Что посетитель делает с её помощью |
|---|---|
searchCollection, multiSearch | поиск, автодополнение, фасеты |
getRecommendations | похожие товары, популярное, «для вас» |
ingestEvents | события поиска, клика, добавления в корзину и покупки |
searchSemantic | «похожее по смыслу», когда поиск по ключевым словам ничего не нашёл |
searchByImage | поиск по фото |
createTranscription, searchByVoice | голосовой ввод |
createChatCompletion, streamChatCompletion | ассистент поддержки |
getConversation, deleteConversation | собственный диалог посетителя |
suggestQueries, presearchQueries | подсказки при вводе и до начала ввода |
createSupportThread, getSupportThread, createSupportMessage | собственное обращение посетителя в поддержку |
listGraphEntities | чтение графа сущностей каталога |
getSearchProfileView | безопасная для браузера проекция профиля поиска (сорты, фасеты, сорт по умолчанию, потолок размера страницы) |
ingestAnalyticsEvents | пакет событий поиска/клика/конверсии фиксированной формы для непроверенных браузерных клиентов |
На всё остальное API отвечает 403. Поисковый ключ не может записывать документы, а также
читать или изменять конфигурацию, поэтому худшее, что можно сделать со скопированным ключом, — выполнять поиск.
Заголовок сессии
Браузерные клиенты передают X-NOVA-SESSION-ID — один идентификатор на вкладку браузера.
Именно он связывает события посетителя для аналитики и A/B-тестов, определяет, к какой сессии
относится диалог, и служит основой для учёта лимита AI-операций поискового ключа.
При работе с поисковым ключом AI-операции требуют этот заголовок (без него — 400); диалог,
начатый в одной сессии, нельзя прочитать или продолжить из другой
(403). Пакеты aacsearch-ui и облегчённый виджет передают его автоматически.
Ограничения ключа
Область доступа определяет, какие операции доступны ключу; ограничения — какие данные он видит. Ограничения можно задать для любого ключа, полного или поискового: при создании ключа в консоли или позже через действие Ограничения у ключа. Пустое ограничение означает отсутствие ограничения.
| Ограничение | Что ограничивает | Ответ при нарушении |
|---|---|---|
allowedCollections | Коллекции, к которым ключ может обращаться. Операции без коллекции (health, ключи) регулируются только областью доступа | 403 |
forcedFilterBy | Фрагмент filter_by для каждой коллекции или под * для всех коллекций, который через AND добавляется к каждому поиску: контроль доступа на уровне документов. Если у коллекции есть своя запись и есть *, применяются обе | — (сужает выдачу) |
allowedFields | Доступ на уровне полей. include_fields сокращается до разрешённых полей (если запрошенные поля все запрещены, возвращается только id). Запрос, где в query_by, facet_by, sort_by, group_by, highlight_fields, include_fields, exclude_fields или filter_by указано другое поле, отклоняется, а не переписывается молча. address разрешает и address.city; id и виртуальные поля с префиксом _ разрешены всегда | 400 |
allowedIps | IPv4/IPv6-адреса или диапазоны CIDR, с которых можно использовать ключ | 403 |
allowedOrigins | Origin страниц, scheme://host[:port], *.example.com — для всех поддоменов. Проверяется Origin, затем Referer; запрос без обоих заголовков отклоняется, поэтому не задавайте это ограничение ключу, которым пользуется и ваш сервер | 403 |
rateLimitPerMinute | Запросов в минуту для этого ключа | 429 с Retry-After |
Принудительный фильтр всегда объединяется через AND с собственным filter_by вызывающего
и никогда им не заменяется:
// ключ: forcedFilterBy = { "products": "tenant_id:=42" }
GET /v1/collections/products/documents/search?q=drill&filter_by=in_stock:=true
// движок получает
filter_by=(in_stock:=true) && (tenant_id:=42)Ограничения применяются до поисковых правил и A/B-экспериментов, поэтому те могут только сузить ограниченный поиск, но не расширить его.
Где они действуют
Не только в обычном searchCollection. Те же проверки выполняются на каждом пути чтения,
который возвращает документы:
multiSearch: каждый элемент проверяется по своей коллекции; один элемент с запрещённой коллекцией отклоняет весь пакет с403.- Ассистент (
createChatCompletion,streamChatCompletion): запрещённые коллекции исключаются из поиска контекста (403, если не осталось ни одной), а источники из предыдущих ходов перепроверяются по текущему ключу. getRecommendations,suggestQueriesиpresearchQueries.searchSemantic,searchByImageиsearchByVoice.
Защищённые (дочерние) ключи
Браузерный ключ, выпущенный через createBrowserKey (POST /browser-keys, см.
ключи виджета), — это подписанный токен nssk_…, производный от
родительского полного ключа и нигде не хранящийся. Он принимает allowed_collections,
allowed_origins, rate_limit_per_minute, user_token и expires_in_seconds (не более
семи дней), ограничен областью search, а ограничения родителя продолжают действовать.
Они объединяются так, что дочерний ключ может только сузить родителя:
- Коллекции и поля пересекаются. Списки без общих элементов запрещают всё и никогда не превращаются в «без ограничений».
- Принудительные фильтры объединяются по каждой коллекции (и по
*): если оба ключа задают одну запись, фрагмент дочернего ключа добавляется к родительскому через AND — дочерний ключ может добавить фильтр, но не заменить его. - Лимит запросов: действует меньший из двух.
- Origin и IP: список, заданный дочерним ключом, используется вместо родительского; иначе действует родительский.
Отзыв или ротация родительского ключа делает недействительными все производные от него ключи.
Кредиты: как оплачиваются операции AI
У вашей организации есть кошелёк кредитов (1 кредит = 1 минимальная денежная единица). Каждый вызов модели оплачивается из него, независимо от того, каким ключом выполнен запрос: платформа запускает модели с собственными ключами провайдеров и списывает с вас кредиты:
| Операция | Что тарифицируется |
|---|---|
| Ход ассистента | входящие и исходящие токены |
| Транскрибация, голосовой поиск | минуты аудио |
Семантический поиск, POST /embeddings | векторизованные тексты |
| Поиск по изображению | векторизованные изображения |
| Подсказки синонимов (speller) | запросы, отправленные модели |
Извлечение сущностей и утверждений графа (generateGraphEntities) | обработанные документы |
Отчёты сообществ графа (generateGraphCommunities) | сообщества, для которых написан summary |
Поиск по графу (globalSearchGraph, driftSearchGraph) | вызовы модели — обработанные отчёты сообществ, отвеченные уточняющие вопросы DRIFT, плюс один reduce-вызов |
Перед запуском модели стоимость оценивается и резервируется; после завершения
списывается фактическая стоимость, а остаток резерва освобождается. Если кошелёк
не покрывает резерв, API отвечает 402 с указанием доступной и необходимой суммы.
Неудачный вызов модели ничего не стоит. Каждое списание — это запись в журнале операций,
которую можно просмотреть в консоли; она называется по имени операции (assistant.chat,
voice.transcription, search.image, …).
Кошелёк новой организации открывается с небольшим пробным балансом; тарифы добавляют включённые в них кредиты при активации, а пополнить кошелёк можно в любой момент.
Квоты и лимиты
Запросы учитываются в месячной квоте тарифа (429, когда она исчерпана).
Поскольку поисковый ключ размещается в браузере и может быть оттуда скопирован,
AI-операции, выполненные с ним, дополнительно ограничены для каждой сессии посетителя —
фиксированным числом в минуту, после чего API отвечает 429 со значением
retry_after. Полные ключи принадлежат серверу и так не ограничиваются.
Ответы с ошибками
Для каждой операции документированы 401 (ключ отсутствует или отозван), 403 (область доступа) и
429 (квота или лимит); операции, тарифицируемые в кредитах, также возвращают 402.
Сгенерированные SDK выбрасывают для каждого случая типизированную ошибку — UnauthorizedError,
ForbiddenError, PaymentRequiredError, TooManyRequestsError, — поэтому
витрина магазина может показать «ассистент недоступен» вместо трассировки стека.
Семантический, фото- и голосовой поиск
Поиск по смыслу на любом языке, поиск документа по фотографии, поиск голосом, встраивание текста и хранение изображений с подписанными ссылками.
Тарифы, потребление и кредиты
Что даёт каждый тариф, как считаются запросы, что такое ИИ-кредит и сколько он стоит, как работают платежи в рублях, продление и что происходит при достижении лимита.