Bulk Template Message API Documentation
This API allows you to send template messages to multiple recipients simultaneously through the WhatsApp channel.
Message delivery is processed asynchronously; the API request immediately returns a bulkMessageId, while messages are queued and processed in the background.
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message/send.js
Key Features
- Send bulk template messages to 1–5,000 recipients in a single request
- Personalized variables for each recipient (HEADER, BODY, BUTTONS, CAROUSEL)
- Shared
defaultPayloadfor all recipients with recipient-specificpayloadmerging (isMerge) - Scheduled delivery (
scheduleAt) - Specify recipients using
username(phone number),userId, orsessionId - Send multiple messages to the same user within a single bulk request
- Optional
referenceIdfor tracking records with external systems - Automatically assign conversations to a user or workgroup after sending (
action)
This API can only send templates that have been approved by Meta.
The template name and language code must exactly match the template registered in Meta Business Manager.
Request Parameters
Top-Level Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
channelUsername | string | Yes | WhatsApp channel number used to send the message (e.g. "908506669933") |
connectorBrand | string | Yes | Channel connector brand. Currently supported value: "whatsapp" |
title | string | No | Campaign title. Used for display in the dashboard. Default: "-" |
scheduleAt | string (ISO 8601) | No | Scheduled delivery date and time (e.g. "2026-06-10T10:00:00.000Z"). If omitted, messages are sent immediately. |
defaultPayload | object | Conditional* | Default template payload applied to all recipients. Required if a recipient does not provide its own payload. |
recipients | array | Yes | Recipient list. Minimum 1, maximum 5,000 recipients. |
action | object | No | Action applied to the conversation after sending. assign-to-user or assign-to-workgroup. |
*If every recipient provides its own payload, defaultPayload is optional.
Recipient Structure
For each recipient, exactly one of username, userId, or sessionId must be provided. Multiple identifiers cannot be used together, and omitting all of them will result in an error.
To send multiple messages to the same user within a single bulk request, add the same identifier to the recipient list multiple times.
| Field | Type | Description |
|---|---|---|
username | string | Recipient's phone number (e.g. "905554443322"). If the user does not exist in the system, it is created automatically. |
userId | string | ID of an existing user in the system. |
sessionId | string | ID of an existing conversation session in the system. |
referenceId | string | Optional reference ID (max 256 characters) for matching with external system records (CRM, order, ticket, etc.). Must be unique within the bulk if provided. |
payload | object | Recipient-specific template payload (optional). If isMerge: true, it is merged with defaultPayload. |
isMerge | boolean | Overrides merge behavior for this recipient (optional). If omitted, defaultPayload.isMerge is used. |
Action Structure
| Field | Type | Description |
|---|---|---|
action.key | string | "assign-to-user" assigns the conversation to a specific agent; "assign-to-workgroup" assigns it to a workgroup. |
action.value | string | ID of the target user or workgroup. |
Template Payload Structure
defaultPayload and recipient-specific payload share the same structure. For template messages, type: "template" must be specified.
{
"type": "template",
"template": {
"templateName": "order_confirmation",
"languageCode": "tr-TR",
"variables": []
},
"isMerge": true
}
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Payload type. For template messages: "template" |
template.templateName | string | Yes* | Template name registered in Meta. Optional in recipient payloads when isMerge: true is used (inherits from default). |
template.languageCode | string | No | Template language code (e.g. "tr", "en", "tr-TR", "en-US"). Must exactly match the language registered in Meta. |
template.variables | array | No | List of variables applied to template components. Detailed below. |
isMerge | boolean | No | true: recipient payload is deep-merged with defaultPayload. false or omitted: recipient payload completely replaces defaultPayload. |
- If
defaultPayload.isMerge: trueand the recipient provides its ownpayload, a deep merge is applied. - With deep merge, the recipient may provide only
variables;templateNameandlanguageCodeare inherited from the default payload. - The recipient's
isMergefield overridesdefaultPayload.isMerge. - If a recipient does not provide a
payload,defaultPayloadis always used.
Variables Structure
Each item in the variables array corresponds to a template component. A component type (type) may appear only once in the array.
| type | Description | parameters | cards |
|---|---|---|---|
"HEADER" | Template header component. Text variable or media URL (image, video, document) | Yes | — |
"BODY" | Template body text variables | Yes | — |
"BUTTONS" | Dynamic URL suffix variables for buttons | Yes | — |
"CAROUSEL" | Card components for carousel templates | — | Yes |
Parameter Formats
The parameters field can be provided in three different formats:
// 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" }
- If your Meta template uses placeholders like
{{1}},{{2}}, use either the array format or numeric-key object format. - If your template uses named placeholders such as
{{firstName}}or{{orderTotal}}, use the named-key object format. - When using arrays, order matters: the first element maps to
{{1}}, the second to{{2}}, and so on.
HEADER Component
Use the HEADER component when the template header contains media (image, video, document) or dynamic text.
// Media header (image URL)
{
"type": "HEADER",
"parameters": ["https://example.com/product-image.jpg"]
}
// Text header variable
{
"type": "HEADER",
"parameters": ["Special Campaign"]
}
BODY Component
Used for dynamic text variables within the template 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 Component
Used for buttons with dynamic URL suffixes. If the template contains multiple URL buttons, only buttons with variables are indexed sequentially (buttons without variables or FLOW buttons are ignored).
// 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 Component
For carousel templates, component variables are defined separately for each card.
{
"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"]
}
]
}
]
}
The length of the cards array must exactly match the number of cards defined in the template.
Examples
1. Simple Template — No Variables, Same Content for All Recipients
This is the simplest way to send a static template without variables to multiple recipients.
{
"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" }
]
}'
- Recipients specified via
usernameare automatically created if they do not already exist in the system - All recipients use the same
defaultPayload; no recipient-specific data is required - When
isMergeis not specified, each recipient directly uses thedefaultPayload
2. Template with Shared Body Variables
The same template is sent to all recipients using identical variable values. The template contains placeholders such as {{1}} and {{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" }]
}
- In this example, the template body might contain content such as: "Enjoy a
{{1}}discount in our campaign! Offer valid until{{2}}." parameters[0]replaces{{1}}, whileparameters[1]replaces{{2}}
3. Personalized Template — Per-Recipient Variables with isMerge
Different variable values are used for each recipient. By setting isMerge: true in the defaultPayload, recipients only need to provide variables; templateName and languageCode are inherited from the default payload.
In this example, the template includes both a media header and personalized body variables.
{
"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"]
}
]
}
}
}
]
}
- Thanks to
isMerge: true,templateNamedoes not need to be repeated in each recipient payload - Each recipient's
variablesarray is completely independent - The header media URL must be publicly accessible
- If
typeis omitted in the recipient payload,defaultPayload.typeis inherited
4. URL Button Variable
Use the BUTTONS component when the template contains a button with a dynamic URL suffix. For example, a tracking number appended to the base 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"]
}
]
}
}
}
]
}
BUTTONSparameters are matched according to the order of buttons that contain variables- FLOW buttons and buttons without variables are ignored; indexing only applies to dynamic URL buttons
- If the template button URL is
https://example.com/track/{{1}}, thenparameters[0]replaces{{1}}
5. Scheduled Delivery
Schedule a message to be sent at a future date and time. scheduleAt must be provided as an ISO 8601 UTC timestamp.
{
"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" }
}
]
}
}
}
]
}
scheduleAtmust be provided in the UTC time zone (e.g., for 10:00 AM Turkey time, use07:00:00.000Z)- This example uses the named parameter format; the template should contain placeholders such as
{{name}}and{{discountRate}} - With
action, conversations created by the message delivery are automatically assigned to the specified workgroup
Response
A successful request returns a bulkMessageId, which can be used to track the delivery process:
{
"bulkMessageId": "abc123xyz789"
}
Error Responses
| Status | Description |
|---|---|
Channel not found | No verified channel matching channelUsername and connectorBrand was found |
Channel is not verified | The matched channel exists but has not yet been verified |
invalidRequest | Multiple identifiers were provided for a recipient or a required payload is missing |
channelNotFound | No active channel matching the provided channelId was found |
schema-error | A field in the request body failed schema validation (missing required field, incorrect type, or unsupported value) |
The returned bulkMessageId can be used with the endpoints below to query delivery statistics and stop the delivery process.
Stats — Delivery Statistics
Retrieves the current delivery status of a bulk message. Returns counts for pending, successful, failed, and cancelled records.
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message/stats.js
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
bulkMessageId | string | Yes | ID of the bulk message to track (returned from 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"
}'
Response
{
"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 Fields
| Field | Type | Description |
|---|---|---|
stats.pending | number | Number of records still waiting in the queue |
stats.success | number | Number of records successfully processed for delivery |
stats.failed | number | Number of records that encountered a delivery error |
stats.cancelled | number | Number of cancelled records |
stats.total | number | Total number of records (pending + success + failed + cancelled) |
stats.success indicates that the message was successfully handed off by the system. It does not guarantee that Meta delivered the message to the recipient. Subsequent status updates generated by Meta (such as delivered, read, or failed) do not affect this counter and are not reflected here.
- stats endpoint: Shows the delivery job status (pending, success, failed, cancelled)
- message-stats endpoint: Shows actual message status (
pending,sending,sent,delivered,read,error, etc.) - A job may be successful, but the message might not yet be delivered/read
Reference ID
The referenceId is an optional field that you can use to match delivery records with an ID from your own system for tracking purposes (e.g., order number, ticket ID).
If provided, it must be unique within the bulk (max 256 characters).
- Not required for use
- Cannot be duplicated within the same bulk message
- Can be reused across different bulk messages
Message Stats — WhatsApp Message Status
Retrieves the message status statistics for a bulk message. Unlike the stats endpoint, this shows the actual message.status for each record instead of the job status.
Possible message statuses: 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
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
bulkMessageId | string | Yes | ID of the bulk message to query |
{
"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"
}'
Response
{
"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 Fields
| Field | Type | Description |
|---|---|---|
pending | number | Messages not yet sent |
sending | number | Messages currently being sent |
sent | number | Messages handed to WhatsApp, not yet delivered |
delivered | number | Messages delivered to recipient's phone |
read | number | Messages read by the recipient |
deleted | number | Deleted messages |
warning | number | Messages with warnings |
error | number | Messages with errors |
unknown | number | Messages with unknown status |
not-sended | number | Messages that could not be sent |
no-message | number | Records without message yet (still queued) |
total | number | Total record count |
- High
no-messagecount indicates delivery is still in progress deliveredcount shows successful message deliveryreadcount can be used to measure campaign engagement- You can poll this endpoint periodically for real-time tracking
Options Structure — Pagination, Filtering, and Sorting
The options parameter used in list and list-with-messages endpoints provides a standard structure for pagination, filtering, and sorting.
Options Fields
| Field | Type | Required | Description |
|---|---|---|---|
pagination | object | No | Pagination settings |
filtering | object | No | Filtering criteria |
sorting | object | No | Sorting settings (e.g., {"createdAt": -1}) |
Pagination Structure
| Field | Type | Default | Description |
|---|---|---|---|
currentPage | number | 1 | Page number to retrieve |
pageItems | number | 50 | Number of records per page (maximum: 50) |
Filtering Structure
Filtering is done using MongoDB query format. You can filter by record fields. In the list-with-messages endpoint, you can also filter by message fields (e.g., 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 Structure
Sorting is done using MongoDB sort format. 1 means ascending, -1 means descending.
// Sort by creation date descending (newest first)
{
"options": {
"sorting": {
"createdAt": -1
}
}
}
// Sort by multiple fields
{
"options": {
"sorting": {
"status": 1,
"createdAt": -1
}
}
}
Combined Usage Example
{
"bulkMessageId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 2,
"pageItems": 50
},
"filtering": {
"message.status": "delivered"
},
"sorting": {
"createdAt": -1
}
}
}
This example sorts delivered messages from newest to oldest.
- Combine
filteringandpaginationfor targeted queries - Response includes
options.pagination.totalCountandoptions.pagination.totalPagesfor navigation message.statusfilter only works in thelist-with-messagesendpoint
Records — Record Details and Listing
Lists all delivery records for a bulk message. Each record represents a single message sent to a recipient.
List — Record List
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message-records/list.js
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
bulkMessageId | string | Yes | ID of the bulk message to list |
options | object | No | Pagination, filtering, sorting options. See Options Structure for details. |
Request — Basic Usage
{
"bulkMessageId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
}
}
}
Request — Filter by Specific Status
{
"bulkMessageId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
},
"filtering": {
"status": "success"
}
}
}
Lists only successful delivery records (record.status = "success").
Response
{
"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 with Message Details
Has the same features as the list endpoint (pagination, filtering, sorting). The only difference: if a record has a messageId, the related message object is also returned. This allows you to see the message status (delivered, read, error, etc.) and payload in a single query.
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message-records/list-with-messages.js
Request — Basic Usage
{
"bulkMessageId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
}
}
}
Request — Filter by Message Status
{
"bulkMessageId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
},
"filtering": {
"message.status": "delivered"
}
}
}
This example fetches only messages with "delivered" status.
Request — List Failed Messages
{
"bulkMessageId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
},
"filtering": {
"message.status": "error"
}
}
}
Used to review messages that encountered delivery errors.
Response
{
"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": {}
}
}
Record Fields
| Field | Type | Description |
|---|---|---|
_id | string | Record ID |
bulkMessageId | string | Bulk message ID this record belongs to |
userId | string | Recipient user ID |
sessionId | string | Conversation session ID |
messageId | string | Sent message ID (null if not sent yet) |
referenceId | string | Optional reference ID (if provided) |
status | string | Record status: pending, success, failed, cancelled |
message | object | Message details (only in list-with-messages) |
List vs List-With-Messages Comparison
| Feature | list | list-with-messages |
|---|---|---|
| Pagination | Yes | Yes |
| Filtering | Yes (record fields only) | Yes (record + message fields) |
| Message Object | No | Yes (if messageId exists) |
| Performance | Fast | Medium (performs JOIN) |
| message.status Filter | Not available | Available |
- list: Quickly list all records, filter by referenceId, check record statuses
- list-with-messages: View WhatsApp message statuses (delivered, read), inspect message payloads
- Filtering examples:
{"status": "failed"}— Failed delivery records{"referenceId": "ORDER-123"}— Specific reference ID{"message.status": "delivered"}— Delivered messages (list-with-messages only){"message.status": "read"}— Read messages (list-with-messages only){"message.status": "error"}— Messages with errors (list-with-messages only){"message.status": {"$in": ["delivered", "read"]}}— Messages that are either delivered or read (list-with-messages only){"message.status": {"$nin": ["error", "not-sended"]}}— Messages excluding errors and not-sent (list-with-messages only){"status": {"$in": ["success", "pending"]}}— Records that are successful or pending
listendpoint is faster; prefer it for general status checks- Use
list-with-messageswhen message details are needed - Maximum records per page (pageItems) is 50; defaults to 50 if not specified
message.statusfilter only works inlist-with-messages- Records with null messageId will have null
messageobjects
Stop — Cancel Delivery
Stops an ongoing bulk message delivery. The queued job is cancelled, and all pending records are moved to the cancelled status. Records that have already been processed as success or failed are not affected.
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message/stop.js
This action cannot be undone. A stopped delivery cannot be resumed.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
bulkMessageId | string | Yes | ID of the bulk message to stop |
{
"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"
}'
Response
For a successful request, the response body is empty. An HTTP 200 status indicates that the operation completed successfully.
{}
- Only bulk messages created through this API can be stopped
- After stopping a delivery, you can use the
statsendpoint to verify the number of cancelled records - If the bulk message cannot be found, the API returns the error:
bulkMessageNotFound