Bulk Template Message API – Dokumentation — v2
Mit dieser API können Sie Vorlagennachrichten über den WhatsApp-Kanal gleichzeitig an mehrere Empfänger senden.
Der Nachrichtenversand wird asynchron verarbeitet; die API-Anfrage liefert sofort eine bulkOperationId zurück, während die Nachrichten in eine Warteschlange gestellt und im Hintergrund verarbeitet werden.
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation/send.js
Jeder Endpunkt in diesem Dokument ist eine Custom Function. Der HTTP-Antwort-Body enthält die eigenen Felder der Funktion (_id, title, pathString…) und unter result die eigentliche Antwort des Endpunkts. Die Antwortbeispiele in diesem Dokument zeigen den Inhalt von result:
{
"_id": "function_id",
"title": "Show",
"pathString": "/bulk-message-api-app/api/v2/bulk-operation/show.js",
"result": {
"bulkOperation": { "_id": "abc123xyz789", "status": "running" }
}
}
Migration von v1
v2 läuft parallel zu v1, sodass Sie nach Ihrem eigenen Zeitplan migrieren können. Die v1-Endpunkte (/api/bulk-message/…, /api/bulk-message-records/…) werden eingestellt; neue Integrationen sollten v2 verwenden.
- Stellen Sie die Endpunktpfade auf v2 um: Aus
…/api/bulk-message/…wird…/api/v2/bulk-operation/…und aus…/api/bulk-message-records/…wird…/api/v2/bulk-operation-items/…. Der Anfrage-Body vonsendändert sich nicht; eine einzelne Anfrage nimmt jetzt bis zu 100.000 statt 5.000 Empfänger an. - Senden Sie in Anfragen
bulkOperationIdstattbulkMessageId. - Ersetzen Sie
stats.jsdurchshow.js. - Lesen Sie die Antworten mit den neuen Feldnamen aus der folgenden Tabelle.
Die v2-Endpunkte kennen nur Massenvorgänge, die mit dem v2-send erstellt wurden. Um eine Massennachricht zu verfolgen, die Sie vor der Umstellung mit v1 erstellt haben, verwenden Sie dafür weiterhin die v1-Endpunkte.
Endpunkte
| v1 | v2 | Was sich in der Antwort ändert |
|---|---|---|
bulk-message/send.js | v2/bulk-operation/send.js | Aus { bulkMessageId } wird { bulkOperationId } |
bulk-message/stats.js | v2/bulk-operation/show.js | Aus { bulkMessage, stats } wird { bulkOperation } |
bulk-message/message-stats.js | v2/bulk-operation/message-stats.js | Die Zähler stehen auf der obersten Ebene statt unter messageStats |
bulk-message/stop.js | v2/bulk-operation/stop.js | Nichts |
bulk-message-records/list.js | v2/bulk-operation-items/list.js | Aus bulkMessageRecords wird bulkOperationItems |
bulk-message-records/list-with-messages.js | v2/bulk-operation-items/list-with-messages.js | Wie bei list; zusätzlich enthält jeder Eintrag session |
Feldnamen
| v1 | v2 |
|---|---|
stats.success | bulkOperation.progress.succeeded |
stats.pending, stats.failed, stats.cancelled, stats.total | bulkOperation.progress.pending, .failed, .cancelled, .total |
| — | bulkOperation.progress.unknown, bulkOperation.status, bulkOperation.result.outcome |
bulkMessage (Massennachricht) | bulkOperation (Massenvorgang) |
bulkMessageRecord (Datensatz) | bulkOperationItem (Eintrag) |
bulkMessageId in Anfragen, in der send-Antwort und in Datensätzen | bulkOperationId |
username / userId / sessionId des Datensatzes wie gesendet | payload.username / payload.userId / payload.sessionId |
referenceId des Datensatzes | payload.referenceId |
payload des Datensatzes (der Vorlagen-Payload des Empfängers) | payload.payload |
userId, sessionId, messageId des Datensatzes nach dem Senden | result.userId, result.sessionId, result.messageId |
Datensatzstatus success | succeeded |
errorMessage bei fehlgeschlagenen Datensätzen | error.message, neben error.code und error.retryable |
| — | position (der Index des Empfängers in recipients) |
Filter {"status": "success"} | {"status": "succeeded"} |
Filter {"referenceId": "…"} | {"payload.referenceId": "…"} |
send-Fehler schema-error, invalidRequest | zod-schema-error, mit dem Pfad des ungültigen Felds in der Meldung |
Hauptfunktionen
- Senden Sie Massen-Vorlagennachrichten an 1–100.000 Empfänger in einer einzigen Anfrage
- Personalisierte Variablen für jeden Empfänger (HEADER, BODY, BUTTONS, CAROUSEL)
- Gemeinsames
defaultPayloadfür alle Empfänger mit dem Zusammenführen empfängerspezifischerpayload-Daten (isMerge) - Geplanter Versand (
scheduleAt) - Empfänger über
username(Telefonnummer),userIdodersessionIdangeben - Mehrere Nachrichten an denselben Benutzer in einer einzigen Massenanfrage senden
- Optionale
referenceIdzum Abgleich von Datensätzen mit externen Systemen - Konversationen nach dem Senden automatisch einem Benutzer oder einer Arbeitsgruppe zuweisen (
action)
Diese API kann nur Vorlagen senden, die von Meta genehmigt wurden.
Vorlagenname und Sprachcode müssen genau mit der im Meta Business Manager registrierten Vorlage übereinstimmen.
Anfrageparameter
Parameter der obersten Ebene
| Parameter | Typ | Pflicht | Beschreibung |
|---|---|---|---|
channelUsername | string | Ja | WhatsApp-Kanalnummer, von der die Nachricht gesendet wird (z. B. "908506669933") |
connectorBrand | string | Ja | Marke des Kanal-Connectors. Derzeit unterstützter Wert: "whatsapp" |
title | string | Nein | Kampagnentitel. Wird im Dashboard angezeigt. Standardwert: "-" |
scheduleAt | string (ISO 8601) | Nein | Geplantes Versanddatum mit Uhrzeit (z. B. "2026-06-10T10:00:00.000Z"). Wenn weggelassen, werden die Nachrichten sofort gesendet. |
defaultPayload | object | Bedingt* | Standard-Vorlagen-Payload, der für alle Empfänger gilt. Erforderlich, wenn ein Empfänger kein eigenes payload angibt. |
recipients | array | Ja | Empfängerliste. Mindestens 1, höchstens 100.000 Empfänger. |
action | object | Nein | Aktion, die nach dem Senden auf die Konversation angewendet wird. assign-to-user oder assign-to-workgroup. |
*Wenn jeder Empfänger ein eigenes payload angibt, ist defaultPayload optional.
Empfängerstruktur
Für jeden Empfänger muss genau eines von username, userId oder sessionId angegeben werden. Mehrere Kennungen können nicht gemeinsam verwendet werden, und fehlen alle, führt das zu einem Fehler.
Um mehrere Nachrichten an denselben Benutzer in einer einzigen Massenanfrage zu senden, fügen Sie dieselbe Kennung mehrfach zur Empfängerliste hinzu.
| Feld | Typ | Beschreibung |
|---|---|---|
username | string | Telefonnummer des Empfängers (z. B. "905554443322"). Existiert der Benutzer im System noch nicht, wird er automatisch angelegt. |
userId | string | ID eines vorhandenen Benutzers im System. |
sessionId | string | ID einer vorhandenen Konversationssitzung im System. |
referenceId | string | Optionale Referenz-ID (max. 256 Zeichen) zum Abgleich mit Datensätzen externer Systeme (CRM, Bestellung, Ticket usw.). Muss, wenn angegeben, innerhalb der Massenanfrage eindeutig sein. |
payload | object | Empfängerspezifischer Vorlagen-Payload (optional). Bei isMerge: true wird er mit defaultPayload zusammengeführt. |
isMerge | boolean | Überschreibt das Zusammenführungsverhalten für diesen Empfänger (optional). Wenn weggelassen, wird defaultPayload.isMerge verwendet. |
Aktionsstruktur
| Feld | Typ | Beschreibung |
|---|---|---|
action.key | string | "assign-to-user" weist die Konversation einem bestimmten Mitarbeiter zu; "assign-to-workgroup" weist sie einer Arbeitsgruppe zu. |
action.value | string | ID des Ziel-Benutzers oder der Ziel-Arbeitsgruppe. |
Struktur des Vorlagen-Payloads
defaultPayload und das empfängerspezifische payload haben dieselbe Struktur. Für Vorlagennachrichten muss type: "template" angegeben werden.
{
"type": "template",
"template": {
"templateName": "order_confirmation",
"languageCode": "tr-TR",
"variables": []
},
"isMerge": true
}
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
type | string | Ja | Payload-Typ. Für Vorlagennachrichten: "template" |
template.templateName | string | Ja* | In Meta registrierter Vorlagenname. In Empfänger-Payloads optional, wenn isMerge: true verwendet wird (wird vom Standard geerbt). |
template.languageCode | string | Nein | Sprachcode der Vorlage (z. B. "tr", "en", "tr-TR", "en-US"). Muss genau mit der in Meta registrierten Sprache übereinstimmen. |
template.variables | array | Nein | Liste der Variablen, die auf die Vorlagenkomponenten angewendet werden. Details unten. |
isMerge | boolean | Nein | true: Der Empfänger-Payload wird tief mit defaultPayload zusammengeführt. false oder weggelassen: Der Empfänger-Payload ersetzt defaultPayload vollständig. |
- Wenn
defaultPayload.isMerge: truegilt und der Empfänger ein eigenespayloadangibt, wird eine tiefe Zusammenführung angewendet. - Bei der tiefen Zusammenführung kann der Empfänger nur
variablesangeben;templateNameundlanguageCodewerden vom Standard-Payload geerbt. - Das Feld
isMergedes Empfängers überschreibtdefaultPayload.isMerge. - Gibt ein Empfänger kein
payloadan, wird immerdefaultPayloadverwendet.
Variablenstruktur
Jedes Element im Array variables entspricht einer Vorlagenkomponente. Ein Komponententyp (type) darf im Array nur einmal vorkommen.
| type | Beschreibung | parameters | cards |
|---|---|---|---|
"HEADER" | Header-Komponente der Vorlage. Textvariable oder Medien-URL (Bild, Video, Dokument) | Ja | — |
"BODY" | Textvariablen im Body der Vorlage | Ja | — |
"BUTTONS" | Variablen für dynamische URL-Suffixe von Schaltflächen | Ja | — |
"CAROUSEL" | Kartenkomponenten für Karussell-Vorlagen | — | Ja |
Parameterformate
Das Feld parameters kann in drei verschiedenen Formaten angegeben werden:
// Format 1: Array (indexbasiert) — für Platzhalter wie {{1}}, {{2}}, {{3}}
"parameters": ["value1", "value2", "value3"]
// Format 2: Objekt (numerische Schlüssel) — alternative Darstellung für {{1}}, {{2}}
"parameters": { "1": "value1", "2": "value2" }
// Format 3: Objekt (benannte Schlüssel) — für Platzhalter wie {{name}}, {{amount}}
"parameters": { "name": "John", "amount": "150 USD" }
- Wenn Ihre Meta-Vorlage Platzhalter wie
{{1}},{{2}}verwendet, nutzen Sie entweder das Array-Format oder das Objektformat mit numerischen Schlüsseln. - Wenn Ihre Vorlage benannte Platzhalter wie
{{firstName}}oder{{orderTotal}}verwendet, nutzen Sie das Objektformat mit benannten Schlüsseln. - Bei Arrays kommt es auf die Reihenfolge an: Das erste Element entspricht
{{1}}, das zweite{{2}}und so weiter.
HEADER-Komponente
Verwenden Sie die Komponente HEADER, wenn der Header der Vorlage Medien (Bild, Video, Dokument) oder dynamischen Text enthält.
// Medien-Header (Bild-URL)
{
"type": "HEADER",
"parameters": ["https://example.com/product-image.jpg"]
}
// Textvariable im Header
{
"type": "HEADER",
"parameters": ["Special Campaign"]
}
BODY-Komponente
Wird für dynamische Textvariablen im Body der Vorlage verwendet.
// Array-Format — wenn die Vorlage {{1}}, {{2}}, {{3}} verwendet
{
"type": "BODY",
"parameters": ["John", "ORD-12345", "150.00 USD"]
}
// Benanntes Format — wenn die Vorlage {{name}}, {{orderAmount}} verwendet
{
"type": "BODY",
"parameters": {
"name": "John",
"orderAmount": "150.00 USD"
}
}
BUTTONS-Komponente
Wird für Schaltflächen mit dynamischen URL-Suffixen verwendet. Enthält die Vorlage mehrere URL-Schaltflächen, werden nur Schaltflächen mit Variablen fortlaufend indiziert (Schaltflächen ohne Variablen und FLOW-Schaltflächen werden ignoriert).
// Variable für den Suffix einer einzelnen URL-Schaltfläche
{
"type": "BUTTONS",
"parameters": ["tracking/ORD-12345"]
}
// Variablen für mehrere URL-Schaltflächen-Suffixe (erste URL-Schaltfläche, zweite URL-Schaltfläche)
{
"type": "BUTTONS",
"parameters": ["tracking/ORD-12345", "cancel/ORD-12345"]
}
CAROUSEL-Komponente
Bei Karussell-Vorlagen werden die Komponentenvariablen für jede Karte separat definiert.
{
"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"]
}
]
}
]
}
Die Länge des Arrays cards muss genau der Anzahl der in der Vorlage definierten Karten entsprechen.
Beispiele
1. Einfache Vorlage – keine Variablen, gleicher Inhalt für alle Empfänger
Dies ist der einfachste Weg, eine statische Vorlage ohne Variablen an mehrere Empfänger zu senden.
{
"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/v2/bulk-operation/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" }
]
}'
- Über
usernameangegebene Empfänger werden automatisch angelegt, wenn sie im System noch nicht existieren - Alle Empfänger verwenden dasselbe
defaultPayload; empfängerspezifische Daten sind nicht erforderlich - Wenn
isMergenicht angegeben ist, verwendet jeder Empfänger direkt dasdefaultPayload
2. Vorlage mit gemeinsamen Body-Variablen
Dieselbe Vorlage wird mit identischen Variablenwerten an alle Empfänger gesendet. Die Vorlage enthält Platzhalter wie {{1}} und {{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 diesem Beispiel könnte der Body der Vorlage etwa lauten: „Genießen Sie in unserer Kampagne
{{1}}Rabatt! Angebot gültig bis{{2}}.“ parameters[0]ersetzt{{1}}, währendparameters[1]{{2}}ersetzt
3. Personalisierte Vorlage – Variablen pro Empfänger mit isMerge
Für jeden Empfänger werden unterschiedliche Variablenwerte verwendet. Setzen Sie isMerge: true im defaultPayload, müssen Empfänger nur variables angeben; templateName und languageCode werden vom Standard-Payload geerbt.
In diesem Beispiel enthält die Vorlage sowohl einen Medien-Header als auch personalisierte Body-Variablen.
{
"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"]
}
]
}
}
}
]
}
- Dank
isMerge: truemusstemplateNamenicht in jedem Empfänger-Payload wiederholt werden - Das Array
variablesjedes Empfängers ist vollständig unabhängig - Die Medien-URL des Headers muss öffentlich erreichbar sein
- Wird
typeim Empfänger-Payload weggelassen, wirddefaultPayload.typegeerbt
4. Variable einer URL-Schaltfläche
Verwenden Sie die Komponente BUTTONS, wenn die Vorlage eine Schaltfläche mit dynamischem URL-Suffix enthält, zum Beispiel eine Sendungsnummer, die an die Basis-URL https://example.com/track/ angehängt wird.
{
"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-Parameter werden anhand der Reihenfolge der Schaltflächen zugeordnet, die Variablen enthalten- FLOW-Schaltflächen und Schaltflächen ohne Variablen werden ignoriert; die Indizierung gilt nur für dynamische URL-Schaltflächen
- Lautet die URL der Schaltfläche in der Vorlage
https://example.com/track/{{1}}, ersetztparameters[0]den Platzhalter{{1}}
5. Geplanter Versand
Planen Sie den Versand einer Nachricht zu einem zukünftigen Datum und einer zukünftigen Uhrzeit. scheduleAt muss als UTC-Zeitstempel nach ISO 8601 angegeben werden.
{
"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" }
}
]
}
}
}
]
}
scheduleAtmuss in der Zeitzone UTC angegeben werden (z. B. für 10:00 Uhr türkischer Zeit07:00:00.000Zverwenden)- Dieses Beispiel verwendet das Format mit benannten Parametern; die Vorlage sollte Platzhalter wie
{{name}}und{{discountRate}}enthalten - Mit
actionwerden Konversationen, die durch den Nachrichtenversand entstehen, automatisch der angegebenen Arbeitsgruppe zugewiesen
Antwort
Eine erfolgreiche Anfrage liefert eine bulkOperationId zurück, mit der sich der Versandvorgang verfolgen lässt:
{
"bulkOperationId": "abc123xyz789"
}
Fehlerantworten
| Status | Beschreibung |
|---|---|
recipients field is required | Das Feld recipients wurde nicht gesendet |
Channel not found | Es wurde kein verifizierter Kanal gefunden, der zu channelUsername und connectorBrand passt |
Channel is not verified | Der passende Kanal existiert, wurde aber noch nicht verifiziert |
zod-schema-error | Ein Feld im Anfrage-Body hat die Schemaprüfung nicht bestanden (fehlendes Pflichtfeld, falscher Typ, nicht unterstützter Wert, mehr als eine Kennung bei einem Empfänger oder fehlendes payload). Die Meldung nennt das Feld, z. B. recipients.0.referenceId: referenceId must be unique |
Mit der zurückgegebenen bulkOperationId lassen sich über die folgenden Endpunkte Versandstatistiken abfragen und der Versandvorgang stoppen.
Show – Status und Statistiken des Massenvorgangs
Ruft den Massenvorgang mit seinem aktuellen Status und den Versandzählern seiner Einträge unter dem Schlüssel bulkOperation ab.
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation/show.js
Anfrageparameter
| Parameter | Typ | Pflicht | Beschreibung |
|---|---|---|---|
bulkOperationId | string | Ja | ID des zu verfolgenden Massenvorgangs (von send zurückgegeben) |
{
"bulkOperationId": "abc123xyz789"
}
curl --location 'https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation/show.js' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN' \
--data '{
"bulkOperationId": "abc123xyz789"
}'
Antwort
{
"bulkOperation": {
"_id": "abc123xyz789",
"type": "send-bulk-message",
"slug": "my-workspace",
"userId": "agent_user_id",
"payload": {
"title": "Campaign Title",
"channelUsername": "908506669933",
"connectorBrand": "whatsapp",
"connectorSlug": "om2WabVegaCloud",
"defaultLanguageCode": "tr-TR",
"sentUser": { "firstname": "John", "lastname": "Doe" },
"defaultPayload": {
"type": "template",
"template": { "templateName": "order_confirmation", "languageCode": "tr-TR" },
"isMerge": true
},
"source": { "type": "recipients", "bulkOperationInputGroupId": "group_id" }
},
"status": "running",
"result": { "outcome": "unknown", "hasErrors": false },
"progress": {
"total": 100,
"pending": 45,
"succeeded": 42,
"failed": 3,
"cancelled": 10,
"unknown": 0
},
"scheduleAt": "2026-06-10T07:00:00.000Z",
"createdAt": "2026-06-08T10:00:00.000Z",
"updatedAt": "2026-06-10T07:00:30.000Z",
"startedAt": "2026-06-10T07:00:05.000Z"
}
}
Show-Felder
Die Felder befinden sich unter bulkOperation.
| Feld | Typ | Beschreibung |
|---|---|---|
status | string | Status des Massenvorgangs: preparing, scheduled, pending, running, stopping, stopped, completed, failed |
progress.total | number | Gesamtzahl der Einträge |
progress.pending | number | Einträge, die noch in der Warteschlange warten |
progress.succeeded | number | Einträge, die erfolgreich für den Versand verarbeitet wurden |
progress.failed | number | Einträge, bei denen ein Zustellfehler aufgetreten ist |
progress.cancelled | number | Durch stop abgebrochene Einträge |
progress.unknown | number | Einträge, deren Ergebnis nicht ermittelt werden konnte |
result.outcome | string | Endergebnis, sobald der Massenvorgang abgeschlossen ist: success, partial, all-failed, cancelled, unknown |
result.hasErrors | boolean | true, wenn mindestens ein Eintrag fehlgeschlagen ist |
scheduleAt | string | Geplanter Versandzeitpunkt (nur bei geplanten Massenvorgängen) |
startedAt, completedAt | string | Wann der Versand begonnen und geendet hat |
progress.succeeded zeigt an, dass die Nachricht vom System erfolgreich übergeben wurde. Es ist keine Garantie dafür, dass Meta die Nachricht an den Empfänger zugestellt hat. Spätere Statusaktualisierungen von Meta (wie delivered, read oder failed) wirken sich nicht auf diesen Zähler aus und werden hier nicht abgebildet.
- Endpunkt show: zeigt den Versandstatus der Einträge (
pending,succeeded,failed,cancelled,unknown) - Endpunkt message-stats: zeigt den tatsächlichen Nachrichtenstatus (
pending,sending,sent,delivered,read,errorusw.) - Ein Eintrag kann
succeededsein, obwohl die Nachricht noch nicht zugestellt oder gelesen wurde
Referenz-ID
Die referenceId ist ein optionales Feld, mit dem Sie Versandeinträge zu Nachverfolgungszwecken einer ID aus Ihrem eigenen System zuordnen können (z. B. Bestellnummer, Ticket-ID). Sie wird bei jedem Eintrag als payload.referenceId zurückgegeben.
Wenn angegeben, muss sie innerhalb der Massenanfrage eindeutig sein (max. 256 Zeichen).
- Für die Nutzung nicht erforderlich
- Darf innerhalb desselben Massenvorgangs nicht doppelt vorkommen
- Kann in verschiedenen Massenvorgängen erneut verwendet werden
Message Stats – WhatsApp-Nachrichtenstatus
Ruft die Statistiken zum Nachrichtenstatus eines Massenvorgangs ab. Anders als der Endpunkt show zeigt dieser den tatsächlichen message.status der gesendeten Nachrichten statt des Eintragsstatus.
Mögliche Nachrichtenstatus: 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/v2/bulk-operation/message-stats.js
Anfrageparameter
| Parameter | Typ | Pflicht | Beschreibung |
|---|---|---|---|
bulkOperationId | string | Ja | ID des abzufragenden Massenvorgangs |
{
"bulkOperationId": "abc123xyz789"
}
curl --location 'https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation/message-stats.js' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN' \
--data '{
"bulkOperationId": "abc123xyz789"
}'
Antwort
{
"pending": 5,
"sending": 2,
"sent": 10,
"delivered": 45,
"read": 30,
"deleted": 2,
"warning": 1,
"error": 3,
"unknown": 0,
"not-sended": 2,
"no-message": 20,
"total": 120
}
Message-Stats-Felder
| Feld | Typ | Beschreibung |
|---|---|---|
pending | number | Noch nicht gesendete Nachrichten |
sending | number | Nachrichten, die gerade gesendet werden |
sent | number | An WhatsApp übergebene, noch nicht zugestellte Nachrichten |
delivered | number | Auf dem Telefon des Empfängers zugestellte Nachrichten |
read | number | Vom Empfänger gelesene Nachrichten |
deleted | number | Gelöschte Nachrichten |
warning | number | Nachrichten mit Warnungen |
error | number | Nachrichten mit Fehlern |
unknown | number | Nachrichten mit unbekanntem Status |
not-sended | number | Nachrichten, die nicht gesendet werden konnten |
no-message | number | Einträge ohne Nachricht (noch in der Warteschlange, fehlgeschlagen oder abgebrochen) |
total | number | Gesamtzahl der Einträge |
- Eine hohe Anzahl bei
no-message, während der Massenvorgang den Statusrunninghat, zeigt an, dass der Versand noch läuft - Die Anzahl bei
deliveredzeigt die erfolgreiche Zustellung von Nachrichten - Die Anzahl bei
readlässt sich nutzen, um die Interaktion mit einer Kampagne zu messen - Sie können diesen Endpunkt regelmäßig abfragen, um den Versand in Echtzeit zu verfolgen
Options-Struktur – Seitenumbruch, Filterung und Sortierung
Der Parameter options, der in den Endpunkten list und list-with-messages verwendet wird, bietet eine einheitliche Struktur für Seitenumbruch, Filterung und Sortierung.
Options-Felder
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
pagination | object | Nein | Einstellungen für den Seitenumbruch |
filtering | object | Nein | Filterkriterien |
sorting | object | Nein | Sortiereinstellungen (z. B. {"position": 1}) |
Struktur des Seitenumbruchs
Wird pagination nicht gesendet, wird die erste Seite mit bis zu 50 Einträgen zurückgegeben. Wird es gesendet, ist currentPage erforderlich.
| Feld | Typ | Standard | Beschreibung |
|---|---|---|---|
currentPage | number | — | Abzurufende Seitennummer (erforderlich, wenn pagination gesendet wird) |
pageItems | number | 50 | Anzahl der Einträge pro Seite (Maximum: 50) |
Filterstruktur
Die Filterung erfolgt im MongoDB-Abfrageformat auf den Feldern der Einträge, mit den Feldnamen genau so, wie sie in der Antwort erscheinen (z. B. status, payload.referenceId, result.messageId). Im Endpunkt list-with-messages können Sie außerdem nach Nachrichtenfeldern filtern (z. B. message.status).
// Nach Eintragsstatus filtern
{
"options": {
"filtering": {
"status": "succeeded"
}
}
}
// Nach referenceId filtern
{
"options": {
"filtering": {
"payload.referenceId": "ORDER-12345"
}
}
}
// Nach Nachrichtenstatus filtern (nur list-with-messages)
{
"options": {
"filtering": {
"message.status": "delivered"
}
}
}
// Nach mehreren Status mit $in filtern (MongoDB-Operator)
{
"options": {
"filtering": {
"message.status": {
"$in": ["delivered", "read"]
}
}
}
}
// Bestimmte Status mit $nin ausschließen (MongoDB-Operator)
{
"options": {
"filtering": {
"message.status": {
"$nin": ["error", "not-sended"]
}
}
}
}
// Einträge ohne Nachricht auflisten (nur list-with-messages)
{
"options": {
"filtering": {
"message": {
"$exists": false
}
}
}
}
Sortierstruktur
Die Sortierung erfolgt im MongoDB-Sortierformat. 1 bedeutet aufsteigend, -1 absteigend. position ist die Reihenfolge des Empfängers im Array recipients der Anfrage (beginnend bei 0).
// In der Reihenfolge sortieren, in der die Empfänger in der Anfrage gesendet wurden
{
"options": {
"sorting": {
"position": 1
}
}
}
// Nach mehreren Feldern sortieren
{
"options": {
"sorting": {
"status": 1,
"position": 1
}
}
}
Beispiel für die kombinierte Verwendung
{
"bulkOperationId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 2,
"pageItems": 50
},
"filtering": {
"message.status": "delivered"
},
"sorting": {
"position": 1
}
}
}
Dieses Beispiel listet die zweite Seite der zugestellten Nachrichten in Empfängerreihenfolge auf.
- Kombinieren Sie
filteringundpaginationfür gezielte Abfragen - Die Antwort enthält
options.pagination.totalCountundoptions.pagination.totalPageszur Navigation - Der Filter
message.statusfunktioniert nur im Endpunktlist-with-messages
Items – Eintragsdetails und Auflistung
Listet alle Versandeinträge eines Massenvorgangs auf. Jeder Eintrag entspricht einem Element des Arrays recipients.
List – Eintragsliste
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation-items/list.js
Anfrageparameter
| Parameter | Typ | Pflicht | Beschreibung |
|---|---|---|---|
bulkOperationId | string | Ja | ID des aufzulistenden Massenvorgangs |
options | object | Nein | Optionen für Seitenumbruch, Filterung und Sortierung. Details unter Options-Struktur. |
Anfrage – Grundlegende Verwendung
{
"bulkOperationId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
}
}
}
Anfrage – Nach bestimmtem Status filtern
{
"bulkOperationId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
},
"filtering": {
"status": "failed"
}
}
}
Listet nur fehlgeschlagene Versandeinträge auf, mit dem Grund in error.
Antwort
{
"bulkOperationItems": [
{
"_id": "item_1",
"bulkOperationId": "abc123xyz789",
"bulkOperationBatchId": "batch_1",
"slug": "my-workspace",
"position": 0,
"payload": {
"username": "905554443301",
"referenceId": "ORDER-12345",
"payload": {
"template": {
"variables": [{ "type": "BODY", "parameters": ["Ahmet", "ORD-001"] }]
}
}
},
"status": "succeeded",
"attempt": 1,
"result": {
"userId": "user_123",
"sessionId": "session_456",
"messageId": "msg_789"
},
"createdAt": "2026-06-10T10:00:00.000Z",
"updatedAt": "2026-06-10T10:00:01.000Z",
"completedAt": "2026-06-10T10:00:01.000Z"
},
{
"_id": "item_2",
"bulkOperationId": "abc123xyz789",
"bulkOperationBatchId": "batch_1",
"slug": "my-workspace",
"position": 1,
"payload": { "username": "905554443302", "referenceId": "ORDER-12346" },
"status": "failed",
"attempt": 1,
"error": { "code": "error", "message": "Variable missing", "retryable": false },
"result": { "userId": "user_124", "sessionId": "session_457" },
"createdAt": "2026-06-10T10:00:00.000Z",
"updatedAt": "2026-06-10T10:00:01.000Z",
"completedAt": "2026-06-10T10:00:01.000Z"
}
],
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50,
"totalCount": 150,
"totalPages": 3
},
"sorting": {},
"filtering": {},
"searching": {}
}
}
List With Messages – Liste mit Nachrichtendetails
Bietet dieselben Funktionen wie der Endpunkt list (Seitenumbruch, Filterung, Sortierung). Der Unterschied: Jeder Eintrag enthält zusätzlich die zugehörigen Objekte message und session, sofern vorhanden. So sehen Sie den Nachrichtenstatus (delivered, read, error usw.) und den Payload in einer einzigen Abfrage.
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation-items/list-with-messages.js
Anfrage – Grundlegende Verwendung
{
"bulkOperationId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
}
}
}
Anfrage – Nach Nachrichtenstatus filtern
{
"bulkOperationId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
},
"filtering": {
"message.status": "delivered"
}
}
}
Dieses Beispiel ruft nur Nachrichten mit dem Status „delivered“ ab.
Anfrage – Fehlgeschlagene Nachrichten auflisten
{
"bulkOperationId": "abc123xyz789",
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50
},
"filtering": {
"message.status": "error"
}
}
}
Dient dazu, Nachrichten zu prüfen, bei denen Zustellfehler aufgetreten sind.
Antwort
{
"bulkOperationItems": [
{
"_id": "item_1",
"bulkOperationId": "abc123xyz789",
"position": 0,
"payload": { "username": "905554443301", "referenceId": "ORDER-12345" },
"status": "succeeded",
"result": {
"userId": "user_123",
"sessionId": "session_456",
"messageId": "msg_789"
},
"message": {
"_id": "msg_789",
"type": "template",
"status": "delivered",
"payload": {
"template": {
"name": "order_notification"
}
},
"createdAt": "2026-06-10T10:01:00.000Z"
},
"session": {
"_id": "session_456",
"status": "opened"
}
}
],
"options": {
"pagination": {
"currentPage": 1,
"pageItems": 50,
"totalCount": 150,
"totalPages": 3
},
"sorting": {},
"filtering": {},
"searching": {}
}
}
Eintragsfelder
| Feld | Typ | Beschreibung |
|---|---|---|
_id | string | Eintrags-ID |
bulkOperationId | string | ID des Massenvorgangs, zu dem dieser Eintrag gehört |
position | number | Reihenfolge des Empfängers im Array recipients der Anfrage, beginnend bei 0 |
payload | object | Der Empfänger genau so, wie er in der Anfrage gesendet wurde (username / userId / sessionId, referenceId, payload, isMerge) |
status | string | Eintragsstatus: pending, succeeded, failed, cancelled, unknown |
error | object | Nur bei failed-Einträgen: code, message und retryable |
result.userId | string | Benutzer-ID des Empfängers |
result.sessionId | string | ID der Konversationssitzung |
result.messageId | string | ID der gesendeten Nachricht (fehlt, wenn keine Nachricht gesendet wurde) |
completedAt | string | Wann der Eintrag verarbeitet wurde |
message | object | Nachrichtendetails (nur bei list-with-messages) |
session | object | Konversationsdetails (nur bei list-with-messages) |
Vergleich: list und list-with-messages
| Merkmal | list | list-with-messages |
|---|---|---|
| Seitenumbruch | Ja | Ja |
| Filterung | Ja (nur Eintragsfelder) | Ja (Eintrags- und Nachrichtenfelder) |
| Message / Session | Nein | Ja (falls vorhanden) |
| Leistung | Schnell | Mittel (führt JOIN aus) |
| Filter message.status | Nicht verfügbar | Verfügbar |
- list: alle Einträge schnell auflisten, nach referenceId filtern, Eintragsstatus prüfen
- list-with-messages: WhatsApp-Nachrichtenstatus (delivered, read) ansehen, Nachrichten-Payloads prüfen
- Filterbeispiele:
{"status": "failed"}— fehlgeschlagene Versandeinträge{"payload.referenceId": "ORDER-123"}— bestimmte Referenz-ID{"message.status": "delivered"}— zugestellte Nachrichten (nur list-with-messages){"message.status": "read"}— gelesene Nachrichten (nur list-with-messages){"message.status": "error"}— Nachrichten mit Fehlern (nur list-with-messages){"message.status": {"$in": ["delivered", "read"]}}— Nachrichten, die zugestellt oder gelesen wurden (nur list-with-messages){"message.status": {"$nin": ["error", "not-sended"]}}— Nachrichten ohne Fehler und nicht gesendete (nur list-with-messages){"message": {"$exists": false}}— Einträge ohne Nachricht (nur list-with-messages){"status": {"$in": ["succeeded", "pending"]}}— Einträge, die erfolgreich oder ausstehend sind
- Der Endpunkt
listist schneller; bevorzugen Sie ihn für allgemeine Statusprüfungen - Verwenden Sie
list-with-messages, wenn Nachrichtendetails benötigt werden - Die maximale Anzahl Einträge pro Seite (pageItems) beträgt 50; ohne Angabe gilt 50
- Der Filter
message.statusfunktioniert nur inlist-with-messages - Einträge ohne
result.messageIdhaben keinmessage-Objekt
Stop – Versand abbrechen
Stoppt den laufenden Versand eines Massenvorgangs. Alle pending-Einträge erhalten den Status cancelled, und der Massenvorgang erhält den Status stopped. Bereits als succeeded oder failed verarbeitete Einträge sind nicht betroffen. Ein geplanter Massenvorgang kann auch vor seinem scheduleAt-Zeitpunkt gestoppt werden.
POST https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation/stop.js
Diese Aktion kann nicht rückgängig gemacht werden. Ein gestoppter Versand kann nicht fortgesetzt werden.
Anfrageparameter
| Parameter | Typ | Pflicht | Beschreibung |
|---|---|---|---|
bulkOperationId | string | Ja | ID des zu stoppenden Massenvorgangs |
{
"bulkOperationId": "abc123xyz789"
}
curl --location 'https://app.monochat.ai/api/:slug/custom-functions/bulk-message-api-app/api/v2/bulk-operation/stop.js' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_JWT_TOKEN' \
--data '{
"bulkOperationId": "abc123xyz789"
}'
Antwort
Bei einer erfolgreichen Anfrage ist der Antwort-Body leer. Ein HTTP-Status 200 zeigt an, dass der Vorgang erfolgreich abgeschlossen wurde.
{}
- Es können nur Massenvorgänge gestoppt werden, die über diese API erstellt wurden
- Nach dem Stoppen eines Versands können Sie mit dem Endpunkt
showdie Anzahl der abgebrochenen Einträge prüfen (bulkOperation.progress.cancelled) - Wird der Massenvorgang nicht gefunden, gibt die API den Fehler
Bulk operation not found.zurück