Гостевые токены

Гостевой токен используется в запросах Shopping Assistant для конкретной секции и пользователя Gravity Field. В resourceId передавайте user.uid, а если ваша интеграция использует user.custom — его значение. Клиент регистрирует гостевую сессию с этим идентификатором, сохраняет токен, затем передаёт его в заголовке Authorization.

История и память ассистента принадлежат гостевой сессии. Один resourceId может использоваться в нескольких независимых сессиях: каждая получает свой токен и видит только свои диалоги. Для обращения к гостевой истории передавайте токен её сессии. Гостевой токен не подтверждает вход покупателя в аккаунт магазина.

В готовом Web-виджете 1.42 включите auth: { mode: 'guest' }: регистрацию, сохранение и передачу токена выполняет сам виджет. Для продолжения разговора между страницами и списка диалогов нужны отдельные настройки. Пример подключения: Web-интеграция, поведение при истечении сессии: Web-виджет.

Получение токена

POST /shopping/guest-sessions

Перед первым запросом генерации получите идентификатор пользователя через базовую интеграцию Gravity Field API V2. Используйте тот же идентификатор в Shopping Assistant:

Идентификация в Gravity Field Значение resourceId
Через user.uid Значение user.uid, полученное от Gravity Field. В Web — GF.userData.uid.
Через user.custom Внешний ID, который ваша интеграция передаёт в user.custom. В запросах API V2 продолжайте передавать и user.ses.

Сохраняйте выбранный способ идентификации при регистрации токена и во всех последующих запросах ассистента. Не создавайте отдельный UUID для Shopping Assistant и не используйте общую заглушку вроде "api request" для разных покупателей.

Каждый успешный вызов создаёт новую сессию и возвращает 201 Created с новым sessionId и токеном. Регистрироваться можно с тем же resourceId, даже если для него уже есть гостевые сессии или история без токена. Такая регистрация не возвращает 409 RESOURCE_ALREADY_EXISTS из-за существующей истории.

Новая сессия начинает с пустой истории и памяти ассистента. Прежние диалоги и предпочтения в неё не переносятся. Действующие токены других сессий сохраняют доступ к своим данным; новая регистрация не отзывает их и не закрывает их публичные ссылки.

В примере ниже замените demo-section на ID подключённой секции, а USER_UID — на user.uid или используемый в вашей интеграции user.custom.

curl --request POST \
  --url 'https://shopping-assistant-api.gravityfield.ai/shopping/guest-sessions' \
  --header 'Content-Type: application/json' \
  --data '{
    "tenant_id": "demo-section",
    "resourceId": "USER_UID"
  }'
Поле Обязательное Назначение
tenant_id Да ID секции, для которой подключён Shopping Assistant.
resourceId Да user.uid Gravity Field или значение user.custom, если интеграция использует внешний ID.

Оба поля — непустые строки длиной до 512 символов. Дополнительные поля не принимаются. Для регистрации действуют IP-ограничения секции.

Ответ

API возвращает 201 Created и Cache-Control: no-store:

{
  "sessionId": "c7cf5ab3-49e0-4425-9ef3-0d68c29ee739",
  "accessToken": "gst_...",
  "tokenType": "Bearer",
  "resourceId": "USER_UID",
  "expiresAt": "2026-11-15T10:00:00.000Z"
}

Значение accessToken в примере сокращено. Настоящий токен состоит из префикса gst_ и 43 символов Base64url.

Поле Назначение
sessionId ID созданной сессии. Сохраняйте вместе с токеном и привязывайте к нему локальные threadId. В запросах используется токен.
accessToken Секретный токен. Возвращается только при регистрации.
tokenType Схема передачи токена: Bearer.
resourceId Идентификатор, переданный при регистрации.
expiresAt Срок действия на момент создания сессии, в ISO 8601.

Сохраните accessToken и sessionId вместе с resourceId и ID секции. Используйте сохранённую сессию при переходах между страницами и повторной инициализации виджета. Параллельные запросы должны ожидать одну регистрацию: каждый дополнительный вызов создаст отдельную пустую сессию. Не записывайте токен в URL, аналитику, error tracking или прикладные логи.

Передача токена

В последующих запросах сохраняйте зарегистрированный resourceId и добавляйте заголовок:

Authorization: Bearer gst_...

В примере генерации переменная окружения GUEST_ACCESS_TOKEN содержит полное значение accessToken из ответа регистрации. Используйте свою секцию и зарегистрированный resourceId:

curl --request POST \
  --url 'https://shopping-assistant-api.gravityfield.ai/shopping/generate' \
  --header 'Content-Type: application/json' \
  --header "Authorization: Bearer $GUEST_ACCESS_TOKEN" \
  --data '{
    "resourceId": "USER_UID",
    "threadId": "thread-8f2b1c",
    "trafficType": "test",
    "messages": [
      {
        "id": "message-1001",
        "role": "user",
        "content": "Помогите выбрать корм для взрослой кошки"
      }
    ],
    "runtimeContext": {
      "tenant_id": "demo-section"
    }
  }'

При работе с гостевой сессией токен требуется в следующих методах:

Метод Контракт
POST /shopping/starter-prompts Стартовые подсказки
POST /shopping/generate, включая debug-режим и повтор запроса Генерация ответа
POST /shopping/history История диалога
GET /shopping/dialogs и DELETE /shopping/dialogs/{threadId} Список и скрытие диалогов
GET /shopping/feedback и PUT /shopping/feedback Оценка ответа
POST /dialogs/share и POST /dialogs/share/revoke Шаринг диалогов

