Aller au contenu principal

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 defaultPayload partagé par tous les destinataires, avec fusion du payload propre à chaque destinataire (isMerge)
  • Envoi programmé (scheduleAt)
  • Indiquez les destinataires avec username (numéro de téléphone), userId ou sessionId
  • Envoyez plusieurs messages au même utilisateur dans une seule requête en masse
  • referenceId facultatif pour rapprocher les enregistrements de systèmes externes
  • Attribuez automatiquement les conversations à un utilisateur ou à un groupe de travail après l’envoi (action)
attention

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ètreTypeObligatoireDescription
channelUsernamestringOuiNuméro du canal WhatsApp utilisé pour envoyer le message (par ex. "908506669933")
connectorBrandstringOuiMarque du connecteur de canal. Valeur actuellement prise en charge : "whatsapp"
titlestringNonTitre de la campagne. Utilisé pour l’affichage dans le tableau de bord. Par défaut : "-"
scheduleAtstring (ISO 8601)NonDate et heure d’envoi programmé (par ex. "2026-06-10T10:00:00.000Z"). Si omis, les messages sont envoyés immédiatement.
defaultPayloadobjectConditionnel*Payload de modèle par défaut appliqué à tous les destinataires. Obligatoire si un destinataire ne fournit pas son propre payload.
recipientsarrayOuiListe des destinataires. Minimum 1, maximum 5 000 destinataires.
actionobjectNonAction 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.

ChampTypeDescription
usernamestringNuméro de téléphone du destinataire (par ex. "905554443322"). Si l’utilisateur n’existe pas dans le système, il est créé automatiquement.
userIdstringIdentifiant d’un utilisateur existant dans le système.
sessionIdstringIdentifiant d’une session de conversation existante dans le système.
referenceIdstringIdentifiant 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.
payloadobjectPayload de modèle propre au destinataire (facultatif). Si isMerge: true, il est fusionné avec defaultPayload.
isMergebooleanRemplace le comportement de fusion pour ce destinataire (facultatif). Si omis, defaultPayload.isMerge est utilisé.

Structure de l’action​

ChampTypeDescription
action.keystring"assign-to-user" attribue la conversation à un agent précis ; "assign-to-workgroup" l’attribue à un groupe de travail.
action.valuestringIdentifiant 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
}
ChampTypeObligatoireDescription
typestringOuiType de payload. Pour les messages modèles : "template"
template.templateNamestringOui*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.languageCodestringNonCode de langue du modèle (par ex. "tr", "en", "tr-TR", "en-US"). Doit correspondre exactement à la langue enregistrée dans Meta.
template.variablesarrayNonListe des variables appliquées aux composants du modèle. Détaillée ci-dessous.
isMergebooleanNontrue : le payload du destinataire est fusionné en profondeur avec defaultPayload. false ou omis : le payload du destinataire remplace entièrement defaultPayload.
Comportement de isMerge
  • Si defaultPayload.isMerge: true et que le destinataire fournit son propre payload, une fusion en profondeur est appliquée.
  • Avec la fusion en profondeur, le destinataire peut ne fournir que variables ; templateName et languageCode sont hérités du payload par défaut.
  • Le champ isMerge du destinataire remplace defaultPayload.isMerge.
  • Si un destinataire ne fournit pas de payload, defaultPayload est 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.

typeDescriptionparameterscards
"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èleOui—
"BUTTONS"Variables de suffixe d’URL dynamique pour les boutonsOui—
"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" }
Quel format utiliser ?
  • 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"]
}

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"]
}
]
}
]
}
attention

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" }
]
}'
astuce
  • Les destinataires indiqués via username sont 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 isMerge n’est pas indiqué, chaque destinataire utilise directement le defaultPayload

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" }]
}
astuce
  • 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 que parameters[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"]
}
]
}
}
}
]
}
astuce
  • Grâce à isMerge: true, templateName n’a pas besoin d’être répété dans chaque payload de destinataire
  • Le tableau variables de chaque destinataire est entièrement indépendant
  • L’URL du média d’en-tête doit être accessible publiquement
  • Si type est omis dans le payload du destinataire, defaultPayload.type est 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"]
}
]
}
}
}
]
}
astuce
  • Les paramètres BUTTONS sont 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}}, alors parameters[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" }
}
]
}
}
}
]
}
astuce
  • scheduleAt doit être fourni dans le fuseau horaire UTC (par ex., pour 10 h 00 heure de Turquie, utilisez 07: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​

StatutDescription
Channel not foundAucun canal vérifié correspondant à channelUsername et connectorBrand n’a été trouvé
Channel is not verifiedLe canal correspondant existe mais n’a pas encore été vérifié
invalidRequestPlusieurs identifiants ont été fournis pour un destinataire ou un payload obligatoire est manquant
channelNotFoundAucun canal actif correspondant au channelId fourni n’a été trouvé
schema-errorUn 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ètreTypeObligatoireDescription
bulkMessageIdstringOuiIdentifiant 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​

ChampTypeDescription
stats.pendingnumberNombre d’enregistrements encore en attente dans la file
stats.successnumberNombre d’enregistrements traités avec succès pour l’envoi
stats.failednumberNombre d’enregistrements ayant rencontré une erreur d’envoi
stats.cancellednumberNombre d’enregistrements annulés
stats.totalnumberNombre total d’enregistrements (pending + success + failed + cancelled)
remarque

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.

Stats et Message Stats
  • 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).

