Сообщения
Чтение переписки, ответ посетителю, идемпотентность и признак источника.
На этой странице
Переписка #
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
| cursor | RFC 3339 | нет | продолжение предыдущей страницы |
| limit | int | нет | 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 #
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
| id | uuid | да | номер сообщения |
| direction | string | да | incoming — посетитель, outgoing — поддержка |
| senderType | string | да | customer, admin, system |
| content | string | да | текст |
| entities[] | object | нет | разметка текста отрезками, см. раздел «Форматирование текста»; пустой список у обычного текста |
| messageType | string | да | text, image, document, audio, video |
| origin | string | да | откуда написано: widget, telegram, api, bitrix24, amocrm, retailcrm, unknown |
| createdAt | RFC 3339 | да | когда записано |
| editedAt | RFC 3339|null | нет | когда исправлено |
| attachments[] | object | нет | вложения, см. раздел «Вложения» |
🔴 origin нужен, чтобы не зациклиться: получив событие о собственном ответе, ваша система не должна отправить его второй раз.
Ответить посетителю #
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
| content | string | нет | текст до 4096 символов; обязателен, если нет file |
| entities[] | object | нет | разметка текста: жирный, наклонный, подчёркнутый, зачёркнутый, моноширинный, цитата и ссылка с подписью — см. раздел ниже |
| file.url | string | нет | ссылка на файл: мы скачаем его сами, до 50 МБ |
| file.name | string | нет | имя файла для переписки |
| file.type | string | нет | image, document, audio, video |
| file_url, file_name, file_type | string | нет | то же самое плоскими полями — для конструкторов связок, которые не умеют вложенные объекты |
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 и строки в браузере: эмодзи занимает два знака, буква кириллицы — один.
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
| type | string | да | bold, italic, underline, strikethrough, code, pre, blockquote, text_link |
| offset | int | да | начало отрезка от начала текста, в единицах UTF-16 |
| length | int | да | длина отрезка в тех же единицах |
| url | string | нет | адрес для type: text_link; допустимы схемы http, https, mailto, tel |
| language | string | нет | язык блока кода для 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 разговора.