Documentation de l’API Bulk Template Message
Cette API vous permet d’envoyer simultanément des messages modèles à plusieurs destinataires via le canal WhatsApp.
L’envoi est traité de manière asynchrone : la requête API renvoie immédiatement un bulkMessageId, tandis que les messages sont mis en file d’attente et traités en arrière-plan.
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message/send.js
Principales fonctionnalités
- Envoyez des messages modèles en masse à 1 à 5 000 destinataires en une seule requête
- Variables personnalisées pour chaque destinataire (HEADER, BODY, BUTTONS, CAROUSEL)
- Un
defaultPayloadpartagé par tous les destinataires, avec fusion dupayloadpropre à chaque destinataire (isMerge) - Envoi programmé (
scheduleAt) - Indiquez les destinataires avec
username(numéro de téléphone),userIdousessionId - Envoyez plusieurs messages au même utilisateur dans une seule requête en masse
referenceIdfacultatif pour rapprocher les enregistrements de systèmes externes- Attribuez automatiquement les conversations à un utilisateur ou à un groupe de travail après l’envoi (
action)
Cette API ne peut envoyer que des modèles approuvés par Meta.
Le nom du modèle et le code de langue doivent correspondre exactement au modèle enregistré dans Meta Business Manager.
Paramètres de la requête
Paramètres de premier niveau
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
channelUsername | string | Oui | Numéro du canal WhatsApp utilisé pour envoyer le message (par ex. "908506669933") |
connectorBrand | string | Oui | Marque du connecteur de canal. Valeur actuellement prise en charge : "whatsapp" |
title | string | Non | Titre de la campagne. Utilisé pour l’affichage dans le tableau de bord. Par défaut : "-" |
scheduleAt | string (ISO 8601) | Non | Date et heure d’envoi programmé (par ex. "2026-06-10T10:00:00.000Z"). Si omis, les messages sont envoyés immédiatement. |
defaultPayload | object | Conditionnel* | Payload de modèle par défaut appliqué à tous les destinataires. Obligatoire si un destinataire ne fournit pas son propre payload. |
recipients | array | Oui | Liste des destinataires. Minimum 1, maximum 5 000 destinataires. |
action | object | Non | Action appliquée à la conversation après l’envoi. assign-to-user ou assign-to-workgroup. |
*Si chaque destinataire fournit son propre payload, defaultPayload est facultatif.
Structure d’un destinataire
Pour chaque destinataire, un seul des champs username, userId ou sessionId doit être fourni. Plusieurs identifiants ne peuvent pas être utilisés ensemble, et les omettre tous provoque une erreur.
Pour envoyer plusieurs messages au même utilisateur dans une seule requête en masse, ajoutez plusieurs fois le même identifiant à la liste des destinataires.
| Champ | Type | Description |
|---|---|---|
username | string | Numéro de téléphone du destinataire (par ex. "905554443322"). Si l’utilisateur n’existe pas dans le système, il est créé automatiquement. |
userId | string | Identifiant d’un utilisateur existant dans le système. |
sessionId | string | Identifiant d’une session de conversation existante dans le système. |
referenceId | string | Identifiant de référence facultatif (256 caractères maximum) pour le rapprochement avec les enregistrements de systèmes externes (CRM, commande, ticket, etc.). Doit être unique dans l’envoi en masse s’il est fourni. |
payload | object | Payload de modèle propre au destinataire (facultatif). Si isMerge: true, il est fusionné avec defaultPayload. |
isMerge | boolean | Remplace le comportement de fusion pour ce destinataire (facultatif). Si omis, defaultPayload.isMerge est utilisé. |
Structure de l’action
| Champ | Type | Description |
|---|---|---|
action.key | string | "assign-to-user" attribue la conversation à un agent précis ; "assign-to-workgroup" l’attribue à un groupe de travail. |
action.value | string | Identifiant de l’utilisateur ou du groupe de travail cible. |
Structure du payload de modèle
defaultPayload et le payload propre à un destinataire ont la même structure. Pour les messages modèles, type: "template" doit être indiqué.
{
"type": "template",
"template": {
"templateName": "order_confirmation",
"languageCode": "tr-TR",
"variables": []
},
"isMerge": true
}
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
type | string | Oui | Type de payload. Pour les messages modèles : "template" |
template.templateName | string | Oui* | Nom du modèle enregistré dans Meta. Facultatif dans les payloads de destinataires lorsque isMerge: true est utilisé (hérité du payload par défaut). |
template.languageCode | string | Non | Code de langue du modèle (par ex. "tr", "en", "tr-TR", "en-US"). Doit correspondre exactement à la langue enregistrée dans Meta. |
template.variables | array | Non | Liste des variables appliquées aux composants du modèle. Détaillée ci-dessous. |
isMerge | boolean | Non | true : le payload du destinataire est fusionné en profondeur avec defaultPayload. false ou omis : le payload du destinataire remplace entièrement defaultPayload. |
- Si
defaultPayload.isMerge: trueet que le destinataire fournit son proprepayload, une fusion en profondeur est appliquée. - Avec la fusion en profondeur, le destinataire peut ne fournir que
variables;templateNameetlanguageCodesont hérités du payload par défaut. - Le champ
isMergedu destinataire remplacedefaultPayload.isMerge. - Si un destinataire ne fournit pas de
payload,defaultPayloadest toujours utilisé.
Structure des variables
Chaque élément du tableau variables correspond à un composant du modèle. Un type de composant (type) ne peut apparaître qu’une seule fois dans le tableau.
| type | Description | parameters | cards |
|---|---|---|---|
"HEADER" | Composant d’en-tête du modèle. Variable de texte ou URL de média (image, vidéo, document) | Oui | — |
"BODY" | Variables de texte du corps du modèle | Oui | — |
"BUTTONS" | Variables de suffixe d’URL dynamique pour les boutons | Oui | — |
"CAROUSEL" | Composants de cartes pour les modèles carrousel | — | Oui |
Formats des paramètres
Le champ parameters peut être fourni sous trois formats différents :
// 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" }
- Si votre modèle Meta utilise des espaces réservés comme
{{1}},{{2}}, utilisez le format tableau ou le format objet à clés numériques. - Si votre modèle utilise des espaces réservés nommés comme
{{firstName}}ou{{orderTotal}}, utilisez le format objet à clés nommées. - Avec les tableaux, l’ordre compte : le premier élément correspond à
{{1}}, le deuxième à{{2}}, et ainsi de suite.
Composant HEADER
Utilisez le composant HEADER lorsque l’en-tête du modèle contient un média (image, vidéo, document) ou du texte dynamique.
// Media header (image URL)
{
"type": "HEADER",
"parameters": ["https://example.com/product-image.jpg"]
}
// Text header variable
{
"type": "HEADER",
"parameters": ["Special Campaign"]
}
Composant BODY
Utilisé pour les variables de texte dynamiques dans le corps du modèle.
// 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"
}
}
Composant BUTTONS
Utilisé pour les boutons avec un suffixe d’URL dynamique. Si le modèle contient plusieurs boutons URL, seuls les boutons qui ont des variables sont indexés séquentiellement (les boutons sans variables ou les boutons FLOW sont ignorés).
// 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"]
}
Composant CAROUSEL
Pour les modèles carrousel, les variables des composants sont définies séparément pour chaque carte.
{
"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"]
}
]
}
]
}
La longueur du tableau cards doit correspondre exactement au nombre de cartes définies dans le modèle.
Exemples
1. Modèle simple — sans variables, même contenu pour tous les destinataires
C’est la façon la plus simple d’envoyer à plusieurs destinataires un modèle statique sans variables.
{
"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" }
]
}'
- Les destinataires indiqués via
usernamesont créés automatiquement s’ils n’existent pas déjà dans le système - Tous les destinataires utilisent le même
defaultPayload; aucune donnée propre à un destinataire n’est nécessaire - Quand
isMergen’est pas indiqué, chaque destinataire utilise directement ledefaultPayload
2. Modèle avec variables de corps partagées
Le même modèle est envoyé à tous les destinataires avec des valeurs de variables identiques. Le modèle contient des espaces réservés tels que {{1}} et {{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" }]
}
- Dans cet exemple, le corps du modèle pourrait contenir un texte comme : « Profitez d’une remise de
{{1}}pendant notre campagne ! Offre valable jusqu’au{{2}}. » parameters[0]remplace{{1}}, tandis queparameters[1]remplace{{2}}
3. Modèle personnalisé — variables par destinataire avec isMerge
Des valeurs de variables différentes sont utilisées pour chaque destinataire. En définissant isMerge: true dans le defaultPayload, les destinataires n’ont qu’à fournir variables ; templateName et languageCode sont hérités du payload par défaut.
Dans cet exemple, le modèle comprend à la fois un en-tête média et des variables de corps personnalisées.
{
"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"]
}
]
}
}
}
]
}
- Grâce à
isMerge: true,templateNamen’a pas besoin d’être répété dans chaque payload de destinataire - Le tableau
variablesde chaque destinataire est entièrement indépendant - L’URL du média d’en-tête doit être accessible publiquement
- Si
typeest omis dans le payload du destinataire,defaultPayload.typeest hérité
4. Variable de bouton URL
Utilisez le composant BUTTONS lorsque le modèle contient un bouton avec un suffixe d’URL dynamique. Par exemple, un numéro de suivi ajouté à l’URL de base 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"]
}
]
}
}
}
]
}
- Les paramètres
BUTTONSsont associés selon l’ordre des boutons qui contiennent des variables - Les boutons FLOW et les boutons sans variables sont ignorés ; l’indexation ne s’applique qu’aux boutons URL dynamiques
- Si l’URL du bouton du modèle est
https://example.com/track/{{1}}, alorsparameters[0]remplace{{1}}
5. Envoi programmé
Programmez l’envoi d’un message à une date et une heure futures. scheduleAt doit être fourni sous forme d’horodatage 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" }
}
]
}
}
}
]
}
scheduleAtdoit être fourni dans le fuseau horaire UTC (par ex., pour 10 h 00 heure de Turquie, utilisez07:00:00.000Z)- Cet exemple utilise le format de paramètres nommés ; le modèle doit contenir des espaces réservés tels que
{{name}}et{{discountRate}} - Avec
action, les conversations créées par l’envoi du message sont automatiquement attribuées au groupe de travail indiqué
Réponse
Une requête réussie renvoie un bulkMessageId, qui peut servir à suivre le processus d’envoi :
{
"bulkMessageId": "abc123xyz789"
}
Réponses d’erreur
| Statut | Description |
|---|---|
Channel not found | Aucun canal vérifié correspondant à channelUsername et connectorBrand n’a été trouvé |
Channel is not verified | Le canal correspondant existe mais n’a pas encore été vérifié |
invalidRequest | Plusieurs identifiants ont été fournis pour un destinataire ou un payload obligatoire est manquant |
channelNotFound | Aucun canal actif correspondant au channelId fourni n’a été trouvé |
schema-error | Un champ du corps de la requête a échoué à la validation du schéma (champ obligatoire manquant, type incorrect ou valeur non prise en charge) |
Le bulkMessageId renvoyé peut être utilisé avec les endpoints ci-dessous pour consulter les statistiques d’envoi et arrêter le processus d’envoi.
Stats — statistiques d’envoi
Récupère l’état d’envoi actuel d’un message en masse. Renvoie le nombre d’enregistrements en attente, réussis, en échec et annulés.
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message/stats.js
Paramètres de la requête
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
bulkMessageId | string | Oui | Identifiant du message en masse à suivre (renvoyé par 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"
}'
Réponse
{
"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
}
}
Champs de stats
| Champ | Type | Description |
|---|---|---|
stats.pending | number | Nombre d’enregistrements encore en attente dans la file |
stats.success | number | Nombre d’enregistrements traités avec succès pour l’envoi |
stats.failed | number | Nombre d’enregistrements ayant rencontré une erreur d’envoi |
stats.cancelled | number | Nombre d’enregistrements annulés |
stats.total | number | Nombre total d’enregistrements (pending + success + failed + cancelled) |
stats.success indique que le message a été transmis avec succès par le système. Cela ne garantit pas que Meta a remis le message au destinataire. Les mises à jour de statut ultérieures générées par Meta (comme delivered, read ou failed) n’affectent pas ce compteur et n’y sont pas reflétées.
- Endpoint stats : affiche l’état de la tâche d’envoi (pending, success, failed, cancelled)
- Endpoint message-stats : affiche l’état réel des messages (
pending,sending,sent,delivered,read,error, etc.) - Une tâche peut être réussie sans que le message soit encore remis ou lu
Identifiant de référence
Le referenceId est un champ facultatif que vous pouvez utiliser pour rapprocher les enregistrements d’envoi d’un identifiant de votre propre système à des fins de suivi (par ex. numéro de commande, identifiant de ticket).
S’il est fourni, il doit être unique dans l’envoi en masse (256 caractères maximum).
- Non obligatoire
- Ne peut pas être dupliqué dans un même message en masse
- Peut être réutilisé dans différents messages en masse
Message Stats — statut des messages WhatsApp
Récupère les statistiques de statut des messages d’un message en masse. Contrairement à l’endpoint stats, il affiche le message.status réel de chaque enregistrement au lieu de l’état de la tâche.
Statuts de message possibles : 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
Paramètres de la requête
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
bulkMessageId | string | Oui | Identifiant du message en masse à interroger |
{
"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"
}'
Réponse
{
"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
}
}
Champs de Message Stats
| Champ | Type | Description |
|---|---|---|
pending | number | Messages pas encore envoyés |
sending | number | Messages en cours d’envoi |
sent | number | Messages transmis à WhatsApp, pas encore remis |
delivered | number | Messages remis sur le téléphone du destinataire |
read | number | Messages lus par le destinataire |
deleted | number | Messages supprimés |
warning | number | Messages avec avertissements |
error | number | Messages en erreur |
unknown | number | Messages de statut inconnu |
not-sended | number | Messages qui n’ont pas pu être envoyés |
no-message | number | Enregistrements sans message pour l’instant (encore en file) |
total | number | Nombre total d’enregistrements |
- Un nombre élevé de
no-messageindique que l’envoi est encore en cours - Le nombre de
deliveredindique les messages remis avec succès - Le nombre de
readpeut servir à mesurer l’engagement de la campagne - Vous pouvez interroger cet endpoint périodiquement pour un suivi en temps réel
Structure des options — pagination, filtrage et tri
Le paramètre options utilisé dans les endpoints list et list-with-messages fournit une structure standard pour la pagination, le filtrage et le tri.
Champs des options
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
pagination | object | Non | Paramètres de pagination |
filtering | object | Non | Critères de filtrage |
sorting | object | Non | Paramètres de tri (par ex. {"createdAt": -1}) |
Structure de la pagination
| Champ | Type | Par défaut | Description |
|---|---|---|---|
currentPage | number | 1 | Numéro de la page à récupérer |
pageItems | number | 50 | Nombre d’enregistrements par page (maximum : 50) |
Structure du filtrage
Le filtrage utilise le format de requête MongoDB. Vous pouvez filtrer sur les champs des enregistrements. Dans l’endpoint list-with-messages, vous pouvez aussi filtrer sur les champs des messages (par ex. 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"]
}
}
}
}
Structure du tri
Le tri utilise le format de tri MongoDB. 1 signifie croissant, -1 décroissant.
// Sort by creation date descending (newest first)
{
"options": {
"sorting": {
"createdAt": -1
}
}
}
// Sort by multiple fields
{
"options": {
"sorting": {
"status": 1,
"createdAt": -1
}
}
}
Exemple d’utilisation combinée
{
"bulkMessageId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 2,
"pageItems": 50
},
"filtering": {
"message.status": "delivered"
},
"sorting": {
"createdAt": -1
}
}
}
Cet exemple trie les messages remis du plus récent au plus ancien.
- Combinez
filteringetpaginationpour des requêtes ciblées - La réponse inclut
options.pagination.totalCountetoptions.pagination.totalPagespour la navigation - Le filtre
message.statusne fonctionne que dans l’endpointlist-with-messages
Records — détails et liste des enregistrements
Liste tous les enregistrements d’envoi d’un message en masse. Chaque enregistrement représente un seul message envoyé à un destinataire.
List — liste des enregistrements
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message-records/list.js
Paramètres de la requête
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
bulkMessageId | string | Oui | Identifiant du message en masse à lister |
options | object | Non | Options de pagination, de filtrage et de tri. Voir Structure des options pour plus de détails. |
Requête — utilisation de base
{
"bulkMessageId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
}
}
}
Requête — filtrer par statut précis
{
"bulkMessageId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
},
"filtering": {
"status": "success"
}
}
}
Liste uniquement les enregistrements d’envoi réussis (record.status = "success").
Réponse
{
"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 — liste avec les détails des messages
Offre les mêmes fonctionnalités que l’endpoint list (pagination, filtrage, tri). Seule différence : si un enregistrement a un messageId, l’objet message associé est aussi renvoyé. Cela vous permet de voir le statut du message (delivered, read, error, etc.) et son payload en une seule requête.
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message-records/list-with-messages.js
Requête — utilisation de base
{
"bulkMessageId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
}
}
}
Requête — filtrer par statut de message
{
"bulkMessageId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
},
"filtering": {
"message.status": "delivered"
}
}
}
Cet exemple ne récupère que les messages au statut « delivered ».
Requête — lister les messages en échec
{
"bulkMessageId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
},
"filtering": {
"message.status": "error"
}
}
}
Sert à examiner les messages qui ont rencontré des erreurs d’envoi.
Réponse
{
"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": {}
}
}
Champs d’un enregistrement
| Champ | Type | Description |
|---|---|---|
_id | string | Identifiant de l’enregistrement |
bulkMessageId | string | Identifiant du message en masse auquel appartient l’enregistrement |
userId | string | Identifiant de l’utilisateur destinataire |
sessionId | string | Identifiant de la session de conversation |
messageId | string | Identifiant du message envoyé (null s’il n’est pas encore envoyé) |
referenceId | string | Identifiant de référence facultatif (s’il est fourni) |
status | string | Statut de l’enregistrement : pending, success, failed, cancelled |
message | object | Détails du message (uniquement dans list-with-messages) |
Comparaison list et list-with-messages
| Fonctionnalité | list | list-with-messages |
|---|---|---|
| Pagination | Oui | Oui |
| Filtrage | Oui (champs d’enregistrement uniquement) | Oui (champs d’enregistrement et de message) |
| Objet message | Non | Oui (si messageId existe) |
| Performance | Rapide | Moyenne (effectue une jointure) |
| Filtre message.status | Non disponible | Disponible |
- list : lister rapidement tous les enregistrements, filtrer par referenceId, vérifier les statuts des enregistrements
- list-with-messages : consulter les statuts des messages WhatsApp (delivered, read), inspecter les payloads des messages
- Exemples de filtrage :
{"status": "failed"}— enregistrements d’envoi en échec{"referenceId": "ORDER-123"}— un identifiant de référence précis{"message.status": "delivered"}— messages remis (list-with-messages uniquement){"message.status": "read"}— messages lus (list-with-messages uniquement){"message.status": "error"}— messages en erreur (list-with-messages uniquement){"message.status": {"$in": ["delivered", "read"]}}— messages remis ou lus (list-with-messages uniquement){"message.status": {"$nin": ["error", "not-sended"]}}— messages hors erreurs et non-envoyés (list-with-messages uniquement){"status": {"$in": ["success", "pending"]}}— enregistrements réussis ou en attente
- L’endpoint
listest plus rapide ; privilégiez-le pour les vérifications générales de statut - Utilisez
list-with-messageslorsque les détails des messages sont nécessaires - Le nombre maximal d’enregistrements par page (pageItems) est de 50 ; la valeur par défaut est 50 si elle n’est pas indiquée
- Le filtre
message.statusne fonctionne que danslist-with-messages - Les enregistrements dont le messageId est null auront un objet
messagenull
Stop — annuler l’envoi
Arrête l’envoi en cours d’un message en masse. La tâche en file d’attente est annulée, et tous les enregistrements pending passent au statut cancelled. Les enregistrements déjà traités comme success ou failed ne sont pas affectés.
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/bulk-message/stop.js
Cette action est irréversible. Un envoi arrêté ne peut pas être repris.
Paramètres de la requête
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
bulkMessageId | string | Oui | Identifiant du message en masse à arrêter |
{
"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"
}'
Réponse
Pour une requête réussie, le corps de la réponse est vide. Un statut HTTP 200 indique que l’opération s’est terminée avec succès.
{}
- Seuls les messages en masse créés via cette API peuvent être arrêtés
- Après l’arrêt d’un envoi, vous pouvez utiliser l’endpoint
statspour vérifier le nombre d’enregistrements annulés - Si le message en masse est introuvable, l’API renvoie l’erreur :
bulkMessageNotFound