# Стартовые подсказки

Получите персональные кнопки для welcome-экрана до первого сообщения покупателя. API выбирает пять подсказок из подготовленного набора секции с учётом страницы, времени и доступных сведений о покупателе. Если в секции отключена память между диалогами, прошлые разговоры для подбора не используются.

Подключение и набор подсказок согласуйте с командой Gravity Field. Вызов этого метода и отображение кнопок реализует ваш клиентский канал; готовый Web-виджет не подключает метод автоматически. Подсказки после ответа ассистента приходят отдельно — в `response.ui.suggests` метода [генерации](generate.md).

## Запрос

### `POST /shopping/starter-prompts`

Метод требует `Authorization: Bearer gst_...`. Сначала получите или используйте сохранённый [гостевой токен](guest_sessions.md). Секцию и пользователя сервер определяет по токену. Статический API-ключ его не заменяет.

Переменная `GUEST_ACCESS_TOKEN` в примере содержит полный токен сохранённой гостевой сессии:

```bash
curl --request POST \
  --url 'https://shopping-assistant-api.gravityfield.ai/shopping/starter-prompts' \
  --header 'Content-Type: application/json' \
  --header "Authorization: Bearer $GUEST_ACCESS_TOKEN" \
  --data '{
    "ctx": {
      "type": "CATEGORY",
      "data": ["Сыры"],
      "lng": "10"
    }
  }'
```

Передавайте актуальный [контекст страницы API V2](/Integration/api_integration/v2/context.md), согласованный с `/visit` и `/choose`. Категория и код зоны обслуживания в примере условные; замените их значениями вашей интеграции.

| Поле | Обязательное | Назначение |
| --- | --- | --- |
| `ctx` | Нет | Объект контекста страницы. Можно опустить или передать `null`; тело `{}` также допустимо. |
| `ctx.type` | Нет | Строка до 100 символов: `HOMEPAGE`, `PRODUCT`, `CART`, `CATEGORY`, `SEARCH`, `OTHER`. Неизвестный или отсутствующий тип обрабатывается как `OTHER`. |
| `ctx.data` | Нет | Данные страницы: SKU товара, категории, поисковый запрос или SKU корзины по правилам API V2. На `PRODUCT` передавайте SKU текущего товара первым элементом массива. |
| `ctx.lng` | Нет | Строка до 100 символов или `null`: согласованный код зоны обслуживания для фида и поиска. |
| `ctx.location` | Нет | Строка до 500 символов или `null`: URL страницы или идентификатор экрана. |

Дополнительные поля внутри `ctx` допускаются. Сериализованный объект `ctx` не должен превышать 32 000 символов. На верхнем уровне разрешён только `ctx`: не передавайте `tenant_id`, `tenantId`, `resourceId`, `threadId`, `messages` или `runtimeContext`.

Запрос не создаёт диалог и не отправляет сообщение ассистенту. Для его выполнения не нужен `threadId`. История для подбора ограничена текущей гостевой сессией: сессии одного UID не объединяются.

## Ответ

При успешном подборе API возвращает `200 OK` и ровно пять уникальных подсказок. Ниже пример формы ответа; тексты и порядок зависят от набора секции и контекста:

```json
{
  "enabled": true,
  "selectionId": "7a7726c4-6ff9-4efc-b892-21378916c84e",
  "promptSetVersion": 4,
  "prompts": [
    { "id": "home_by_list", "text": "Подбери товары по моему списку" },
    { "id": "weekly_basket", "text": "Подбери продукты на неделю" },
    { "id": "dinner_recipe", "text": "Что приготовить на ужин" },
    { "id": "breakfast", "text": "Что взять на завтрак" },
    { "id": "cleaning", "text": "Товары для уборки" }
  ]
}
```