Important
  • 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ètreTypeObligatoireDescription
bulkMessageIdstringOuiIdentifiant 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​

ChampTypeDescription
pendingnumberMessages pas encore envoyés
sendingnumberMessages en cours d’envoi
sentnumberMessages transmis à WhatsApp, pas encore remis
deliverednumberMessages remis sur le téléphone du destinataire
readnumberMessages lus par le destinataire
deletednumberMessages supprimés
warningnumberMessages avec avertissements
errornumberMessages en erreur
unknownnumberMessages de statut inconnu
not-sendednumberMessages qui n’ont pas pu être envoyés
no-messagenumberEnregistrements sans message pour l’instant (encore en file)
totalnumberNombre total d’enregistrements
Conseils d’utilisation
  • Un nombre élevé de no-message indique que l’envoi est encore en cours
  • Le nombre de delivered indique les messages remis avec succès
  • Le nombre de read peut 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​

ChampTypeObligatoireDescription
paginationobjectNonParamètres de pagination
filteringobjectNonCritères de filtrage
sortingobjectNonParamètres de tri (par ex. {"createdAt": -1})

Structure de la pagination​

ChampTypePar défautDescription
currentPagenumber1Numéro de la page à récupérer
pageItemsnumber50Nombre 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.

Conseils pratiques
  • Combinez filtering et pagination pour des requêtes ciblées
  • La réponse inclut options.pagination.totalCount et options.pagination.totalPages pour la navigation
  • Le filtre message.status ne fonctionne que dans l’endpoint list-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ètreTypeObligatoireDescription
bulkMessageIdstringOuiIdentifiant du message en masse à lister
optionsobjectNonOptions 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​

ChampTypeDescription
_idstringIdentifiant de l’enregistrement
bulkMessageIdstringIdentifiant du message en masse auquel appartient l’enregistrement
userIdstringIdentifiant de l’utilisateur destinataire
sessionIdstringIdentifiant de la session de conversation
messageIdstringIdentifiant du message envoyé (null s’il n’est pas encore envoyé)
referenceIdstringIdentifiant de référence facultatif (s’il est fourni)
statusstringStatut de l’enregistrement : pending, success, failed, cancelled
messageobjectDétails du message (uniquement dans list-with-messages)

Comparaison list et list-with-messages​

Fonctionnalitélistlist-with-messages
PaginationOuiOui
FiltrageOui (champs d’enregistrement uniquement)Oui (champs d’enregistrement et de message)
Objet messageNonOui (si messageId existe)
PerformanceRapideMoyenne (effectue une jointure)
Filtre message.statusNon disponibleDisponible
Scénarios d’utilisation
  • 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
Performance et remarques d’utilisation
  • L’endpoint list est plus rapide ; privilégiez-le pour les vérifications générales de statut
  • Utilisez list-with-messages lorsque 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.status ne fonctionne que dans list-with-messages
  • Les enregistrements dont le messageId est null auront un objet message null

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
attention

Cette action est irréversible. Un envoi arrêté ne peut pas être repris.

Paramètres de la requête​

ParamètreTypeObligatoireDescription
bulkMessageIdstringOuiIdentifiant 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.

{}
astuce
  • 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 stats pour vérifier le nombre d’enregistrements annulés
  • Si le message en masse est introuvable, l’API renvoie l’erreur : bulkMessageNotFound