# ТутОтвет API: инструкция для нейросети

Ты подключён к сервису ТутОтвет (lk.tutotvet.ru). Он собирает отзывы покупателей магазина с Wildberries, Ozon и
Яндекс Маркета и публикует ответы на них. Через этот API ты можешь читать отзывы, отвечать на них от имени
продавца и включать или выключать правила автоответов.

## Подключение

- Адрес: `https://lk.tutotvet.ru/api/v1`
- Ключ передаётся в каждом запросе заголовком `Authorization: Bearer tt_...`. Ключ выдаёт владелец магазина в
  кабинете: Настройки - API и нейросети. Никому не показывай ключ и не вставляй его в ответы покупателям.
- Ключ действует для одной организации (магазина) или для всех организаций владельца. У каждого отзыва и правила
  есть `org_id` и `org_name`; список организаций ключа - в `GET /me`. Параметр `org` в списках оставляет только одну
  организацию. Отвечать и менять правила можно по `mp` и `id` - организацию сервис найдёт сам.
- Есть и MCP-сервер с теми же возможностями: `https://lk.tutotvet.ru/mcp` (Streamable HTTP, тот же заголовок
  Authorization). Если ты подключён через MCP, пользуйся его инструментами вместо HTTP-запросов.
- Данные - JSON в UTF-8. Для POST добавь `Content-Type: application/json`.
- Не больше 120 запросов в минуту. При ответе 429 подожди минуту.
- Полное описание методов (OpenAPI): `https://lk.tutotvet.ru/api/v1/openapi.json`

## Методы

| Метод | Право ключа | Что делает |
|---|---|---|
| `GET /me` | read | организации ключа: подключённые маркетплейсы, остаток тарифа |
| `GET /reviews` | read | список отзывов |
| `GET /reviews/{mp}/{id}` | read | один отзыв |
| `POST /reviews/{mp}/{id}/answer` | answer | опубликовать ответ `{"text": "..."}` |
| `POST /reviews/{mp}/{id}/reject` | answer | не отвечать на черновик модерации |
| `POST /reviews/{mp}/{id}/regenerate` | answer | нейросеть ТутОтвет переписывает черновик `{"wish": "короче"}` |
| `GET /stats` | read | сводка за период: ответы, средняя оценка, без ответа, модерация |
| `GET /history` | read | история: отвечено ботом и без ответа с причинами (все способы подключения) |
| `GET /billing` | read | баланс, тарифы и остатки, автопродление, последние операции |
| `GET /insights/{mp}` | read | анализ отзывов за 30 дней: виды отзывов, темы, кто на них отвечает |
| `POST /insights/{mp}/run` | rules | обновить анализ (до минуты) |
| `POST /insights/{mp}/quick-setup` | rules | создать правила на все виды отзывов без правила `{"moderation": true}` |
| `GET /rules` | read | правила автоответов (кратко) |
| `GET /rules/{mp}/{id}` | read | правило целиком: шаблоны, стоп-слова, белый список, артикулы |
| `GET /rules/examples` | read | готовые фразы по блокам |
| `POST /rules/{mp}` | rules | создать правило |
| `POST /rules/{mp}/{id}` | rules | изменить правило: только переданные поля |
| `POST /rules/{mp}/{id}/delete` | rules | удалить правило |
| `POST /rules/{mp}/{id}/copy` | rules | копия `{"mp": "ozon", "org": 123}` |
| `POST /rules/{mp}/{id}/active` | rules | включить или выключить `{"active": true}` |
| `POST /settings/{mp}/option` | rules | WB: не отвечать на возвраты; Ozon: на отменённые заказы `{"value": true}` |
| `GET /billing/price` | read | цена пакета ответов (`template`, `neuro` - из `grades` в `/billing`) |
| `POST /billing/order` | billing | подключить тариф с баланса `{"marketplaces": ["wb"], "template": 500, "neuro": 100}` |
| `POST /billing/tariffs/{id}/prolongation` | billing | автопродление тарифа `{"on": true}` |
| `POST /billing/trial` | billing | бесплатный период `{"mp": "ozon"}` |
| `POST /billing/promo/check`, `/billing/promo/redeem` | billing | личный промокод `{"code": "TT-XXXXXX"}` |
| `POST /billing/pay` | billing | ссылка на оплату картой `{"amount": "1000", "email": "..."}` - платит человек |
| `POST /billing/invoice` | billing | счёт для юрлица по реквизитам из профиля `{"amount": 10000, "email": "..."}` |

Если в ключе несколько организаций, для `stats`, `history`, `billing`, `insights`, `settings` и создания правила
передайте `org` (id из `/me`).

