Zum Inhalt springen
OmniChannels.ai

WhatsApp-Nachricht per API senden: cURL, Node, Python, PHP

WhatsApp-Nachrichten per API senden: Beispiele in cURL, Node.js, Python und PHP für Vorlagen und Session-Nachrichten, plus Statusverfolgung und Fehler.

Aktualisiert 10 Min. Lesezeit

Von OmniChannels.ai Editorial Team · Geprüft von BroadNet Messaging Solutions Team

Integration

Kurze Antwort

Mit der OmniChannels.ai-API senden Sie jede WhatsApp-Nachricht über einen einzigen Endpunkt, POST https://api.broadnet.me/whatsapp/message/sendbulk, als Multipart-Formulardaten mit einem Authorization: Bearer-Header. Das Feld messageType wählt die Nutzlast: TEMPLATE für freigegebene Vorlagen, die Sie brauchen, um eine Konversation zu beginnen oder außerhalb des 24-Stunden-Fensters zu schreiben, und TEXT, IMAGE oder INTERACTIVE für Antworten innerhalb davon.

Auf dieser Seite
  1. Wie sende ich eine WhatsApp-Nachricht über die API?
  2. Vorlage oder Session-Nachricht: Was sende ich?
  3. Wie sende ich eine freigegebene Vorlage?
  4. Welche Anfragefelder sind am wichtigsten?
  5. Wie sende ich eine Vorlage mit Button oder OTP?
  6. Wie antworte ich innerhalb des Kundenservice-Fensters?
  7. Wie verfolge ich die Zustellung?
  8. Welche Fehler muss ich behandeln?
  9. Praxisbeispiel: ein Dienst für Bestellbenachrichtigungen
  10. Welche typischen Fehler gibt es?
  11. So unterstützt OmniChannels.ai

Das Wichtigste

  • Alle WhatsApp-Nachrichten laufen über POST /whatsapp/message/sendbulk; messageType (TEMPLATE, TEXT, IMAGE, INTERACTIVE und weitere) bestimmt, welche Felder erforderlich sind.
  • Die Anfrage ist multipart/form-data, nicht JSON, daher braucht Python files= und PHP einen Array-Body, um URL-Kodierung zu vermeiden.
  • Außerhalb des 24-Stunden-Kundenservice-Fensters kann nur eine freigegebene Vorlage gesendet werden; innerhalb können Sie Freitext, Medien und interaktive Nachrichten senden.
  • Der Aufruf stellt die Nachrichten in die Warteschlange und gibt sofort eine batchId zurück; Status je Empfänger kommen an Ihrem Webhook und vom Bulk-Insights-Endpunkt.
  • Die API hat keinen Idempotency-Key, daher sollten Sie jeden Versand vor dem Aufruf protokollieren und nach einem Timeout den Status prüfen, statt erneut zu senden.

Dieser Leitfaden richtet sich an Entwickler, die den WhatsApp-Versand in eine Anwendung integrieren. Er zeigt funktionierende Anfragen in cURL, Node.js, Python und PHP, erklärt den Unterschied zwischen Vorlagen- und Session-Nachrichten und behandelt Verfolgung und Fehler. Jeder Endpunkt und jedes Feld stammt aus unserer WhatsApp-API-Referenz und der OpenAPI-Spezifikation.

Wie sende ich eine WhatsApp-Nachricht über die API?

Sie richten einen einzigen authentifizierten POST an https://api.broadnet.me/whatsapp/message/sendbulk mit Formularfeldern. Das Feld messageType wählt die Art der Nachricht, und die Antwort bestätigt, dass die Nachrichten in die Warteschlange gestellt wurden.

Element Wert
Basis-URL https://api.broadnet.me (kein Präfix /v1)
Endpunkt POST /whatsapp/message/sendbulk
Authentifizierung Authorization: Bearer $BROADNET_TOKEN
Inhaltstyp multipart/form-data (wird von Ihrem HTTP-Client automatisch gesetzt)
Antwort JSON-Batch-Zusammenfassung mit einer batchId

Testzugangsdaten werden nach einer kurzen Zugangsanfrage ausgestellt, und Testsendungen gehen an Ihre eigenen verifizierten Nummern. Siehe den Quickstart und die Seiten zur Authentifizierung. Halten Sie das Token ausschließlich auf Ihrem Server.

