Документация Bulk Template Message API
Этот API позволяет одновременно отправлять шаблонные сообщения нескольким получателям через канал WhatsApp.
Доставка сообщений обрабатывается асинхронно: API-запрос сразу возвращает bulkMessageId, а сообщения ставятся в очередь и обрабатываются в фоновом режиме.
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message/send.js
Ключевые возможности
- Отправка массовых шаблонных сообщений 1–5 000 получателям в одном запросе
- Персонализированные переменные для каждого получателя (HEADER, BODY, BUTTONS, CAROUSEL)
- Общий
defaultPayloadдля всех получателей с объединением с индивидуальнымpayloadполучателя (isMerge) - Отложенная отправка (
scheduleAt) - Указание получателей через
username(номер телефона),userIdилиsessionId - Отправка нескольких сообщений одному пользователю в одном массовом запросе
- Необязательный
referenceIdдля сопоставления записей с внешними системами - Автоматическое назначение диалогов пользователю или рабочей группе после отправки (
action)
Через этот API можно отправлять только шаблоны, одобренные Meta.
Название шаблона и код языка должны в точности совпадать с шаблоном, зарегистрированным в Meta Business Manager.
Параметры запроса
Параметры верхнего уровня
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
channelUsername | string | Да | Номер канала WhatsApp, с которого отправляется сообщение (например, "908506669933") |
connectorBrand | string | Да | Бренд коннектора канала. Сейчас поддерживается значение: "whatsapp" |
title | string | Нет | Название кампании. Используется для отображения на панели. По умолчанию: "-" |
scheduleAt | string (ISO 8601) | Нет | Дата и время отложенной отправки (например, "2026-06-10T10:00:00.000Z"). Если не указано, сообщения отправляются сразу. |
defaultPayload | object | Условно* | Шаблонная нагрузка по умолчанию, применяемая ко всем получателям. Обязательна, если у получателя нет собственного payload. |
recipients | array | Да | Список получателей. Минимум 1, максимум 5 000 получателей. |
action | object | Нет | Действие, применяемое к диалогу после отправки. assign-to-user или assign-to-workgroup. |
*Если у каждого получателя есть собственный payload, defaultPayload необязателен.
Структура получателя
Для каждого получателя нужно указать ровно один из параметров username, userId или sessionId. Несколько идентификаторов одновременно использовать нельзя, а если не указан ни один, будет ошибка.
Чтобы отправить несколько сообщений одному пользователю в одном массовом запросе, добавьте один и тот же идентификатор в список получателей несколько раз.
| Поле | Тип | Описание |
|---|---|---|
username | string | Номер телефона получателя (например, "905554443322"). Если пользователя нет в системе, он создаётся автоматически. |
userId | string | Идентификатор существующего пользователя в системе. |
sessionId | string | Идентификатор существующего диалога в системе. |
referenceId | string | Необязательный идентификатор для сопоставления с записями внешней системы (CRM, заказ, заявка и т. д.), до 256 символов. Если указан, должен быть уникальным в рамках одной рассылки. |
payload | object | Шаблонная нагрузка для конкретного получателя (необязательно). Если isMerge: true, она объединяется с defaultPayload. |
isMerge | boolean | Переопределяет поведение объединения для этого получателя (необязательно). Если не указано, используется defaultPayload.isMerge. |
Структура действия
| Поле | Тип | Описание |
|---|---|---|
action.key | string | "assign-to-user" назначает диалог конкретному сотруднику; "assign-to-workgroup" назначает его рабочей группе. |
action.value | string | Идентификатор целевого пользователя или рабочей группы. |
Структура шаблонной нагрузки
defaultPayload и payload конкретного получателя имеют одинаковую структуру. Для шаблонных сообщений необходимо указать type: "template".
{
"type": "template",
"template": {
"templateName": "order_confirmation",
"languageCode": "tr-TR",
"variables": []
},
"isMerge": true
}
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
type | string | Да | Тип нагрузки. Для шаблонных сообщений: "template" |
template.templateName | string | Да* | Название шаблона, зарегистрированного в Meta. В нагрузке получателя необязательно, если используется isMerge: true (наследуется из нагрузки по умолчанию). |
template.languageCode | string | Нет | Код языка шаблона (например, "tr", "en", "tr-TR", "en-US"). Должен в точности совпадать с языком, зарегистрированным в Meta. |
template.variables | array | Нет | Список переменных, применяемых к компонентам шаблона. Подробности ниже. |
isMerge | boolean | Нет | true: нагрузка получателя глубоко объединяется с defaultPayload. false или не указано: нагрузка получателя полностью заменяет defaultPayload. |
- Если
defaultPayload.isMerge: trueи получатель передаёт собственныйpayload, применяется глубокое объединение. - При глубоком объединении получатель может указать только
variables;templateNameиlanguageCodeнаследуются из нагрузки по умолчанию. - Поле
isMergeполучателя переопределяетdefaultPayload.isMerge. - Если получатель не передаёт
payload, всегда используетсяdefaultPayload.
Структура переменных
Каждый элемент массива variables соответствует компоненту шаблона. Тип компонента (type) может встречаться в массиве только один раз.
| type | Описание | parameters | cards |
|---|---|---|---|
"HEADER" | Компонент заголовка шаблона. Текстовая переменная или URL медиафайла (изображение, видео, документ) | Да | — |
"BODY" | Текстовые переменные тела шаблона | Да | — |
"BUTTONS" | Переменные динамического суффикса URL для кнопок | Да | — |
"CAROUSEL" | Компоненты карточек для шаблонов-каруселей | — | Да |
Форматы параметров
Поле parameters можно передавать в трёх разных форматах:
// Format 1: Array (index-based) — for placeholders like {{1}}, {{2}}, {{3}}
"parameters": ["value1", "value2", "value3"]
// Format 2: Object (numeric keys) — alternative representation for {{1}}, {{2}}
"parameters": { "1": "value1", "2": "value2" }
// Format 3: Object (named keys) — for placeholders like {{name}}, {{amount}}
"parameters": { "name": "John", "amount": "150 USD" }
- Если в вашем шаблоне Meta используются подстановки вида
{{1}},{{2}}, применяйте формат массива или объект с числовыми ключами. - Если в шаблоне используются именованные подстановки, например
{{firstName}}или{{orderTotal}}, применяйте объект с именованными ключами. - При использовании массивов важен порядок: первый элемент соответствует
{{1}}, второй —{{2}}и так далее.
Компонент HEADER
Используйте компонент HEADER, если заголовок шаблона содержит медиафайл (изображение, видео, документ) или динамический текст.
// Media header (image URL)
{
"type": "HEADER",
"parameters": ["https://example.com/product-image.jpg"]
}
// Text header variable
{
"type": "HEADER",
"parameters": ["Special Campaign"]
}
Компонент BODY
Используется для динамических текстовых переменных в теле шаблона.
// Array format — when the template uses {{1}}, {{2}}, {{3}}
{
"type": "BODY",
"parameters": ["John", "ORD-12345", "150.00 USD"]
}
// Named format — when the template uses {{name}}, {{orderAmount}}
{
"type": "BODY",
"parameters": {
"name": "John",
"orderAmount": "150.00 USD"
}
}
Компонент BUTTONS
Используется для кнопок с динамическими суффиксами URL. Если в шаблоне несколько URL-кнопок, последовательно нумеруются только кнопки с переменными (кнопки без переменных и кнопки FLOW игнорируются).
// Single URL button suffix variable
{
"type": "BUTTONS",
"parameters": ["tracking/ORD-12345"]
}
// Multiple URL button suffix variables (first URL button, second URL button)
{
"type": "BUTTONS",
"parameters": ["tracking/ORD-12345", "cancel/ORD-12345"]
}
Компонент CAROUSEL
Для шаблонов-каруселей переменные компонентов задаются отдельно для каждой карточки.
{
"type": "CAROUSEL",
"cards": [
{
"components": [
{
"type": "HEADER",
"parameters": ["https://example.com/card1.jpg"]
},
{
"type": "BODY",
"parameters": ["Product A", "99.00 USD"]
}
]
},
{
"components": [
{
"type": "HEADER",
"parameters": ["https://example.com/card2.jpg"]
},
{
"type": "BODY",
"parameters": ["Product B", "149.00 USD"]
}
]
}
]
}
Длина массива cards должна в точности совпадать с количеством карточек, определённых в шаблоне.
Примеры
1. Простой шаблон — без переменных, одинаковое содержимое для всех получателей
Это самый простой способ отправить статичный шаблон без переменных нескольким получателям.
{
"channelUsername": "908506669933",
"connectorBrand": "whatsapp",
"title": "General Announcement",
"defaultPayload": {
"type": "template",
"template": {
"templateName": "hello_world",
"languageCode": "tr-TR"
}
},
"recipients": [{ "username": "905554443301" }, { "username": "905554443302" }, { "username": "905554443303" }]
}
curl --location 'https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message/send.js' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN' \
--data '{
"channelUsername": "908506669933",
"connectorBrand": "whatsapp",
"title": "General Announcement",
"defaultPayload": {
"type": "template",
"template": {
"templateName": "hello_world",
"languageCode": "tr-TR"
}
},
"recipients": [
{ "username": "905554443301" },
{ "username": "905554443302" },
{ "username": "905554443303" }
]
}'
- Получатели, указанные через
username, создаются автоматически, если их ещё нет в системе - Все получатели используют один и тот же
defaultPayload; данные для конкретных получателей не требуются - Если
isMergeне указан, каждый получатель напрямую используетdefaultPayload
2. Шаблон с общими переменными тела
Один и тот же шаблон отправляется всем получателям с одинаковыми значениями переменных. В шаблоне есть подстановки вроде {{1}} и {{2}}.
{
"channelUsername": "908506669933",
"connectorBrand": "whatsapp",
"title": "Summer Campaign",
"defaultPayload": {
"type": "template",
"template": {
"templateName": "promo_notification",
"languageCode": "tr-TR",
"variables": [
{
"type": "BODY",
"parameters": ["30%", "July 31, 2026"]
}
]
}
},
"recipients": [{ "username": "905554443301" }, { "username": "905554443302" }]
}
- В этом примере тело шаблона может содержать текст вроде: «Скидка
{{1}}в нашей акции! Предложение действует до{{2}}.» parameters[0]заменяет{{1}}, аparameters[1]заменяет{{2}}
3. Персонализированный шаблон — переменные для каждого получателя с isMerge
Для каждого получателя используются разные значения переменных. Если задать isMerge: true в defaultPayload, получателям достаточно передать только variables; templateName и languageCode наследуются из нагрузки по умолчанию.
В этом примере шаблон содержит и медиазаголовок, и персонализированные переменные тела.
{
"channelUsername": "908506669933",
"connectorBrand": "whatsapp",
"title": "Personal Order Notification",
"defaultPayload": {
"type": "template",
"template": {
"templateName": "order_confirmation",
"languageCode": "tr-TR"
},
"isMerge": true
},
"recipients": [
{
"username": "905554443301",
"payload": {
"template": {
"variables": [
{
"type": "HEADER",
"parameters": ["https://s3.example.com/product-a.jpg"]
},
{
"type": "BODY",
"parameters": ["Ahmet", "ORD-001", "150.00 TRY"]
}
]
}
}
},
{
"username": "905554443302",
"payload": {
"template": {
"variables": [
{
"type": "HEADER",
"parameters": ["https://s3.example.com/product-b.jpg"]
},
{
"type": "BODY",
"parameters": ["Fatma", "ORD-002", "289.00 TRY"]
}
]
}
}
}
]
}
- Благодаря
isMerge: truetemplateNameне нужно повторять в нагрузке каждого получателя - Массив
variablesкаждого получателя полностью независим - URL медиафайла заголовка должен быть общедоступным
- Если в нагрузке получателя не указан
type, наследуетсяdefaultPayload.type
4. Переменная URL-кнопки
Используйте компонент BUTTONS, если в шаблоне есть кнопка с динамическим суффиксом URL. Например, номер отслеживания, добавляемый к базовому URL https://example.com/track/.
{
"channelUsername": "908506669933",
"connectorBrand": "whatsapp",
"title": "Shipment Tracking Notification",
"defaultPayload": {
"type": "template",
"template": {
"templateName": "shipment_tracking",
"languageCode": "tr-TR"
},
"isMerge": true
},
"recipients": [
{
"username": "905554443301",
"payload": {
"template": {
"variables": [
{
"type": "BODY",
"parameters": ["Ahmet", "TK-98765"]
},
{
"type": "BUTTONS",
"parameters": ["TK-98765"]
}
]
}
}
},
{
"username": "905554443302",
"payload": {
"template": {
"variables": [
{
"type": "BODY",
"parameters": ["Recep", "TK-12345"]
},
{
"type": "BUTTONS",
"parameters": ["TK-12345"]
}
]
}
}
}
]
}
- Параметры
BUTTONSсопоставляются в порядке кнопок, содержащих переменные - Кнопки FLOW и кнопки без переменных игнорируются; нумерация применяется только к кнопкам с динамическим URL
- Если URL кнопки в шаблоне —
https://example.com/track/{{1}}, тоparameters[0]заменяет{{1}}
5. Отложенная отправка
Запланируйте отправку сообщения на будущую дату и время. scheduleAt нужно передавать как метку времени UTC в формате ISO 8601.
{
"channelUsername": "908506669933",
"connectorBrand": "whatsapp",
"title": "Morning Campaign Message",
"scheduleAt": "2026-06-10T07:00:00.000Z",
"defaultPayload": {
"type": "template",
"template": {
"templateName": "morning_campaign",
"languageCode": "en-US"
},
"isMerge": true
},
"action": {
"key": "assign-to-workgroup",
"value": "WORKGROUP_ID"
},
"recipients": [
{
"username": "905554443301",
"payload": {
"template": {
"variables": [
{
"type": "BODY",
"parameters": { "name": "Ahmet", "discountRate": "25" }
}
]
}
}
},
{
"username": "905554443302",
"payload": {
"template": {
"variables": [
{
"type": "BODY",
"parameters": { "name": "Zeynep", "discountRate": "40" }
}
]
}
}
}
]
}
scheduleAtнужно передавать в часовом поясе UTC (например, для 10:00 по времени Турции используйте07:00:00.000Z)- В этом примере используется формат именованных параметров; в шаблоне должны быть подстановки вроде
{{name}}и{{discountRate}} - С параметром
actionдиалоги, созданные при доставке сообщения, автоматически назначаются указанной рабочей группе
Ответ
Успешный запрос возвращает bulkMessageId, с помощью которого можно отслеживать процесс доставки:
{
"bulkMessageId": "abc123xyz789"
}
Ответы с ошибкой
| Статус | Описание |
|---|---|
Channel not found | Не найден верифицированный канал, соответствующий channelUsername и connectorBrand |
Channel is not verified | Подходящий канал существует, но ещё не верифицирован |
invalidRequest | Для получателя указано несколько идентификаторов или отсутствует обязательная нагрузка |
channelNotFound | Не найден активный канал, соответствующий переданному channelId |
schema-error | Поле тела запроса не прошло проверку схемы (отсутствует обязательное поле, неверный тип или неподдерживаемое значение) |
Возвращённый bulkMessageId можно использовать в эндпоинтах ниже, чтобы запрашивать статистику доставки и останавливать процесс доставки.
Stats — статистика доставки
Возвращает текущее состояние доставки массовой рассылки. Возвращает количество ожидающих, успешных, неудачных и отменённых записей.
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message/stats.js
Параметры запроса
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
bulkMessageId | string | Да | Идентификатор отслеживаемой массовой рассылки (возвращается из createBulkPerRecipient) |
{
"bulkMessageId": "abc123xyz789"
}
curl --location 'https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message/stats.js' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN' \
--data '{
"bulkMessageId": "abc123xyz789"
}'
Ответ
{
"bulkMessage": {
"_id": "abc123xyz789",
"slug": "my-workspace",
"title": "Campaign Title",
"channelUsername": "908506669933",
"connectorBrand": "whatsapp",
"connectorSlug": "whatsapp-cloud",
"payload": {
"recipientCount": 100,
"defaultPayloadType": "template",
"jobId": "job_abc123"
},
"schedule": {
"date": "2026-06-10T07:00:00.000Z",
"type": "later"
},
"createdAt": "2026-06-08T10:00:00.000Z",
"updatedAt": "2026-06-08T10:30:00.000Z"
},
"stats": {
"pending": 45,
"success": 42,
"failed": 3,
"cancelled": 10,
"total": 100
}
}
Поля Stats
| Поле | Тип | Описание |
|---|---|---|
stats.pending | number | Количество записей, всё ещё ожидающих в очереди |
stats.success | number | Количество записей, успешно обработанных для доставки |
stats.failed | number | Количество записей, при доставке которых возникла ошибка |
stats.cancelled | number | Количество отменённых записей |
stats.total | number | Общее количество записей (pending + success + failed + cancelled) |
stats.success означает, что сообщение успешно передано системой. Это не гарантирует, что Meta доставила сообщение получателю. Последующие обновления статуса от Meta (такие как delivered, read или failed) не влияют на этот счётчик и здесь не отражаются.
- Эндпоинт stats: показывает состояние задания доставки (pending, success, failed, cancelled)
- Эндпоинт message-stats: показывает фактический статус сообщений (
pending,sending,sent,delivered,read,errorи т. д.) - Задание может быть успешным, но сообщение при этом ещё может быть не доставлено или не прочитано
Reference ID
referenceId — необязательное поле, которое можно использовать, чтобы сопоставлять записи доставки с идентификатором из вашей собственной системы для отслеживания (например, номер заказа, идентификатор заявки).
Если поле указано, оно должно быть уникальным в рамках рассылки (максимум 256 символов).
- Использовать необязательно
- Нельзя дублировать в рамках одной массовой рассылки
- Можно повторно использовать в разных массовых рассылках
Message Stats — статус сообщений WhatsApp
Возвращает статистику статусов сообщений массовой рассылки. В отличие от эндпоинта stats, здесь показывается фактический message.status каждой записи, а не статус задания.
Возможные статусы сообщений: pending, sending, sent, delivered, read, deleted, warning, error, unknown, not-sended
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message/message-stats.js
Параметры запроса
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
bulkMessageId | string | Да | Идентификатор запрашиваемой массовой рассылки |
{
"bulkMessageId": "abc123xyz789"
}
curl --location 'https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message/message-stats.js' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN' \
--data '{
"bulkMessageId": "abc123xyz789"
}'
Ответ
{
"bulkMessage": {
"_id": "abc123xyz789",
"slug": "my-workspace",
"type": "perRecipient",
"title": "Campaign Title"
},
"messageStats": {
"pending": 5,
"sending": 2,
"sent": 10,
"delivered": 45,
"read": 30,
"deleted": 2,
"warning": 1,
"error": 3,
"unknown": 0,
"not-sended": 2,
"no-message": 10,
"total": 120
}
}
Поля Message Stats
| Поле | Тип | Описание |
|---|---|---|
pending | number | Сообщения, которые ещё не отправлены |
sending | number | Сообщения, отправляемые в данный момент |
sent | number | Сообщения, переданные в WhatsApp, но ещё не доставленные |
delivered | number | Сообщения, доставленные на телефон получателя |
read | number | Сообщения, прочитанные получателем |
deleted | number | Удалённые сообщения |
warning | number | Сообщения с предупреждениями |
error | number | Сообщения с ошибками |
unknown | number | Сообщения с неизвестным статусом |
not-sended | number | Сообщения, которые не удалось отправить |
no-message | number | Записи, у которых ещё нет сообщения (всё ещё в очереди) |
total | number | Общее количество записей |
- Большое значение
no-messageозначает, что доставка ещё продолжается - Значение
deliveredпоказывает успешную доставку сообщений - Значение
readможно использовать для измерения вовлечённости в кампанию - Вы можете периодически опрашивать этот эндпоинт для отслеживания в реальном времени
Структура Options — постраничный вывод, фильтрация и сортировка
Параметр options, используемый в эндпоинтах list и list-with-messages, задаёт стандартную структуру для постраничного вывода, фильтрации и сортировки.
Поля Options
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
pagination | object | Нет | Настройки постраничного вывода |
filtering | object | Нет | Критерии фильтрации |
sorting | object | Нет | Настройки сортировки (например, {"createdAt": -1}) |
Структура Pagination
| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
currentPage | number | 1 | Номер запрашиваемой страницы |
pageItems | number | 50 | Количество записей на странице (максимум: 50) |
Структура Filtering
Фильтрация выполняется в формате запросов MongoDB. Можно фильтровать по полям записей. В эндпоинте list-with-messages можно также фильтровать по полям сообщений (например, message.status).
// Filter by record status
{
"options": {
"filtering": {
"status": "success"
}
}
}
// Filter by referenceId
{
"options": {
"filtering": {
"referenceId": "ORDER-12345"
}
}
}
// Filter by message status (only list-with-messages)
{
"options": {
"filtering": {
"message.status": "delivered"
}
}
}
// Filter by multiple statuses using $in (MongoDB operator)
{
"options": {
"filtering": {
"message.status": {
"$in": ["delivered", "read"]
}
}
}
}
// Exclude specific statuses using $nin (MongoDB operator)
{
"options": {
"filtering": {
"message.status": {
"$nin": ["error", "not-sended"]
}
}
}
}
Структура Sorting
Сортировка выполняется в формате сортировки MongoDB. 1 означает по возрастанию, -1 — по убыванию.
// Sort by creation date descending (newest first)
{
"options": {
"sorting": {
"createdAt": -1
}
}
}
// Sort by multiple fields
{
"options": {
"sorting": {
"status": 1,
"createdAt": -1
}
}
}
Пример комбинированного использования
{
"bulkMessageId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 2,
"pageItems": 50
},
"filtering": {
"message.status": "delivered"
},
"sorting": {
"createdAt": -1
}
}
}
Этот пример сортирует доставленные сообщения от новых к старым.
- Сочетайте
filteringиpaginationдля точечных запросов - Ответ содержит
options.pagination.totalCountиoptions.pagination.totalPagesдля навигации - Фильтр
message.statusработает только в эндпоинтеlist-with-messages
Records — сведения о записях и их список
Возвращает список всех записей доставки массовой рассылки. Каждая запись соответствует одному сообщению, отправленному получателю.
List — список записей
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message-records/list.js
Параметры запроса
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
bulkMessageId | string | Да | Идентификатор массовой рассылки, записи которой нужно вывести |
options | object | Нет | Параметры постраничного вывода, фильтрации и сортировки. Подробности см. в разделе Структура Options. |
Запрос — базовое использование
{
"bulkMessageId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
}
}
}
Запрос — фильтр по конкретному статусу
{
"bulkMessageId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
},
"filtering": {
"status": "success"
}
}
}
Выводит только записи об успешной доставке (record.status = "success").
Ответ
{
"bulkMessageRecords": [
{
"_id": "record_1",
"bulkMessageId": "abc123xyz789",
"slug": "my-workspace",
"userId": "user_123",
"sessionId": "session_456",
"messageId": "msg_789",
"referenceId": "ORDER-12345",
"status": "success",
"createdAt": "2026-06-10T10:00:00.000Z"
}
],
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50,
"totalCount": 150,
"totalPages": 3
},
"sorting": {},
"filtering": {}
}
}
List With Messages — список со сведениями о сообщениях
Имеет те же возможности, что и эндпоинт list (постраничный вывод, фильтрация, сортировка). Единственное отличие: если у записи есть messageId, возвращается и связанный объект message. Это позволяет увидеть статус сообщения (delivered, read, error и т. д.) и его нагрузку одним запросом.
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message-records/list-with-messages.js
Запрос — базовое использование
{
"bulkMessageId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
}
}
}
Запрос — фильтр по статусу сообщения
{
"bulkMessageId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
},
"filtering": {
"message.status": "delivered"
}
}
}
Этот пример выбирает только сообщения со статусом "delivered".
Запрос — список неудачных сообщений
{
"bulkMessageId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
},
"filtering": {
"message.status": "error"
}
}
}
Используется для просмотра сообщений, при доставке которых возникли ошибки.
Ответ
{
"bulkMessageRecords": [
{
"_id": "record_1",
"bulkMessageId": "abc123xyz789",
"userId": "user_123",
"messageId": "msg_789",
"referenceId": "ORDER-12345",
"status": "success",
"message": {
"_id": "msg_789",
"status": "delivered",
"payload": {
"type": "template",
"template": {
"templateName": "order_notification"
}
},
"createdAt": "2026-06-10T10:01:00.000Z",
"deliveredAt": "2026-06-10T10:01:05.000Z"
}
}
],
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50,
"totalCount": 150,
"totalPages": 3
},
"sorting": {},
"filtering": {}
}
}
Поля записи
| Поле | Тип | Описание |
|---|---|---|
_id | string | Идентификатор записи |
bulkMessageId | string | Идентификатор массовой рассылки, которой принадлежит запись |
userId | string | Идентификатор пользователя-получателя |
sessionId | string | Идентификатор диалога |
messageId | string | Идентификатор отправленного сообщения (null, если ещё не отправлено) |
referenceId | string | Необязательный идентификатор для сопоставления (если указан) |
status | string | Статус записи: pending, success, failed, cancelled |
message | object | Сведения о сообщении (только в list-with-messages) |
Сравнение List и List-With-Messages
| Возможность | list | list-with-messages |
|---|---|---|
| Постраничный вывод | Да | Да |
| Фильтрация | Да (только по полям записи) | Да (по полям записи и сообщения) |
| Объект сообщения | Нет | Да (если есть messageId) |
| Производительность | Быстро | Средне (выполняется JOIN) |
| Фильтр message.status | Недоступен | Доступен |
- list: быстро вывести все записи, отфильтровать по referenceId, проверить статусы записей
- list-with-messages: посмотреть статусы сообщений WhatsApp (delivered, read), изучить нагрузку сообщений
- Примеры фильтров:
{"status": "failed"}— записи с неудачной доставкой{"referenceId": "ORDER-123"}— конкретный reference ID{"message.status": "delivered"}— доставленные сообщения (только list-with-messages){"message.status": "read"}— прочитанные сообщения (только list-with-messages){"message.status": "error"}— сообщения с ошибками (только list-with-messages){"message.status": {"$in": ["delivered", "read"]}}— сообщения, которые доставлены или прочитаны (только list-with-messages){"message.status": {"$nin": ["error", "not-sended"]}}— сообщения без ошибок и неотправленных (только list-with-messages){"status": {"$in": ["success", "pending"]}}— записи, которые успешны или ожидают
- Эндпоинт
listработает быстрее; используйте его для обычной проверки статусов - Используйте
list-with-messages, когда нужны сведения о сообщениях - Максимальное количество записей на странице (pageItems) — 50; если не указано, по умолчанию 50
- Фильтр
message.statusработает только вlist-with-messages - У записей с null в messageId объект
messageбудет null
Stop — отмена доставки
Останавливает выполняющуюся доставку массовой рассылки. Задание в очереди отменяется, а все записи со статусом pending переводятся в статус cancelled. Записи, уже обработанные как success или failed, не затрагиваются.
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message/stop.js
Это действие нельзя отменить. Остановленную доставку нельзя возобновить.
Параметры запроса
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
bulkMessageId | string | Да | Идентификатор останавливаемой массовой рассылки |
{
"bulkMessageId": "abc123xyz789"
}
curl --location 'https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message/stop.js' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN' \
--data '{
"bulkMessageId": "abc123xyz789"
}'
Ответ
При успешном запросе тело ответа пустое. Статус HTTP 200 означает, что операция выполнена успешно.
{}
- Остановить можно только массовые рассылки, созданные через этот API
- После остановки доставки можно использовать эндпоинт
stats, чтобы проверить количество отменённых записей - Если массовая рассылка не найдена, API возвращает ошибку:
bulkMessageNotFound