`mp` - маркетплейс: `wb` (Wildberries), `ozon` (Ozon), `ym` (Яндекс Маркет).

### GET /reviews

Параметры:
- `status` - какие отзывы нужны (по умолчанию `needs_answer`):
  - `needs_answer` - ждут ответа: черновики на модерации, сбои публикации и отзывы, на которые бот не ответил;
  - `unanswered` - только отзывы, на которые бот не ответил и которые сейчас ждут ответа на маркетплейсе (поле
    `reason` объясняет почему, например «Нет подходящего правила»). Отзыв, на который ответили в кабинете маркетплейса
    или который пометили обработанным, получает статус `left_queue` и в этот список не попадает;
  - `moderation` - бот подготовил черновик ответа (поле `answer`) и ждёт решения;
  - `failed` - ответ не опубликовался (поле `error`);
  - `sending` - ответ принят и будет опубликован в ближайшие 10-15 минут;
  - `published` - ответ опубликован;
  - `all` - все.
- `mp` - только один маркетплейс.
- `org` - только одна организация (id из `/me`).
- `limit` - сколько отзывов (1-200, по умолчанию 50).
- `before` - для следующей страницы передай значение `next_before` из предыдущего ответа.

Пример ответа:

```json
{
  "reviews": [
    {
      "mp": "wb", "id": "Hx7...", "org_id": 501, "org_name": "Автохимия", "rating": 2, "text": "Пришёл с трещиной на крышке",
      "product": "Шампунь для авто 1 л", "sku": "123456789", "author": "Анна",
      "created": "2026-10-30T12:15:00+03:00", "status": "unanswered",
      "answer": null, "reason": "Нет подходящего правила", "rule": null,
      "photos": 1, "videos": 0, "link": "https://www.wildberries.ru/catalog/123456789/detail.aspx"
    }
  ],
  "next_before": null
}
```

Поле `answer` у статуса `moderation` - черновик, который подготовил ТутОтвет. Его можно одобрить как есть
(отправить тот же текст в `/answer`), улучшить или заменить своим.

### POST /reviews/{mp}/{id}/answer

```
POST https://lk.tutotvet.ru/api/v1/reviews/wb/Hx7.../answer
Authorization: Bearer tt_...
Content-Type: application/json

{"text": "Анна, здравствуйте! Очень жаль, что флакон пришёл повреждённым..."}
```

Ответ: `{"ok": true, "review": {..., "status": "sending"}, "message": "...", "warning": null}`. Бот опубликует
ответ на маркетплейсе в течение 10-15 минут; после этого статус станет `published`. Если в `warning` написано, что
тариф закончился, ответ уйдёт после продления тарифа - сообщи об этом владельцу.

Ошибки:
- 401 - нет ключа или ключ отозван; 403 - у ключа нет нужного права;
- 404 - отзыв не найден; 409 - на отзыв уже ответили или ответ уже отправляется;
- 422 - текст не прошёл проверку (причина в поле `detail`), исправь текст и отправь снова;
- 429 - слишком много запросов, подожди минуту.

## Как отвечать на отзывы

1. Раз в 15-30 минут (или когда попросит владелец) запроси `GET /reviews?status=needs_answer`.
2. Для каждого отзыва напиши ответ и отправь `POST /reviews/{mp}/{id}/answer`. Если отвечать не нужно (спам,
   отзыв не о товаре), у черновика модерации вызови `/reject`, остальные просто пропусти.
3. Отвечай на каждый отзыв один раз. Отзыв со статусом `sending` или `published` больше не трогай.

Правила текста ответа (маркетплейсы штрафуют за нарушения, сервис часть из них проверяет сам):
- без ссылок, адресов почты, телефонов и названий чужих магазинов и сайтов - такой ответ API не примет;
- не используй длинное тире (сервис заменит его дефисом);
- обращайся к покупателю по имени, если оно есть в поле `author` (у Ozon имени нет - пиши без имени);
- пиши по существу отзыва: поблагодари за хороший отзыв, на жалобу - извинись, объясни и предложи решение;
  не спорь с покупателем и не обвиняй его;
- не обещай того, что продавец не подтвердил: возвраты, компенсации, сроки;
- не пиши, что ответ подготовлен нейросетью;
- длина - обычно 2-5 предложений, не больше 3000 символов;
- учитывай пожелания владельца магазина к тону и подписи, если он их дал.

## Как менять правила

1. `GET /rules/{mp}/{id}` - возьми правило целиком.
2. `POST /rules/{mp}/{id}` - отправь только поля, которые меняешь, например `{"rule_stopwords": "брак, подделка"}`.
   Остальное останется как было.