Для оценки в гостевой интеграции используйте PUT с заголовком Authorization. Обычный переход по GET-ссылке не передаёт этот заголовок. Не добавляйте токен в query-параметры. В API шаринга user_id должен совпадать с зарегистрированным resourceId; tenant_id в тело запроса не добавляют.

Чтение публичной копии через GET /dialogs/shared/{share_token} использует отдельный share_token и не требует гостевого токена. Ключ API V2 также не заменяет гостевой токен.

Срок действия

Сессия действует 30 дней бездействия. После успешного авторизованного обращения сервер пытается продлить её ещё на 30 дней. Ошибочные запросы срок не продлевают; истёкшая или отозванная сессия не возобновляется. Поле expiresAt из ответа регистрации содержит первоначальный срок, а не обновляемую дату. Отдельного refresh token нет.

Восстановление после потери или истечения токена

Если токен потерян или API вернул 401 INVALID_GUEST_TOKEN:

  1. Очистите сохранённые токен, sessionId, идентификаторы диалогов и локальную переписку прежней сессии.
  2. Зарегистрируйтесь через POST /shopping/guest-sessions с тем же resourceId. Не меняйте user.uid или используемый user.custom Gravity Field.
  3. Сохраните новые sessionId и токен, создайте новый threadId и начните новый разговор.

Повторная регистрация создаёт новую пустую сессию, а не восстанавливает прежнюю. Не отправляйте в неё старую историю и сообщения повторно. Если прежний токен ещё действителен и сохранён, используйте его для продолжения прежнего диалога.

Храните активный threadId вместе с sessionId. Токен другой сессии не откроет старый диалог, даже если resourceId совпадает: API вернёт 404. На разных origin браузера, например www и без www, могут храниться независимые сессии одного UID.

При 401 GUEST_TOKEN_REQUIRED сначала проверьте, что сохранённый токен добавлен в запрос, вместо создания новой сессии. Ошибки 403, 404 и 503 сами по себе не требуют повторной регистрации.

Отзыв токена

POST /shopping/guest-sessions/revoke

Передайте текущий гостевой токен в заголовке. Тело запроса не требуется:

curl --request POST \
  --url 'https://shopping-assistant-api.gravityfield.ai/shopping/guest-sessions/revoke' \
  --header "Authorization: Bearer $GUEST_ACCESS_TOKEN"

API возвращает 204 No Content. Повторный отзыв того же известного токена, в том числе истёкшего, также возвращает 204. Отсутствующий или неизвестный токен возвращает 401 INVALID_GUEST_TOKEN.

Отзыв действует только на предъявленный токен. Другие сессии того же resourceId продолжают работать, а история отозванной сессии не становится доступной без токена. Для нового разговора можно зарегистрировать новую сессию с тем же resourceId.

Отзыв гостевого токена не отзывает ранее созданные публичные ссылки — для них предусмотрен отдельный метод отзыва.

Совместимость с интеграциями без токена

При подключении гостевого режима сохраните resourceId Gravity Field, очистите локальные ID диалогов и переписку прежнего режима, зарегистрируйте сессию и начните новый разговор. Существующая история без токена не импортируется в гостевую сессию. Если клиент запомнил отказ 409 от прежней версии API, снимите эту блокировку и повторите регистрацию.

Новая регистрация не блокирует обращения без токена для внешнего UID. Такие запросы используют отдельную историю и не получают доступ к данным гостевых сессий. UID, защищённые прежней версией API, сохраняют требование токена: ранее выданные действующие токены продолжают открывать свои диалоги.

Ошибки и ограничения

HTTP Причина Что делать клиенту
400 Invalid request body — неверные поля регистрации; Unknown tenant — неизвестная секция. Проверить ID секции и тело запроса.
401 GUEST_TOKEN_REQUIRED — запрос без токена к UID, защищённому прежней версией API. Проверить, что сохранённый токен добавлен в заголовок. Не сбрасывать сессию из-за пропущенного заголовка.
401 INVALID_GUEST_TOKEN — токен некорректен, неизвестен, истёк или отозван. Выполнить восстановление сессии с тем же resourceId.
403 GUEST_RESOURCE_MISMATCH — токен относится к другой секции или ресурсу; IP_NOT_ALLOWED — IP не разрешён для секции. Проверить идентификаторы и условия подключения. Не создавать новую сессию автоматически.
404 Диалог отсутствует, скрыт или принадлежит другой сессии, в том числе с тем же resourceId. Проверить threadId и его связь с сохранённым sessionId. Не менять сессию автоматически.
429 Превышен лимит регистрации. Подождать число секунд из заголовка Retry-After.
503 AUTH_STORAGE_UNAVAILABLE — сервис не смог проверить или сохранить сессию. Сохранить текущую сессию и предложить повторить позже.

Регистрация ограничена 20 попытками в минуту с одного IP на экземпляр сервиса. CORS разрешает заголовок Authorization; запросы OPTIONS не требуют токена. Ответы используют Cache-Control: no-store.

Ошибки 403, 404 и 503 сами по себе не требуют замены токена. После сетевой ошибки не повторяйте генерацию автоматически: результат мог уже сохраниться. Для повтора того же сообщения соблюдайте правила повторных запросов.