Чаты по ключу ассистента
Ключ ассистента site_… даёт доступ к переписке одного ассистента: завести чат, отправить сообщение и получить ответ, прочитать историю, передать диалог оператору. Отдельно — выгрузка диалогов на перевод по ключу user_….
Ключ ассистента
Методы /chat/* и /chats работают не с ключом пользователя user_…, а с ключом ассистента site_…. Ключ привязан к одному ассистенту: всё, что создаётся и читается этими методами, принадлежит ему. Получить ключ — GET /assistants/{assistantId}/api-key с ключом user_…, подробнее в разделе Авторизация.
SITE_KEY=$(curl -s "$BASE/assistants/$ASSISTANT/api-key" \
-H "Authorization: Bearer $KEY" | jq -r .api_key)
Ключ передаётся одним из трёх способов, проверяются по порядку:
| Способ | Пример |
|---|---|
Заголовок Authorization | Authorization: Bearer site_XXXXXXXX… |
Заголовок X-API-Key | X-API-Key: site_XXXXXXXX… |
| Параметр строки запроса | ?api_key=site_XXXXXXXX… |
| HTTP | Когда |
|---|---|
| 401 | Ключа нет: {"success": false, "error": "API key is required", "message": "…"} |
| 401 | Ключ не начинается с site_ (например, передан user_…): {"success": false, "error": "Invalid API key format", "message": "API key must start with \"site_\""} |
| 401 | Ключ не найден: {"success": false, "error": "Invalid API key", "message": "The provided API key is not valid"} |
Отказы проверки ключа приходят в общем формате ошибок /api/v1, как и все остальные, см. Ошибки и ответы.
С ключом site_… можно читать все диалоги ассистента по токену чата и писать от имени посетителя. Не вставляйте его в код страницы или мобильного приложения — вызывайте методы со своего сервера.
Чаты
Чат опознаётся токеном chat_token вида chat_ + 32 символа. Токен выдают POST /chat/create и POST /chat/message; храните его у себя, чтобы продолжать разговор и читать историю.
Ответ ассистента в этих методах строится упрощённо: системный промпт и модель ассистента плюс поиск по его страницам знаний. Агенты, коннекторы, генерация картинок, кредиты и пейволл здесь не участвуют — это канал для своего бота или виджета поверх ассистента, а не замена чата в браузере.
Создать чат
Заводит пустой чат и отдаёт его токен.
POST /chat/create
| Параметр | Тип | Обяз. | Описание |
|---|---|---|---|
channel | string | нет | Тело. Канал: api (по умолчанию), widget, telegram, whatsapp, email. |
channel_data | object | нет | Тело. Произвольные данные канала: id собеседника в мессенджере, имя, ссылка. Возвращаются в истории чата. |
curl -s -X POST "$BASE/chat/create" \
-H "Authorization: Bearer $SITE_KEY" \
-H "Content-Type: application/json" \
-d '{"channel": "telegram", "channel_data": {"telegram_id": 100200300, "name": "Анна"}}'
Ответ 201, пример собран по коду:
{
"success": true,
"chat_token": "chat_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"chat_id": 140512,
"channel": "telegram"
}
| HTTP | Когда |
|---|---|
| 401 | Ключ ассистента не передан или неверный |
| 422 | Неизвестный channel, channel_data не объект: {"success": false, "message": "…", "errors": {"channel": ["…"]}} |
Отправить сообщение
Сохраняет сообщение посетителя и возвращает ответ ассистента. Без chat_token сначала создаёт новый чат — удобно для первого сообщения. Если у чата выключен бот, сообщение сохраняется, а ответа нет — отвечает оператор.
POST /chat/message
| Параметр | Тип | Обяз. | Описание |
|---|---|---|---|
message | string | да | Тело. Текст посетителя, до 10 000 символов. |
chat_token | string | нет | Тело. Токен существующего чата этого ассистента. Не передан — создаётся новый чат. |
history | array | нет | Тело. Предыдущие реплики для контекста: [{"role": "user", "content": "…"}, {"role": "assistant", "content": "…"}]. Учитываются последние 10. |
channel | string | нет | Тело. Канал нового чата, как у POST /chat/create. Для существующего чата игнорируется. |
channel_data | object | нет | Тело. Данные канала нового чата. |
Сохранённую историю чата модель сама не подтягивает: контекст разговора — только то, что пришло в history. Передавайте прошлые реплики, если нужен связный диалог.
curl -s -X POST "$BASE/chat/message" \
-H "Authorization: Bearer $SITE_KEY" \
-H "Content-Type: application/json" \
-d '{
"chat_token": "chat_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"message": "А сколько стоит подписка на месяц?",
"history": [
{"role": "user", "content": "Привет! Что ты умеешь?"},
{"role": "assistant", "content": "Привет! Помогаю с текстами, идеями и картинками."}
]
}'
Пример ответа собран по коду:
{
"success": true,
"chat_token": "chat_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"answer": "Месячная подписка стоит 1900 ₽ и даёт 20 000 кредитов.",
"reasoning": null,
"sources": [
{ "url": "https://example.com/pricing", "title": "Тарифы" }
],
"timing": { "model": "google/gemini-3-flash", "total": 2140 },
"bot_disabled": false,
"manager_requested": false,
"user_message": { "id": 870011, "chat_id": 140512, "role": "user", "content": "А сколько стоит подписка на месяц?", "…": "…" },
"assistant_message": { "id": 870012, "chat_id": 140512, "role": "assistant", "content": "Месячная подписка стоит 1900 ₽…", "…": "…" }
}
| Свойство | Тип | Описание |
|---|---|---|
chat_token | string | Токен чата — новый, если чат создан этим вызовом. |
answer | string или null | Ответ ассистента. null, если бот в чате выключен. |
reasoning | string или null | Рассуждения модели, если модель их отдаёт. |
sources | array | Страницы, на которые опирался ответ: url, title. |
timing | object или null | Модель и время ответа в миллисекундах. |
bot_disabled | boolean | Бот в чате выключен — ответ ждёт оператора. |
manager_requested | boolean | Модель не уверена и позвала оператора: чат помечается как требующий внимания, бот при этом продолжает отвечать. |
user_message, assistant_message | object | Сохранённые сообщения целиком, со всеми полями записи. |
Если бот выключен, ответ короче: success, chat_token, bot_disabled: true, answer: null, user_message.
| HTTP | Когда |
|---|---|
| 401 | Ключ ассистента не передан или неверный |
| 404 | chat_token не найден или чат другого ассистента: {"success": false, "error": "Chat not found", "message": "The provided chat_token is invalid or does not belong to this site"} |
| 422 | Нет message, текст длиннее 10 000, неизвестный channel: {"success": false, "error": "Validation error", "message": "The message field is required., …"} |
| 500 | Ошибка модели: {"success": false, "error": "Internal error", "message": "…"}. Сообщение посетителя при этом уже сохранено. |
История чата
Чат со всеми сообщениями, включая системные и ответы операторов, от старых к новым.
GET /chat/{chatToken}
| Параметр | Тип | Обяз. | Описание |
|---|---|---|---|
chatToken | string | да | Путь. Токен чата. Работает для любого чата ассистента, в том числе созданного в браузере. |
curl -s "$BASE/chat/chat_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
-H "Authorization: Bearer $SITE_KEY"
{
"success": true,
"chat_token": "chat_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"chat_id": 131207,
"channel": "frame",
"channel_data": {
"visitor_name": "Весёлый Енот",
"visitor_color": "#3498DB",
"visitor_avatar": "https://anonymous-animals.azurewebsites.net/animal/raccoon"
},
"messages": [
{
"id": "851020",
"role": "user",
"content": "Составь план тренировок на неделю",
"sources": null,
"timing": null,
"reasoning": null,
"manager_id": null,
"manager_name": null,
"manager_avatar": null,
"attachments": null,
"is_voice_input": false,
"created_at": "2026-09-25T19:43:44+00:00",
"tokens": null,
"cost_usd": null,
"read_by": []
},
{
"id": "851021",
"role": "assistant",
"content": "Вот план на семь дней…",
"sources": [
{ "url": "https://example.com/training", "title": "Как составить план тренировок" }
],
"timing": { "model": "default-model", "total": 52947 },
"reasoning": "**Planning the week**\n\n…",
"manager_id": null,
"manager_name": null,
"manager_avatar": null,
"attachments": null,
"is_voice_input": false,
"created_at": "2026-09-25T19:44:37+00:00",
"tokens": 3120,
"cost_usd": 0.0041,
"read_by": []
}
],
"bot_disabled": false,
"manager_requested": false,
"created_at": "2026-09-25T19:43:44+00:00",
"updated_at": "2026-09-25T19:44:37+00:00"
}
| Свойство | Тип | Описание |
|---|---|---|
chat_id | integer | Внутренний id чата. |
channel | string | Канал: frame (чат в браузере), api, widget, telegram, whatsapp, email. |
channel_data | object или null | Данные канала: для браузерного чата — имя и цвет анонимного посетителя, для своих каналов — то, что передали при создании. |
messages[].id | string | Id сообщения. |
messages[].role | string | user, assistant, system или ответ оператора. |
messages[].content | string | Текст. |
messages[].sources | array или null | Источники ответа: url, title. |
messages[].timing | object или null | model и total — время ответа, мс. |
messages[].reasoning | string или null | Рассуждения модели. |
messages[].manager_id, manager_name, manager_avatar | — | Оператор, если сообщение написал он. |
messages[].attachments | array или null | Вложения. |
messages[].is_voice_input | boolean | Сообщение надиктовано голосом. |
messages[].tokens, cost_usd | integer, number | Расход на ответ. |
messages[].read_by | array | Кто из операторов прочитал. |
bot_disabled | boolean | Бот выключен. |
manager_requested | boolean | Модель звала оператора. |
| HTTP | Когда |
|---|---|
| 401 | Ключ ассистента не передан или неверный |
| 404 | Чата нет или он другого ассистента: {"success": false, "error": "Chat not found", "message": "…"} |
Включить или выключить бота
Передаёт чат оператору: с выключенным ботом сообщения посетителя сохраняются, но ассистент не отвечает. Включение возвращает автоответы.
POST /chat/{chatToken}/toggle-bot
| Параметр | Тип | Обяз. | Описание |
|---|---|---|---|
chatToken | string | да | Путь. Токен чата. |
bot_disabled | boolean | да | Тело. true — выключить бота, false — включить. |
curl -s -X POST "$BASE/chat/chat_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/toggle-bot" \
-H "Authorization: Bearer $SITE_KEY" \
-H "Content-Type: application/json" \
-d '{"bot_disabled": true}'
Пример ответа собран по коду:
{
"success": true,
"chat_token": "chat_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"bot_disabled": true
}
| HTTP | Когда |
|---|---|
| 401 | Ключ ассистента не передан или неверный |
| 404 | Чата нет или он другого ассистента: {"success": false, "error": "Chat not found"} |
| 422 | Нет bot_disabled или не boolean |
Список чатов
Все чаты ассистента, в которых есть хотя бы одно сообщение, от недавно обновлённых к давним: и созданные через API, и браузерные (frame), и из Telegram. Отсюда берут chat_token, чтобы прочитать историю.
GET /chats
| Параметр | Тип | Обяз. | Описание |
|---|---|---|---|
channel | string | нет | Строка запроса. Только чаты этого канала: frame, api, widget, telegram, whatsapp, email. |
limit | integer | нет | Строка запроса. 1–100, по умолчанию 20. |
offset | integer | нет | Строка запроса. По умолчанию 0. |
curl -s "$BASE/chats?channel=frame&offset=0" \
-H "Authorization: Bearer $SITE_KEY"
{
"success": true,
"chats": [
{
"chat_token": "chat_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"chat_id": 140512,
"channel": "frame",
"messages_count": 4,
"last_message": {
"role": "assistant",
"content": "Вот план на неделю: понедельник — ноги и кор, вторник — отдых, среда — спина…",
"created_at": "2026-09-25T10:02:11+00:00"
},
"bot_disabled": false,
"manager_requested": false,
"needs_attention": false,
"created_at": "2026-09-25T09:58:40+00:00",
"updated_at": "2026-09-25T10:02:11+00:00"
}
],
"total": 1240,
"limit": 20,
"offset": 0
}
| Свойство | Тип | Описание |
|---|---|---|
chats[].chat_token | string | Токен чата — для GET /chat/{chatToken} и toggle-bot. |
chats[].chat_id | integer | Внутренний id чата. |
chats[].channel | string | Канал чата. |
chats[].messages_count | integer | Сколько сообщений в чате. |
chats[].last_message | object | Последнее сообщение: role, content (первые 100 символов), created_at. |
chats[].bot_disabled | boolean | Бот выключен, отвечает оператор. |
chats[].manager_requested | boolean | Модель звала оператора. |
chats[].needs_attention | boolean | Модель звала оператора, а оператор чат ещё не открыл. |
chats[].created_at, updated_at | string | ISO 8601, UTC. |
total | integer | Сколько чатов подходит под фильтр, без учёта limit и offset. |
limit, offset | integer | Применённые значения, всегда числом (?limit=50 вернёт 50, а не "50"). |
| HTTP | Когда |
|---|---|
| 401 | Ключ ассистента не передан или неверный |
| 422 | limit вне 1–100, offset отрицательный: {"success": false, "message": "The limit field must not be greater than 100.", "errors": {"limit": ["…"]}} |
Переводы диалогов
Чтобы читать диалоги посетителей на любом языке, диалог выгружают одним JSON, переводят внешней моделью целиком (контекст не теряется) и загружают перевод обратно. Перевод появляется в интерфейсе у карточки пользователя. Эти методы работают с ключом user_…, а не site_…: доступ у владельца ассистента и пользователя с расшаренным доступом.
{chat} в путях — числовой id чата или его короткий hash_id из адреса чата.
Выгрузить диалог
Все сообщения чата без системных, плюс текущий тип диалога и список известных типов — их удобно отдать модели, чтобы она уточнила тип.
GET /assistants/{assistantId}/chats/{chat}/messages
| Параметр | Тип | Обяз. | Описание |
|---|---|---|---|
assistantId | integer | да | Путь. Id ассистента. |
chat | string | да | Путь. Id или hash_id чата. |
curl -s "$BASE/assistants/$ASSISTANT/chats/Qa7Kp2/messages" \
-H "Authorization: Bearer $KEY"
{
"success": true,
"chat": {
"id": 131207,
"hash_id": "Qa7Kp2",
"user_id": 100452,
"created_at": "2026-09-25T19:43:44+00:00",
"has_translation": false,
"dialog_type": null
},
"dialog_types": ["academic writing", "advice", "coding", "fitness", "…"],
"messages": [
{ "id": "851020", "role": "user", "content": "Составь план тренировок на неделю", "created_at": "2026-09-25T19:43:44+00:00" },
{ "id": "851021", "role": "assistant", "content": "Вот план на семь дней…", "created_at": "2026-09-25T19:44:37+00:00" }
]
}
| Свойство | Тип | Описание |
|---|---|---|
chat.has_translation | boolean | Есть ли уже перевод на русский. |
chat.dialog_type | string или null | Тип диалога. |
dialog_types | array | Все типы диалогов, известные площадке. |
messages | array | id, role (user или assistant), content, created_at. Id сохраняйте — по ним загружается перевод. |
| HTTP | Когда |
|---|---|
| 404 | Ассистент чужой или чат не этого ассистента: {"success": false, "error": "Chat not found or access denied"}. Нечисловой assistantId — тоже 404. |
Загрузить перевод
Сохраняет перевод на язык; повторная загрузка на тот же язык заменяет прежний перевод. Заодно можно проставить тип диалога — новый тип попадёт в общий список dialog_types.
PUT /assistants/{assistantId}/chats/{chat}/translation
| Параметр | Тип | Обяз. | Описание |
|---|---|---|---|
assistantId | integer | да | Путь. Id ассистента. |
chat | string | да | Путь. Id или hash_id чата. |
locale | string | нет | Тело. Язык перевода, до 8 символов. По умолчанию ru. |
messages | array | да | Тело. Не пустой. Элементы — объекты {id, content, reasoning?}: id обязателен, строка или число из выгрузки; content и reasoning — строки или null. |
type | string | нет | Тело. Тип диалога, до 60 символов. Приводится к нижнему регистру, остаются латиница, цифры, пробел, _ и -. |
curl -s -X PUT "$BASE/assistants/$ASSISTANT/chats/Qa7Kp2/translation" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{
"locale": "ru",
"type": "fitness",
"messages": [
{ "id": "851020", "content": "Составь план тренировок на неделю" },
{ "id": "851021", "content": "Вот план на семь дней…" }
]
}'
Пример ответа собран по коду:
{ "success": true, "translation_id": 5210, "messages_count": 2 }
| HTTP | Когда |
|---|---|
| 404 | Ассистент чужой или чата нет |
| 422 | Нет messages или он пустой; элемент не объект; у элемента нет id или id не строка и не число ("The messages.0.id must be a message id (string or integer)."); content или reasoning не строка: {"success": false, "errors": {…}} |
Получить перевод
GET /assistants/{assistantId}/chats/{chat}/translation
| Параметр | Тип | Обяз. | Описание |
|---|---|---|---|
assistantId | integer | да | Путь. |
chat | string | да | Путь. Id или hash_id чата. |
locale | string | нет | Строка запроса. По умолчанию ru. |
curl -s "$BASE/assistants/$ASSISTANT/chats/Qa7Kp2/translation?locale=ru" \
-H "Authorization: Bearer $KEY"
Перевода нет:
{ "success": true, "translation": null }
Перевод есть (собрано по коду):
{
"success": true,
"translation": {
"locale": "ru",
"messages": [
{ "id": "851020", "content": "Составь план тренировок на неделю" }
],
"updated_at": "2026-09-25T20:10:00+00:00"
}
}
Удалить перевод
DELETE /assistants/{assistantId}/chats/{chat}/translation
| Параметр | Тип | Обяз. | Описание |
|---|---|---|---|
assistantId | integer | да | Путь. |
chat | string | да | Путь. Id или hash_id чата. |
locale | string | нет | Тело или строка запроса. По умолчанию ru. |
curl -s -X DELETE "$BASE/assistants/$ASSISTANT/chats/Qa7Kp2/translation?locale=ru" \
-H "Authorization: Bearer $KEY"
Ответ {"success": true} — и когда перевод был удалён, и когда его не было.
Дальше
- Авторизация — ключи
user_…иsite_… - Поддержка и обращения
- Домены, Telegram, встраивание