Для AI-агентов: markdown этой страницы — /docs/marketing.mdиндекс документации — /llms.txt
Сегменты, рассылки и цепочки
Обновлено
TelegaFirst помогает микробизнесу продолжать разговор с клиентом: выбрать аудиторию, подготовить сообщение, согласовать отправку и увидеть результат. Владелец и операторы управляют этим из Telegram, а собственный AI-агент владельца может работать через Hub с выданными правами. Клиенты получают сообщения в своём поддерживаемом канале; выбор аудитории и право доставить сообщение проверяются отдельно.
Результат работы — сохранённый сегмент, подготовленный черновик и, после подтверждения человеком, принятая задача отправки с доступным статусом. queued означает постановку в очередь. Итоговые счётчики показывают, сколько сообщений действительно отправлено и сколько завершилось ошибкой.
Перед началом
Подключите бизнес по инструкции запуска и проверьте активный slug и бота. Для MCP выполните авторизацию, обновите tools/list и получите схему нужной операции по руководству MCP. Наличие схемы ещё не означает установленный в вашем AI-клиенте инструмент.
Для REST ниже указаны относительные пути Hub. X-Api-Key и Authorization: Bearer tgf_* — альтернативные способы передать допустимый ключ. Owner/customer JWT нельзя подставлять вместо ключа на этих маршрутах. Нужные права и текущий доступ человека или credential проверяются при каждом вызове; права одной операции не заменяют права другой.
| Задача | REST scope |
|---|---|
| Оси, цели, preview и чтение сохранённых сегментов | broadcasts:read |
| Выборка клиентов сегмента | dialogs:read |
| Создание, изменение, удаление сохранённого сегмента; запись и запуск рассылки | broadcasts:write |
| Чтение кампаний и источников | marketing:read |
| Изменение кампаний и источников | marketing:write |
| Чтение цепочек и шагов через MCP | chains:read |
| Изменение цепочек, шагов и подготовка пакетного входа | chains:write |
Все required scopes операции обязательны одновременно. Тариф, readiness, актуальные permissions, лимиты и согласие на денежное действие сохраняют силу при наличии scope. Права и ограничения.
Примеры используют демонстрационные номера и контрактные ответы. Они не являются записью реальной рассылки. Перед записью получите номера из своего бизнеса: номер клиента, кампании, товара или цепочки — tenant-local seq_num, а не идентификатор базы данных. client_id приходит из аутентификации и не передаётся в JSON. Идентификаторы и страницы результатов.
Соберите и проверьте аудиторию
Прочитайте
GET /api/v1/tools/segments/axes(200), в MCP —describe_segment_axes. Выберите доступныеkind/keyи проверьтеrequiresTarget,targetEntity,periodSupportedиavailable.Для условий с целью вызовите
POST /api/v1/tools/segments/targets(201), в MCP —list_segment_targets. Возвращённыйseq— строка с номером объекта вашего бизнеса. Здесь default/maximumlimit—50; строка поиска ограничена200символами.Соберите фильтр: внутри
anyусловия объединяются через «ИЛИ», разные группыinclude— через «И», условияexcludeвычитаются как объединение. Плоский старый список условий не подходит.Выполните
POST /api/v1/tools/segments/reach(201), в MCP —preview_segment_reach. Прочитайтеvalid,issues,reachableиbreakdown. Число0приvalid:falseне означает корректный пустой сегмент.После успешной проверки при необходимости вызовите
POST /api/v1/tools/segments/sample(201), в MCP —sample_segment_audience. Defaultlimit—20, maximum —50; результат содержитuserSeqNums, без внешних chat IDs.
Пример запроса целей; для POST с непустым телом нужен отдельный Idempotency-Key:
POST /api/v1/tools/segments/targets
Content-Type: application/json
Idempotency-Key: audience-targets-1
{
"kind": "commerce",
"key": "bought_product",
"search": "Course"
}Контрактный ответ 201:
{
"targets": [
{
"seq": "7",
"title": "Course"
}
]
}Фильтр «Вся база», который можно передать в filter для preview и sample:
{
"include": [
{
"any": [
{
"kind": "preset",
"key": "all_subscribers"
}
]
}
],
"exclude": []
}Название all_subscribers обозначает базовое условие аудитории. Оно не доказывает рекламное согласие каждого человека. Получайте необходимое согласие на сообщения и учитывайте актуальные ограничения доставки; блокировка бота исключает получателя, а ограничения канала и поддерживаемых возможностей могут привести к пропуску. Preview не резервирует аудиторию и не гарантирует доставку каждому выбранному клиенту.
Например, структурно неверный фильтр в reach:
{
"filter": {
"malformed": true
}
}Этот запрос даёт диагностический ответ 201, а не разрешение отправлять:
{
"valid": false,
"issues": [
"Malformed filter"
],
"reachable": 0,
"breakdown": {
"valid": false,
"issues": [
"Malformed filter"
],
"reachable": null,
"include": [],
"exclude": [],
"excludedUnion": null
}
}Попытка получить sample с непригодным фильтром возвращает 422 INVALID_INPUT. Исправьте фильтр по описанию осей, снова выполните preview, затем sample. Ошибка выбора аудитории не должна превращаться в отправку всей базе.
Сохраните сегмент и работайте с его версией
POST /api/v1/tools/segments/saved создаёт сегмент и возвращает 201. Заголовок Idempotency-Key обязателен. Заголовок сегмента после обрезки пробелов должен содержать 1..120 символов.
{
"title": " New audience ",
"filter": {
"include": [
{
"any": [
{
"kind": "preset",
"key": "all_subscribers"
}
]
}
],
"exclude": []
}
}Полный контрактный результат:
{
"seqNum": 9,
"title": "New audience",
"filter": {
"include": [
{
"any": [
{
"kind": "preset",
"key": "all_subscribers"
}
]
}
],
"exclude": []
},
"version": 1,
"updatedAt": "2026-10-01T10:00:00.000Z"
}Для чтения используйте GET /api/v1/tools/segments/saved/{seqNum}. Список GET /api/v1/tools/segments/saved?afterSeqNum=6&limit=1 возвращает segments и nextAfterSeqNum; следующий запрос получает возвращённый номер. Default limit — 100, maximum — 500. Не переносите этот параметр на списки рассылок или цепочек: у них другой контракт, без такой пагинации.
Изменение PATCH /api/v1/tools/segments/saved/7 требует текущего expectedVersion и хотя бы одного из title/filter. Например, после чтения версии 2:
{
"expectedVersion": 2,
"title": " Updated audience "
}Успех 200 содержит тот же seqNum:7, обновлённое название Updated audience и version:3. При 409 CONFLICT с detail Saved segment version changed; reload and retry перечитайте сегмент, покажите изменения человеку и решите, нужна ли прежняя правка. Удаление DELETE /api/v1/tools/segments/saved/7 также принимает тело {"expectedVersion":2} для удаления именно прочитанной версии.
В рассылке saved_segment_seq_num — номер сохранённого сегмента. Не передавайте одновременно противоречащие друг другу источники аудитории. При подготовке запуска версия и содержимое сегмента входят в проверяемый снимок; изменение аудитории требует новой подготовки.
Подготовьте рассылку и отдельно согласуйте запуск
Черновик REST создаётся POST /api/v1/tools/broadcasts (201), меняется PATCH того же пути (200). Непустой POST требует Idempotency-Key. Пример создания:
{
"title": "Autumn",
"saved_segment_seq_num": null,
"segment_labels": "Everyone",
"message_ttl_minutes": 90,
"button_title": "Open",
"button_target": {
"kind": "section_root",
"section": "catalog"
}
}Полный контрактный результат:
{
"seqNum": 3,
"status": "draft",
"title": "Autumn",
"savedSegmentSeqNum": null,
"target": {
"kind": "section_root",
"section": "catalog"
},
"isAwaitingReply": false,
"segmentLabels": "Everyone",
"segmentFilter": null,
"scheduledAt": null,
"scheduleEcho": null,
"messageTtlMinutes": 90,
"buttonTitle": "Open",
"buttonTarget": {
"kind": "section_root",
"section": "catalog"
}
}Черновик ещё не отправляется. Текст/медиа и аудитория должны быть подготовлены до запуска; REST shell-запрос выше не заменяет подготовку rich content. У MCP create_broadcast отдельная rich-схема с обязательным content: не копируйте REST JSON в этот инструмент. Его описанный путь состоит из четырёх вызовов: create_broadcast, один get_content_draft, затем prepare_broadcast_launch и после окончательного подтверждения человеком — execute_broadcast_launch. Если единственная проверка draft ещё не вернула опубликованный seqNum, остановитесь и разберитесь с готовностью контента.
В REST при PATCH отсутствующий segment_filter сохраняет прежнюю аудиторию, а null сбрасывает её на всю базу. Проверьте это перед подтверждением. Для schedule передайте kind:"once" и at_local — локальное время бизнеса без offset/Z; абсолютное время разрешает сервер по часовому поясу бизнеса. Проверяйте возвращённый scheduleEcho. Нельзя подменять at_local произвольной UTC-строкой.
REST-порядок запуска:
Прочитайте
GET /api/v1/tools/broadcastsи проверьте черновик, содержание, аудиторию, время, срок сообщения и доступный баланс.Вызовите
POST /api/v1/tools/broadcasts/prepare-launchс{"seq_num":3}и новымIdempotency-Key. Ответ200содержитseqNum, текущийstatusиrevision— строку из64hex-символов. Подготовка не отправляет сообщения.Покажите человеку именно подготовленный сценарий и получите окончательное подтверждение запуска: отправка может расходовать баланс.
Передайте тот же
seq_numи точную возвращённуюrevisionвPOST /api/v1/tools/broadcasts/execute-launch, с отдельным новымIdempotency-Key. Успех202:
{
"seqNum": 3,
"status": "queued"
}Чтобы не перепечатать и не выдумать revision, сформируйте тело из сохранённого успешного ответа подготовки:
jq -c '{seq_num: .seqNum, revision: .revision}' preparation.json > launch.jsonПередайте launch.json как JSON-тело execute только после подтверждения. Если черновик изменился после подготовки, сервер возвращает 409 CONFLICT: получите новую preparation и новое подтверждение, а не заменяйте hash вручную.
MCP использует серверную квитанцию: prepare_broadcast_launch возвращает preparation_id, payload_hash, expires_at, payload и launch. execute_broadcast_launch получает только точные preparation_id/payload_hash; REST revision-body не подходит вместо этой квитанции. Выполняйте пару из одного авторизованного контекста и не переносите подготовку между бизнесами или credential.
После запуска вызовите POST /api/v1/tools/broadcasts/status с {"seq_num":3} (201, scope broadcasts:read, отдельный Idempotency-Key); в MCP — get_broadcast_status. Читайте статус рассылки и последнюю execution вместе. Например, полный контрактный ответ показывает отдельные состояния и фактические счётчики:
{
"seqNum": 3,
"status": "draft",
"execution": {
"status": "completed",
"totalRecipients": 21,
"totalSent": 19,
"failed": 2,
"startedAt": "2026-09-30T11:00:00.000Z",
"completedAt": "2026-09-30T11:01:00.000Z"
}
}Это демонстрация формы ответа, не продолжение реального запуска из примера. Для свежего status-read после изменения состояния используйте новый ключ: повтор прежнего идемпотентного POST может вернуть прежний ответ из кэша. В списке и карточке предусмотрены состояния draft, scheduled, sending, completed, failed, cancelled; execution:null означает отсутствие записанного запуска.
Цепочки сообщений
GET /api/v1/tools/chains читает цепочки, POST создаёт shell по {"title":"Welcome"}, PATCH меняет название по {"seq_num":7,"title":"Welcome"}, а POST /api/v1/tools/chains/delete удаляет по {"seq_num":7}. Создание/удаление возвращают 201; создание требует Idempotency-Key и даёт:
{
"seqNum": 7,
"title": "Welcome",
"isActive": false,
"deeplinkCode": null
}Активность определяется настройкой шагов; поле isActive нельзя записать в shell-body. Через MCP используйте list_chain_steps, create_chain_step, update_chain_step, delete_chain_step с chain_seq_num и возвращённым номером шага. Оператор также настраивает цепочку в Telegram. У shell REST нет отдельного придуманного маршрута шагов или массового старта.
Для пакетного входа через MCP сначала вызовите prepare_chain_batch_entry. Пример аргументов, если указанные клиенты и цепочка существуют в выбранном бизнесе:
{
"chain_seq_num": 7,
"user_seq_nums": [
17,
18
],
"on_active": "noop"
}Допустимо 1..50 клиентов. on_active выбирается явно: noop сохраняет активный проход, deliver доставляет выбранный шаг без перемещения, restart прекращает активный проход перед новым. Покажите возвращённый неизменяемый сценарий человеку; после подтверждения execute_chain_batch_entry получает preparation_id и payload_hash из preparation. Повторно придумывать массив клиентов в execute нельзя. Проверка состояния, доставки и актуальных прав сохраняется при исполнении.
Кампании и ссылки на источники
Кампания связывает источник обращения с целевым содержимым и статистикой. GET /api/v1/tools/marketing и GET /api/v1/tools/marketing/links возвращают кампании/источники; для записи используйте POST/PATCH соответствующих путей. Например, новый источник в кампании 2:
{
"campaign_seq_num": 2,
"kind": "code_word",
"title": "Summer source",
"code_word": "summer",
"comment": null,
"is_active": true
}POST /api/v1/tools/marketing/links с новым Idempotency-Key возвращает 201:
{
"seqNum": 5,
"campaignSeqNum": 2,
"kind": "code_word",
"title": "Summer source",
"comment": null,
"wordNormalized": "summer",
"isActive": true,
"qrUrl": "https://storage.example.test/qr/opaque.png?sig=signed",
"qrUrlExpiresAt": "2026-09-30T10:15:00.000Z"
}В примере домен .test и подпись демонстрационные; рабочий QR URL берите из ответа и учитывайте qrUrlExpiresAt. Истёкший signed URL нельзя считать постоянным публичным адресом. В управлении кампаниями цель {"kind":"deeplink","entity_type":"product","entity_seq":3} использует guarded номер товара. Публичную ссылку на товар, событие или цепочку берите по серверному opaque-коду; не превращайте entity_seq, campaignSeqNum или seqNum в анонимный URL. Единственная читаемая строка адреса бизнеса — Client.slug.
Ошибки и повтор запросов
| Ответ | Что делать |
|---|---|
400 VALIDATION_ERROR / INVALID_REQUEST | Исправить конкретные поля, типы и строгую форму запроса; client_id и внутренние IDs не добавлять |
400 IDEMPOTENCY_KEY_REQUIRED | Добавить ключ к непустому POST; новый замысел получает новый ключ |
401 INVALID_API_KEY | Проверить допустимый транспорт credential; пройти нужную авторизацию |
403 INSUFFICIENT_SCOPE, PUBLISHABLE_KEY_NOT_ALLOWED, NO_ACTIVE_BOT | Сверить scope, вид ключа, активного бота и актуальный доступ |
404 NOT_FOUND | Получить актуальный номер в выбранном бизнесе; чужой объект также недоступен |
409 CONFLICT | Прочитать detail: старая версия сегмента, изменённый launch-снимок или ещё выполняющийся HTTP-запрос требуют разных действий |
422 INVALID_INPUT | Исправить значение, которое называет detail, например фильтр или зарезервированное кодовое слово; исправленное тело отправить с новым ключом |
422 IDEMPOTENCY_KEY_MISMATCH | Для изменённого тела использовать новый ключ; прежний ключ повторяет прежний запрос |
413 PAYLOAD_TOO_LARGE / ITEM_COUNT_EXCEEDED | Уменьшить объём и размер пакета |
429 RATE_LIMIT_EXCEEDED / RATE_LIMIT_UNAVAILABLE | Учитывать Retry-After, если он возвращён; отказ лимитера не означает успешную отправку |
500 INTERNAL_ERROR | Сохранить traceId, проверить состояние до повтора действия |
REST HTTP-ответ хранится 86400 секунд для применимых идемпотентных запросов. У PATCH ключ необязателен; если он передан, изменённое тело с тем же ключом даёт 422. Заголовки X-Client-Slug/X-Bot-Username помогают сверить контекст, а X-RateLimit-* — бюджет запроса. ETag не заменяет expectedVersion сохранённого сегмента или launch revision. Идемпотентность, справочник ошибок.
Точные формы отдельных операций: сегменты, рассылки, цепочки REST, кампании, цепочки MCP, рассылки MCP. Сегменты посещения мероприятия связывают маркетинг с регистрациями и записями. Внутренние разговорные AI-агенты советуют и передают запрос человеку; операции с расходованием денег выполняет только собственный scoped агент клиента через разрешённый сценарий.