| Поле | Назначение |
| --- | --- |
| `enabled` | Включён ли набор подсказок для секции. Значение `true` само по себе не означает успешный подбор. |
| `selectionId` | ID конкретного подбора. Возвращается при `enabled: true`. |
| `promptSetVersion` | Версия набора подсказок секции. Возвращается при `enabled: true`. |
| `prompts` | Пять выбранных подсказок в порядке отображения либо пустой массив, если подбор не выполнен. |
| `prompts[].id` | ID подсказки в наборе. Не заменяет текст пользовательского сообщения. |
| `prompts[].text` | Текст кнопки и сообщения, которое отправляется после нажатия. |

Если набор для секции не включён, ответ содержит только:

```json
{ "enabled": false }
```

Если набор включён, но подбор не выполнен, например из-за таймаута или ошибки модели, API также возвращает `200 OK`:

```json
{
  "enabled": true,
  "selectionId": "7a7726c4-6ff9-4efc-b892-21378916c84e",
  "promptSetVersion": 4,
  "prompts": []
}
```

Сервер не подставляет резервные подсказки. Причина недоступности, оценки уместности, память покупателя и история в публичный ответ не входят. Ошибки авторизации и неверный запрос возвращаются отдельными HTTP-ошибками, а не пустым успешным ответом.

Ответы используют `Cache-Control: no-store`. Не помещайте персональные подсказки в общий или публичный кеш.

## Отображение и нажатие

1. При открытии welcome-экрана вызовите метод с сохранённым гостевым токеном и актуальным `ctx`.
2. При `enabled: true` и непустом `prompts` покажите пять кнопок в порядке ответа. При `enabled: false`, пустом массиве или сетевой ошибке используйте собственные статические подсказки из вариации кампании или настроек UI. Обрабатывайте ошибки токена по [правилам восстановления сессии](guest_sessions.md#восстановление-после-потери-или-истечения-токена).
3. При смене страницы или гостевой сессии отмените прежний запрос либо игнорируйте его поздний ответ, чтобы не показать подсказки из старого контекста.
4. После нажатия отправьте выбранный `text` как обычное новое сообщение в [`POST /shopping/generate`](generate.md) с тем же гостевым токеном, внешним `resourceId` и актуальным на момент нажатия контекстом. Для нового разговора создайте `threadId`; для продолжения сохраните существующий.

Пример тела генерации после нажатия первой кнопки. Замените `demo-section` и `USER_UID` значениями сохранённой сессии, создайте свои ID диалога и сообщения:

```json
{
  "threadId": "thread-8f2b1c",
  "resourceId": "USER_UID",
  "messages": [
    {
      "id": "message-1001",
      "role": "user",
      "content": "Подбери товары по моему списку"
    }
  ],
  "runtimeContext": {
    "tenant_id": "demo-section",
    "ctx": { "type": "CATEGORY", "data": ["Сыры"], "lng": "10" }
  }
}
```

Не добавляйте `selectionId`, `promptSetVersion` или ID подсказки в тело генерации. События диалога передавайте по [общим правилам трекинга](../tracking.md); сам факт подбора не означает показ кнопок или нажатие.

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

| HTTP | Причина | Что делать клиенту |
| --- | --- | --- |
| `400` | `INVALID_REQUEST` — некорректный JSON, лишние поля верхнего уровня или превышены ограничения `ctx`. | Исправить тело запроса. |
| `401` | `INVALID_GUEST_TOKEN` — токен отсутствует, неверен, истёк или отозван. | Проверить заголовок и восстановить сессию по правилам гостевых токенов. |
| `403` | IP не разрешён для секции. | Проверить условия подключения с командой Gravity Field. |
| `405` | Метод не поддерживается. | Использовать `POST`. |
| `503` | `AUTH_STORAGE_UNAVAILABLE` — сервис не смог проверить доступ. | Сохранить текущую сессию и повторить запрос позже. |

CORS допускает заголовок `Authorization`; запросы `OPTIONS` не требуют токена. Ошибка подбора не должна мешать покупателю написать сообщение вручную или выбрать статическую подсказку.
