Сообщения

Чтение переписки, ответ посетителю, идемпотентность и признак источника.

Переписка #

GET /api/v1/conversations/{id}/messages conversations:read
ПолеТипОбяз.Описание
cursorRFC 3339нетпродолжение предыдущей страницы
limitintнет1…100, по умолчанию 25
Ответ
{"data": [{
  "id": "7735af47-2e36-45fd-9543-83f67b6d7eef",
  "direction": "outgoing",
  "senderType": "admin",
  "content": "Заказ уже в пути",
  "entities": [{"type": "bold", "offset": 0, "length": 5}],
  "messageType": "text",
  "origin": "api",
  "createdAt": "2026-08-22T09:15:04.281Z",
  "editedAt": null,
  "attachments": []
}], "hasMore": false}

Объект message #

ПолеТипОбяз.Описание
iduuidданомер сообщения
directionstringдаincoming — посетитель, outgoing — поддержка
senderTypestringдаcustomer, admin, system
contentstringдатекст
entities[]objectнетразметка текста отрезками, см. раздел «Форматирование текста»; пустой список у обычного текста
messageTypestringдаtext, image, document, audio, video
originstringдаоткуда написано: widget, telegram, api, bitrix24, amocrm, retailcrm, unknown
createdAtRFC 3339дакогда записано
editedAtRFC 3339|nullнеткогда исправлено
attachments[]objectнетвложения, см. раздел «Вложения»

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

Ответить посетителю #

POST /api/v1/conversations/{id}/messages conversations:write
ПолеТипОбяз.Описание
contentstringнеттекст до 4096 символов; обязателен, если нет file
entities[]objectнетразметка текста: жирный, наклонный, подчёркнутый, зачёркнутый, моноширинный, цитата и ссылка с подписью — см. раздел ниже
file.urlstringнетссылка на файл: мы скачаем его сами, до 50 МБ
file.namestringнетимя файла для переписки
file.typestringнетimage, document, audio, video
file_url, file_name, file_typestringнетто же самое плоскими полями — для конструкторов связок, которые не умеют вложенные объекты
Запрос
POST /api/v1/conversations/6c82f8e2-…/messages
Idempotency-Key: reply-4417
Content-Type: application/json

{"content": "Заказ уже в пути",
 "file": {"url": "https://example.ru/act.pdf", "name": "Акт.pdf", "type": "document"}}
Ответ
201 {"data": {"id": "7735af47-…", "content": "Заказ уже в пути",
                "createdAt": "2026-08-22T09:15:04.281Z", "direction": "outgoing", "status": "queued"}}
200 {"data": {"id": "7735af47-…", "duplicate": true}}

Файл забирается до записи сообщения: недоступная ссылка не оставит в переписке пустой ответ. Запросы к вашему адресу идут мимо прокси и не во внутреннюю сеть. Вложение можно прислать и плоскими полями file_url, file_name, file_type — так удобнее конструкторам связок; вложенный объект file главнее. Имя или тип файла без ссылки — отказ validation_error, а не молчаливая отправка одного текста: иначе связка считала бы, что вложение ушло.

Форматирование текста #

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

Оператору для этого ничего изучать не нужно: он форматирует ответ обычными средствами Telegram (выделить текст → «Жирный», «Ссылка» и так далее), а посетитель видит то же самое. Через API разметка задаётся полем entities.

Разметка передаётся отрезками, а не тегами: HTML в переписке мы не принимаем и не отдаём. Отрезок — это «с такого-то знака столько-то знаков такой-то вид». Смещения считаются в единицах UTF-16 — так же, как их считают Telegram Bot API и строки в браузере: эмодзи занимает два знака, буква кириллицы — один.

ПолеТипОбяз.Описание
typestringдаbold, italic, underline, strikethrough, code, pre, blockquote, text_link
offsetintданачало отрезка от начала текста, в единицах UTF-16
lengthintдадлина отрезка в тех же единицах
urlstringнетадрес для type: text_link; допустимы схемы http, https, mailto, tel
languagestringнетязык блока кода для type: pre
Запрос
POST /api/v1/conversations/6c82f8e2-…/messages
Content-Type: application/json

{"content": "Заказ уже в пути, отследить можно тут",
 "entities": [
   {"type": "bold", "offset": 0, "length": 5},
   {"type": "text_link", "offset": 30, "length": 3, "url": "https://example.ru/track/4417"}
 ]}

Отрезки, которые нельзя показать, отбрасываются, а текст остаётся целым: неизвестный тип, выход за пределы текста и ссылка с чужой схемой (javascript:, data:) молча превращаются в обычный текст. Пересекаться отрезки не должны — вкладывайте их друг в друга, как это делает Telegram: ссылка внутри жирного, а не наполовину.

Idempotency-Key #

Заголовок делает повтор безопасным: связь может оборваться после того, как запрос уже приняли. Повторная отправка с тем же ключом вернёт 200 и duplicate: true вместо второго сообщения.

Допустимы до 128 символов из A-Z a-z 0-9 . _ : - Ключ действует в пределах вашего ключа доступа: два разных ключа доступа с одинаковым Idempotency-Key друг другу не мешают.

Что означает status: queued #

Ответ принят в доставку и уйдёт в окно посетителя той же очередью, что и ответ оператора из Telegram. Отдельного признака «доставлено» у API нет: событие message.created придёт вам на общих основаниях, а видимость ответа посетителем отражает поле lastReadAt разговора.