Vorlage oder Session-Nachricht: Was sende ich?

Senden Sie eine Vorlage, um eine Konversation zu beginnen oder außerhalb des Fensters zu schreiben, und eine Session-Nachricht, wenn der Kunde Ihnen in den letzten 24 Stunden geschrieben hat. Diese Regel stammt von Meta, nicht von uns.

Vorlagennachricht Session-Nachricht
messageType TEMPLATE TEXT, IMAGE, VIDEO, AUDIO, DOCUMENT, INTERACTIVE und weitere
Wann erlaubt Jederzeit, sobald die Vorlage freigegeben ist Nur solange das Kundenservice-Fenster offen ist
Freigabe nötig Ja, durch Meta Nein
Typische Verwendung Bestellupdates, OTP, Erinnerungen, Kampagnen Support-Antworten, Antworten auf Fragen

Meta berechnet jede zugestellte Nachricht nach Kategorie, und seine Regeln für Servicenachrichten und Utility-Vorlagen haben sich zum 1. Oktober 2026 geändert. Unser Fenster-Leitfaden behandelt die Mechanik, und unsere Preisseite und der Rechner die Kosten.

Wie sende ich eine freigegebene Vorlage?

Setzen Sie messageType=TEMPLATE, nennen Sie die Vorlage und ihren Sprachcode und übergeben Sie die Variablenwerte. Mit batchId=0 beginnen Sie einen neuen Batch.

curl -X POST https://api.broadnet.me/whatsapp/message/sendbulk \
  -H "Authorization: Bearer $BROADNET_TOKEN" \
  -F batchId=0 \
  -F campaignName=order-updates \
  -F destinationNo=971500000000 \
  -F messageType=TEMPLATE \
  -F templateName=order_update \
  -F templateLanguage=en_US \
  -F bodyTemplateVariables=INV-400
// Node.js 18+ (integriertes fetch und FormData)
const form = new FormData();
form.append("batchId", "0");
form.append("campaignName", "order-updates");
form.append("destinationNo", "971500000000");
form.append("messageType", "TEMPLATE");
form.append("templateName", "order_update");
form.append("templateLanguage", "en_US");
form.append("bodyTemplateVariables", "INV-400");

