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

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

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

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

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" для разных покупателей.

Текущий метод выдаёт токен только до первого использования этого resourceId в Shopping Assistant. Если ресурс уже зарегистрирован или для него существует история, API возвращает 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 созданной сессии. Не заменяет токен в запросах.
accessToken Секретный токен. Возвращается только при регистрации.
tokenType Схема передачи токена: Bearer.
resourceId Идентификатор, переданный при регистрации.
expiresAt Срок действия на момент создания сессии, в ISO 8601.

Сохраните accessToken вместе с 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/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 нет.

Если токен потерян, истёк или отозван, текущий метод не позволяет получить новый токен для того же resourceId. Покажите в интерфейсе, что сессия недоступна. Не меняйте user.uid, user.custom или resourceId ради повторной регистрации: идентификация должна оставаться общей с Gravity Field.

Отзыв токена

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.

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

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

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

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

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