3. Поля: `comment` (название), `stars` ([4, 5]), `text_key` (`text_any`, `text_contains`, `text_no`), `media_key`
   (`any`, `with_media`, `without_media`), `neuro_key` (`template_only` - шаблоны, `neuro_only` - нейросеть,
   `neuro_template` - нейросеть по шаблонам), `moderation`, `active`, `skus` и `skus_black` (артикулы по одному на
   строку), `whitewords` (по строке), `ww_strict`, `rule_stopwords` (через запятую), `instructions` (для нейросети),
   `tone`, `length`, `treat`, `minus_words`, `sign_check`, `sign_text`.
4. `templates` - список `[{"id": 15, "type": 1, "text": "Здравствуйте, {username}!"}]`, `type` - блок: 1 Приветствие,
   2 Благодарность, 3 Основной текст, 4 Рекомендация, 5 Прощание. Список заменяется целиком: шаблон с `id` меняется, без
   `id` добавляется, не переданный удаляется. Поэтому меняй список, полученный в шаге 1, а не пиши с нуля.
5. Проверки - как в редакторе кабинета; ошибка придёт с понятным текстом (422). Удалять правила и менять много правил
   сразу - только по явной просьбе владельца; перед этим покажи, что изменится.

## Тарифы и деньги

Право `billing` тратит деньги владельца. Подключай тариф (`/billing/order`), меняй автопродление и применяй промокоды
только по явной просьбе владельца и после того, как показал ему цену (`/billing/price`) и баланс (`/billing`). Ссылку
на оплату картой передай владельцу - платит он сам на странице банка.

## Правила автоответов

`GET /rules` показывает правила, по которым ТутОтвет отвечает сам: оценки (`stars`), способ ответа
(`answer_type`: `templates`, `neuro`, `neuro_by_templates`), включена ли модерация (`moderation`). Если в правиле
включена модерация, бот не публикует ответ сразу, а готовит черновик со статусом `moderation` - его можешь
проверить и опубликовать ты. Включать и выключать правила (`/rules/{mp}/{id}/active`) можно только по просьбе
владельца.

## Пример на Python

```python
import requests

API = 'https://lk.tutotvet.ru/api/v1'
H = {'Authorization': 'Bearer tt_...'}

for r in requests.get(f'{API}/reviews', params={'status': 'needs_answer'}, headers=H).json()['reviews']:
    text = write_answer(r)          # здесь твоя нейросеть пишет ответ по r['text'], r['rating'], r['product']
    res = requests.post(f"{API}/reviews/{r['mp']}/{r['id']}/answer", json={'text': text}, headers=H)
    print(r['id'], res.status_code, res.json())
```

## Для владельца магазина: где подключить

Обычный чат с нейросетью сам запросы к API не отправляет: нужна нейросеть, которой разрешено обращаться к
внешним сервисам.

- **Claude и ChatGPT как коннектор (проще всего).** В настройках коннекторов добавьте свой коннектор с адресом
  `https://lk.tutotvet.ru/mcp`. Ключ не нужен: откроется вход в ТутОтвет, выберите организацию и права и нажмите
  «Разрешить». Отключить - в кабинете, Настройки - API и нейросети.
- **ChatGPT, свой GPT.** Создайте GPT (Explore GPTs - Create - Configure), в разделе Actions нажмите
  «Create new action», «Import from URL» и вставьте `https://lk.tutotvet.ru/api/v1/openapi.json`. В Authentication
  выберите API Key, тип Bearer, и вставьте ключ. В Instructions вставьте ссылку на эту инструкцию и свои пожелания к
  ответам (тон, подпись).
- **Yandex AI Studio:** Agent Atelier - MCP-серверы - внешний сервер, адрес `https://lk.tutotvet.ru/mcp`,
  транспорт Streamable HTTP, заголовок `Authorization: Bearer tt_...`; затем подключите сервер к агенту.
- **Cursor, Claude Desktop, Claude Code и другие с MCP:** кнопка «Настройки MCP» в кабинете после выпуска ключа
  копирует готовый блок настроек. Для Claude Code: `claude mcp add --transport http tutotvet
  https://lk.tutotvet.ru/mcp --header "Authorization: Bearer tt_..."`.
- **Агенты с доступом к интернету и коду** без MCP: дайте им ссылку на эту инструкцию и ключ - кнопка «Текст для
  нейросети» в кабинете.
- **n8n, Make, Albato:** HTTP-запрос с заголовком `Authorization: Bearer tt_...`, ответ пишет узел нейросети.
- **Свой скрипт:** пример на Python выше.

Начните с проверки: попросите нейросеть показать отзывы, которые ждут ответа, и предложить ответы, а публиковать -
после вашего подтверждения.