const res = await fetch("https://api.broadnet.me/whatsapp/message/sendbulk", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.BROADNET_TOKEN}` }, // fetch setzt die Multipart-Grenze
  body: form,
});
console.log(await res.json());
import os
import requests

fields = {
    "batchId": "0",
    "campaignName": "order-updates",
    "destinationNo": "971500000000",
    "messageType": "TEMPLATE",
    "templateName": "order_update",
    "templateLanguage": "en_US",
    "bodyTemplateVariables": "INV-400",
}
# Jedes Feld als Multipart-Teil senden (files=) statt URL-kodiert (data=).
r = requests.post(
    "https://api.broadnet.me/whatsapp/message/sendbulk",
    headers={"Authorization": f"Bearer {os.environ['BROADNET_TOKEN']}"},
    files={k: (None, v) for k, v in fields.items()},
    timeout=30,
)
print(r.json())
<?php
$ch = curl_init("https://api.broadnet.me/whatsapp/message/sendbulk");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("BROADNET_TOKEN")],
    // Ein Array (kein String) lässt cURL multipart/form-data senden.
    CURLOPT_POSTFIELDS => [
        "batchId" => "0",
        "campaignName" => "order-updates",
        "destinationNo" => "971500000000",
        "messageType" => "TEMPLATE",
        "templateName" => "order_update",
        "templateLanguage" => "en_US",
        "bodyTemplateVariables" => "INV-400",
    ],
]);
echo curl_exec($ch);
curl_close($ch);

Das Ziel ist Ländervorwahl plus Nummer, nur Ziffern. Der Aufruf kehrt sofort mit einer Batch-Zusammenfassung zurück:

{
  "totalFiles": 1,
  "totalSuccess": 1,
  "totalFailed": 0,
  "totalDuplicates": 0,
  "batchId": "2609091405000000001",
  "fileResults": [
    {
      "fileName": "direct",
      "totalRecords": 1,
      "successCount": 1,
      "failedRecipients": [],
      "duplicateRecipients": []
    }
  ],
  "message": "Messages queued for delivery"
}

Speichern Sie die batchId neben Ihrem eigenen Datensatz. „In der Warteschlange“ heißt nicht „zugestellt“.

Welche Anfragefelder sind am wichtigsten?

Welche Felder erforderlich sind, hängt von messageType ab. Dies sind die gängigen.

Feld Erforderlich Beschreibung
messageType Ja TEXT, IMAGE, VIDEO, AUDIO, DOCUMENT, STICKER, LOCATION, CONTACTS, TEMPLATE, INTERACTIVE, REACTION oder FLOW
destinationNo oder destinationFiles Eines von beiden Nummern, getrennt durch Kommas, Semikolons oder Zeilenumbrüche; oder eine TXT-, CSV- oder XLSX-Datei
batchId Nein 0 beginnt einen neuen Batch
campaignName Nein Ihre Bezeichnung für das Reporting
allowDuplicate Nein false entfernt doppelte Empfänger
templateName, templateLanguage Für TEMPLATE Name der freigegebenen Vorlage und Sprachcode, etwa en_US oder ar
bodyTemplateVariables Je Vorlage Wert der Body-Variable; benannte Parameter werden als JSON übergeben
buttonsTemplateVariable Je Vorlage Dynamischer Button-Wert: URL-Suffix, Gutscheincode oder OTP-Code
content Für TEXT Textkörper, bis zu 4.096 Zeichen, oder eine Bildunterschrift für Medien
mediaUrl Je Typ Öffentliche HTTPS-URL des Mediums
interactivePayload Für INTERACTIVE Metas Interactive-Objekt als JSON-String

Die Planung nutzt scheduled, scheduleTime und gmt, und delay drosselt die Zustellung. Die vollständige Liste steht in der WhatsApp-API-Referenz.

Wie sende ich eine Vorlage mit Button oder OTP?

Fügen Sie den Button-Wert in buttonsTemplateVariable hinzu. Für eine Authentifizierungsvorlage mit Button zum Kopieren des Codes übergeben Sie den Code sowohl im Body- als auch im Button-Feld.

curl -X POST https://api.broadnet.me/whatsapp/message/sendbulk \
  -H "Authorization: Bearer $BROADNET_TOKEN" \
  -F batchId=0 \
  -F destinationNo=971500000000 \
  -F messageType=TEMPLATE \
  -F templateName=login_code \
  -F templateLanguage=en_US \
  -F bodyTemplateVariables=482913 \
  -F buttonsTemplateVariable=482913

Hier ist login_code ein Platzhalter für Ihre eigene freigegebene Authentifizierungsvorlage. Bei mehreren Buttons nimmt buttonsTemplateVariable ein JSON-Array entgegen. Erzeugen Sie den Code auf Ihrem Server, speichern Sie ihn gehasht mit Ablaufzeit und protokollieren Sie ihn nie. Unser OTP-Leitfaden behandelt One-Tap-, Zero-Tap- und Copy-Code-Zustellung.

Wie antworte ich innerhalb des Kundenservice-Fensters?

Verwenden Sie einen Session-Nachrichtentyp. Eine einfache Textantwort braucht messageType=TEXT und content.

curl -X POST https://api.broadnet.me/whatsapp/message/sendbulk \
  -H "Authorization: Bearer $BROADNET_TOKEN" \
  -F batchId=0 \
  -F destinationNo=971500000000 \
  -F messageType=TEXT \
  -F campaignName=support \
  -F "content=Your order has shipped. Reply here if you need anything."

Für Antwort-Buttons senden Sie messageType=INTERACTIVE und einen interactivePayload im Format von Metas Interactive-Nachrichten.

curl -X POST https://api.broadnet.me/whatsapp/message/sendbulk \
  -H "Authorization: Bearer $BROADNET_TOKEN" \
  -F batchId=0 \
  -F destinationNo=971500000000 \
  -F messageType=INTERACTIVE \
  -F campaignName=support \
  -F 'interactivePayload={"type":"button","body":{"text":"Confirm your delivery slot?"},"action":{"buttons":[{"type":"reply","reply":{"id":"slot_ok","title":"Confirm"}},{"type":"reply","reply":{"id":"slot_change","title":"Change"}}]}}'

Um eine eingehende Nachricht als gelesen zu markieren und optional eine Tipp-Anzeige zu zeigen, rufen Sie POST /whatsapp/message/read mit JSON auf:

curl -X POST https://api.broadnet.me/whatsapp/message/read \
  -H "Authorization: Bearer $BROADNET_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "messageId": "wamid.HBgMOTcxNTAwMDAwMDAwFQIAEhgg", "typing": true }'

Hinweise zur Gestaltung finden Sie in unserem Leitfaden zu interaktiven Nachrichten.

Wie verfolge ich die Zustellung?

Status werden an den in Ihrem Account konfigurierten Webhook gesendet und lassen sich auch je Batch abrufen. Jeder Empfänger durchläuft SUBMITTED, SENT, DELIVERED und READ oder endet als FAILED bzw. REJECTED mit einem Grund.

curl "https://api.broadnet.me/whatsapp/message/bulk-insights?batch_Id=2609091405000000001&status=FAILED&page=0&size=50" \
  -H "Authorization: Bearer $BROADNET_TOKEN"

batch_Id ist erforderlich; status, destination, search, page und size sind optional, und page ist nullbasiert. Nutzen Sie Polling als Absicherung gegen verpasste Ereignisse und bauen Sie Ihren Empfänger wie in unserem Webhooks-Leitfaden beschrieben. Batches lassen sich außerdem mit den Batch-Endpunkten der Referenz pausieren, fortsetzen und abbrechen.

Welche Fehler muss ich behandeln?

Lesen Sie zuerst den HTTP-Status, dann den Fehler-Body. Die API meldet Fehler in einem JSON-Body mit fünf Feldern, und WhatsApp-spezifische Fehler können von Meta kommen.

Status Bedeutung Maßnahme
400 Validierungsfehler, etwa ein fehlendes typspezifisches Feld oder ein ungültiges Ziel Anfrage korrigieren; nicht unverändert wiederholen
401 / 403 Fehlendes oder ungültiges Token oder Operation nicht erlaubt Token korrigieren oder uns bitten, die Operation freizuschalten
404 Vorlage oder Absender nicht gefunden Vorlagenname und Sprache prüfen
413 Hochgeladene Datei zu groß Datei verkleinern
429 Ratenlimit Auf Retry-After warten
502 Meta hat den Aufruf abgelehnt; message enthält Metas Fehlercode und Text Lesen; nur bei vorübergehendem Fehler wiederholen
500, 503, 504 Server- oder Upstream-Problem Mit exponentiellem Backoff und Jitter wiederholen

Unser Leitfaden zu Fehlercodes erklärt gängige Meta-Codes. Da es keinen Idempotency-Key gibt, befolgen Sie die Schritte zum Schutz vor Duplikaten unter Fehler und Limits: zuerst einen ausstehenden Datensatz schreiben, die zurückgegebene batchId speichern und nach einem Timeout den Status prüfen, bevor Sie erneut senden.

Praxisbeispiel: ein Dienst für Bestellbenachrichtigungen

„Souq Rafiq“ (fiktiv), ein Händler in den VAE, sendet eine Vorlage order_update, wenn eine Bestellung versandt wird.

  1. Der Bestelldienst schreibt eine Zeile mit dem Schlüssel order-8842-shipped und dem Status pending.
  2. Er ruft sendbulk mit der Vorlage und der Bestellnummer als bodyTemplateVariables auf.
  3. Bei 200 speichert er die batchId und markiert die Zeile als accepted.
  4. Der Webhook-Handler setzt die Zeile auf DELIVERED oder READ bzw. auf FAILED mit einem Grund.
  5. Antwortet der Kunde, nutzt das Support-Tool innerhalb des Fensters eine Session-Nachricht vom Typ TEXT.
  6. Ein nächtlicher Job liest bulk-insights für die Batches des Vortags und gleicht fehlende Status ab.

Welche typischen Fehler gibt es?

  • JSON senden. Der WhatsApp-Sendeendpunkt ist Multipart; Content-Type: application/json funktioniert nicht.
  • Python data= statt files=, was das Formular URL-kodiert.
  • Freitext außerhalb des Fensters, der fehlschlägt. Nutzen Sie eine Vorlage.
  • Falscher Sprachcode, etwa en statt en_US der Vorlage.
  • 200 als zugestellt werten. Es bedeutet: in der Warteschlange.
  • Blinde Wiederholungen nach einem Timeout, die einen Kunden doppelt anschreiben können.
  • Token im Client-Code. Rufen Sie die API nur aus Ihrem Backend auf.
  • Grenzen: Die Payload-Details variieren je Vorlage. Bestätigen Sie das Variablenlayout für Ihre erste personalisierte Kampagne mit unserem Team.

So unterstützt OmniChannels.ai

BroadNet ist ein offizieller Meta Business Solution Provider, und das Onboarding für die WhatsApp Business API nutzt Meta Embedded Signup; unser Team bereitet die Registrierung gemeinsam mit Ihnen vor, die Freigaben bleiben bei Meta. Die REST-API ist mit einer OpenAPI-3.1-Spezifikation und einem TypeScript-SDK, @broadnet/cpaas-sdk, dokumentiert, und Zustellstatus werden kanalübergreifend normalisiert. Beginnen Sie mit der WhatsApp-API-Dokumentation oder dem Quickstart.

Häufige Fragen

Sende ich WhatsApp-Nachrichten als JSON oder als Formulardaten?

Als Formulardaten. Der WhatsApp-Sendeendpunkt POST /whatsapp/message/sendbulk nimmt multipart/form-data entgegen, wobei jedes Feld ein Formularteil ist. Einzelsendungen von SMS nutzen JSON, was eine häufige Quelle von Verwechslungen ist. Senden Sie die Felder in Python über files= statt data= und übergeben Sie in PHP ein Array als Body, damit cURL Multipart erzeugt.

Kann ich eine WhatsApp-Nachricht ohne Vorlage senden?

Nur innerhalb des Kundenservice-Fensters. Wenn ein Kunde Ihnen schreibt, öffnet sich ein 24-Stunden-Fenster, in dem Sie mit Text, Medien oder interaktiven Nachrichten antworten können. Außerhalb davon oder um eine Konversation zu beginnen, müssen Sie eine freigegebene Vorlage senden. Die API setzt Metas Regeln durch, und ein Freitext-Versand in ein geschlossenes Fenster schlägt fehl.

Woran erkenne ich, ob die Nachricht zugestellt wurde?

Der Sendeaufruf bestätigt nur, dass Nachrichten in die Warteschlange gestellt wurden, und liefert eine batchId. Die Status je Empfänger durchlaufen SUBMITTED, SENT, DELIVERED und READ oder enden als FAILED bzw. REJECTED. Sie werden an Ihren Webhook gesendet und lassen sich auch je Batch über den Bulk-Insights-Endpunkt abrufen.

Kann ich in einer Anfrage an viele Empfänger senden?

Ja. destinationNo akzeptiert mehrere Nummern, getrennt durch Kommas, Semikolons oder Zeilenumbrüche, und destinationFiles akzeptiert eine TXT-, CSV- oder XLSX-Datei. Für eine Vorlage mit unterschiedlichen Variablen je Empfänger laden Sie eine personalisierte Datei mit einer Zeile pro Empfänger hoch. Setzen Sie allowDuplicate auf false, um doppelte Nummern zu entfernen.

Gibt es einen Idempotency-Key, der doppelte Sendungen verhindert?

Nein. Die API akzeptiert keinen Idempotency-Key. Läuft eine Anfrage in ein Timeout, können Sie clientseitig nicht erkennen, ob sie angenommen wurde. Protokollieren Sie jeden Versand vor dem Aufruf in Ihrer eigenen Datenbank, speichern Sie die zurückgegebene batchId und prüfen Sie vor jeder Wiederholung den Status oder die Batch-Liste.

Brauche ich vor dem Senden ein Opt-in?

Ja. Metas Richtlinie verlangt, dass jeder Empfänger eingewilligt hat, Nachrichten Ihres Unternehmens zu erhalten, und Vorlagen müssen vor der Nutzung freigegeben sein. Die API prüft die Einwilligung nicht für Sie. Erfassen Sie das Opt-in an der Quelle, speichern Sie den Nachweis und sperren Sie jeden, der sich abmeldet.

Quellen

  1. WhatsApp Business Messaging Policy
  2. Pricing on the WhatsApp Business Platform — Meta for Developers
  3. RFC 7578: Returning Values from Forms: multipart/form-data