Zum Inhalt springen
20 min read

Ihre Software mit WhatsApp verbinden

API-Schlüssel ausstellen, eine genehmigte WhatsApp-Vorlage zuordnen, einen Webhook auf Ihren eigenen Server richten und die REST-API aufrufen — der vollständige Leitfaden zur API-Verwaltung.

Ihre Software mit WhatsApp verbinden

Über die API-Verwaltung versendet ein anderes System — Ihre Abrechnungssoftware, Ihr Onlineshop, Ihr eigenes Backend — WhatsApp-Nachrichten über WizMessage. Sie stellen ihm hier einen API-Schlüssel aus, legen fest, welche genehmigte WhatsApp-Vorlage es senden darf, und richten es auf einen Webhook aus, damit Antworten zurückkommen. Dieser Leitfaden führt durch den gesamten Weg und dokumentiert anschließend die REST-API, die Ihre Entwickler aufrufen werden.

Das Dashboard

Wo Ihre API-Schlüssel liegen

Jeder von Ihnen ausgestellte Schlüssel erscheint hier unter „API Keys“. Jede Zeile zeigt den Status des Schlüssels, sein öffentliches Präfix (der einzige Teil des Schlüssels, der nach dem Erstellen überhaupt noch einmal angezeigt wird) und wie viele Aufrufe er heute getätigt hat. „Manage“ öffnet den Schlüssel; der Schalter pausiert ihn, ohne ihn zu löschen.

Video-Walkthrough — 2 Schritte, 0:05. Wählen Sie einen Schritt, um nur diesen Teil abzuspielen.
Das API-Schlüssel-Dashboard listet jeden ausgestellten Schlüssel mit Status, öffentlichem Präfix und täglicher Aufrufanzahl auf

Ein Schlüssel, der noch nicht fertig ist

Ein Schlüssel ohne zugeordnete Vorlage trägt das Kennzeichen „Needs setup“. Er kann sich authentifizieren, aber keine Vorlagennachricht senden, solange Sie ihm keine zuordnen — eine halb konfigurierte Integration ist so auf einen Blick erkennbar, statt später beim Senden zu scheitern.

Eine API-Schlüssel-Zeile mit dem Kennzeichen „Needs setup“, weil ihr noch keine Vorlage zugeordnet ist

Geführte Einrichtung

Schritt 1 — Was möchten Sie verbinden?

„Connect your software“ öffnet einen Assistenten mit vier Schritten. Benennen Sie den Schlüssel zunächst nach dem System, das ihn verwenden wird, und wählen Sie die passende Vorgabe. Die Vorgaben schlagen lediglich sinnvolle Feldnamen vor — die Abrechnungsvorgabe schlägt invoice_number, amount, due_date und customer_name vor — sie schränken nicht ein, was Sie zuordnen können.

Video-Walkthrough — 4 Schritte, 0:19. Wählen Sie einen Schritt, um nur diesen Teil abzuspielen.
Schritt 1 des Assistenten: Benennung des API-Schlüssels und Auswahl der Vorgabe, die zum verbindenden System passt

Schritt 2 — Nachricht auswählen

Wählen Sie eine Ihrer genehmigten WhatsApp-Vorlagen. Vorlagen liegen bei Meta, nicht hier — diese Liste wird live aus Ihrem verbundenen WhatsApp-Konto abgerufen, und nur GENEHMIGTE Vorlagen lassen sich senden. Dieser Schritt ist optional: Überspringen Sie ihn, wenn der Schlüssel ausschließlich reinen Text sendet, und ordnen Sie später eine Vorlage zu.

Schritt 2 des Assistenten: Auswahl einer der genehmigten WhatsApp-Vorlagen, die live von Meta abgerufen werden

Schritt 3 — Wohin sollen Antworten gehen?

Wenn jemand auf Ihre Nachricht antwortet oder eine Zustellmeldung eintrifft, senden wir sie per POST an eine URL, die Sie kontrollieren. Lassen Sie dies aus, wenn Ihr System ausschließlich sendet. Sie können die URL später im Tab „Webhooks“ des Schlüssels ergänzen — nichts davon ist endgültig.

Schritt 3 des Assistenten: Festlegen der Webhook-URL, an die Antworten und Zustellmeldungen gesendet werden

Schritt 4 — Live gehen

Erst der Klick auf „Next“ im vorherigen Schritt erstellt den Schlüssel tatsächlich — dieser Bildschirm ist die Bestätigung. Kopieren Sie jetzt alle drei Werte: Der API-Schlüssel, das API-Secret und das Webhook-Signaturgeheimnis werden genau einmal angezeigt und lassen sich danach nicht wiederherstellen. Verlieren Sie das Secret, müssen Sie es rotieren — und damit jedes System aktualisieren, das es verwendet hat.

Schritt 4 des Assistenten: API-Schlüssel, API-Secret und Webhook-Signaturgeheimnis werden genau einmal angezeigt

Einen Schlüssel verwalten

Übersicht

Beim Öffnen eines Schlüssels landen Sie auf dem Tab „Overview“: was er darf, wie stark er genutzt wird und welche Endpunkte er aufrufen kann. Die Nutzungszahlen stammen aus dem Anfrageprotokoll und spiegeln daher echten Traffic wider.

Video-Walkthrough — 1 Schritt, 0:05.
Der Tab „Overview“ eines API-Schlüssels mit seinen Berechtigungen, seiner Nutzung und den aufrufbaren Endpunkten

Ein Schlüssel, der noch eingerichtet werden muss

Ein Schlüssel ohne zugeordnete Vorlage öffnet stattdessen den Tab „Setup“ — derselbe Assistent, direkt eingebettet. Beachten Sie, dass sich die Tabs vom vorherigen Screenshot unterscheiden: Solange ein Schlüssel nicht mindestens eine Vorlage hat, werden „Templates“ und „Webhooks“ nicht angeboten, weil es für sie noch nichts zu tun gibt.

Video-Walkthrough — 1 Schritt, 0:05.
Ein nicht konfigurierter Schlüssel öffnet den Tab „Setup“, die Tabs „Templates“ und „Webhooks“ werden noch nicht angeboten

Vorlagen

Im Tab „Templates“ steht jede Karte für eine Vorlage, die dieser Schlüssel senden darf. Der Fließtext ist die bei Meta genehmigte Nachricht, und die Chips darunter sind die Variablennamen, die Ihr System liefern wird. „Try it“ sendet einen Test, „Get code“ erzeugt eine fertige Anfrage in acht Programmiersprachen.

Video-Walkthrough — 2 Schritte, 0:07. Wählen Sie einen Schritt, um nur diesen Teil abzuspielen.
Der Tab „Templates“ mit einer Karte je Vorlage samt genehmigtem Fließtext und Chips für die Variablennamen

Die Variablen richtig lesen — der eine Punkt, bei dem Sie innehalten sollten

Sehen Sie sich die Karte payment_failed_alert an. Ihre Nachricht enthält {{1}}, dann {{3}}, dann {{2}} — die Platzhalter stehen im Text NICHT in numerischer Reihenfolge. Die Chips darunter sind numerisch sortiert: customer_name füllt {{1}}, renewal_date füllt {{2}}, plan_name füllt {{3}}. Ordnen Sie Ihre Werte immer der NUMMER zu, niemals der Reihenfolge, in der die Platzhalter zufällig im Satz auftauchen. Genau hier passieren die meisten Fehler — besonders bei übersetzten Vorlagen, in denen die Wortstellung die Platzhalter verschiebt.

Eine Vorlagenkarte, deren Platzhalter im Nachrichtentext nicht in numerischer Reihenfolge stehen

Die drei Schaltflächen auf jeder Vorlage

„Try it“ — einen Test senden, ohne Code zu schreiben

Die Papierflieger-Schaltfläche öffnet diese Vorlage vorbelegt mit Beispielwerten, einem je Variablenname. Das ist der schnellste Weg, eine Zuordnung zu prüfen, bevor Ihre Entwickler sie anfassen. Beachten Sie den Schalter: „Simulate Only“ ist die Voreinstellung, und nichts verlässt das Haus — der Server spiegelt Ihre Nutzlast einfach zurück. Stellen Sie ihn auf „Send Real Message“, geht eine echte WhatsApp-Nachricht an die Nummer im Feld — und wird berechnet.

Video-Walkthrough — 7 Schritte, 0:21. Wählen Sie einen Schritt, um nur diesen Teil abzuspielen.
Der Dialog „Try it“, vorbelegt mit je einem Beispielwert pro Variable und dem Schalter „Simulate Only“

Was eine simulierte Sendung zurückgibt

Ein Klick auf „Send Request“ im Modus „Simulate Only“ liefert die Anfrage so zurück, wie die Plattform sie empfangen hat — mit HTTP-Status und Laufzeit. Verstehen Sie das als Formprüfung, nicht als Generalprobe: Es bestätigt, dass Ihr JSON geparst und der Schlüssel akzeptiert wurde, aber es prüft Ihre Variablennamen NICHT gegen die Zuordnung und kontaktiert Meta nie. Eine Nutzlast, die sauber simuliert, kann im Ernstfall trotzdem abgelehnt werden. Um die Zuordnung selbst zu belegen, schalten Sie „Send Real Message“ ein und senden an Ihr eigenes Telefon.

Die Antwort einer simulierten Sendung: die zurückgespiegelte Anfrage mit HTTP-Status und Laufzeit

„Get code“ — die fertig geschriebene Anfrage

Die Schaltfläche mit den spitzen Klammern erzeugt eine funktionierende Anfrage für genau diese Vorlage in acht Sprachen: cURL, JavaScript, Node.js, Python, PHP, Ruby, Go und C#. Geben Sie sie an die Person weiter, die die Integration schreibt. Die Variablen erscheinen als {{placeholders}}, benannt nach Ihrer Zuordnung, und die Zugangsdaten bleiben als YOUR_API_KEY / YOUR_API_SECRET stehen — dieser Dialog gibt Ihren echten Schlüssel nie aus, das Snippet lässt sich also gefahrlos in ein Ticket einfügen.

Der Dialog „Get code“ mit einer fertigen Anfrage für diese Vorlage und Platzhaltern für die Zugangsdaten

Die Sprache wechseln

Klicken Sie oben auf eine beliebige Sprache, und das Snippet wird dafür neu geschrieben — derselbe Aufruf, dieselben Header, der HTTP-Client dieser Sprache. Jedes wird beim ersten Klick erzeugt, ein kurzer Spinner beim ersten Wechsel ist also normal. „Copy“ übernimmt das Snippet so, wie es dasteht: Es ist vollständig, inklusive Imports, und wenn dieser Schlüssel Signaturen verlangt, ist der Signaturschritt bereits enthalten.

Dieselbe Anfrage, nach einem Klick in der Sprachleiste für eine andere Sprache neu geschrieben

„Edit“ — ändern, was Ihr System sendet

Der Stift öffnet die Zuordnung selbst. Die Handy-Vorschau oben ist die echte Nachricht mit Ihren aktuellen Namen eingesetzt, Sie sehen also, was der Kunde lesen wird. Darunter lässt sich jede erkannte Variable umbenennen, umsortieren, als Pflichtfeld markieren oder mit einem Typ versehen — ein Datum, ein Geldbetrag, ein Bild. Eine Variable umzubenennen benennt sie auch in Ihrer API-Nutzlast um, ein System, das den alten Namen bereits sendet, beginnt also zu scheitern: Ändern Sie beides gemeinsam.

Der Bearbeitungsdialog der Zuordnung mit Handy-Vorschau über der umbenennbaren, umsortierbaren Variablenliste

Test API — dasselbe Werkzeug, jeder Endpunkt

„Test API“ oben im Tab ist „Try it“ ohne die Vorlagenbindung: Wählen Sie einen der drei Sende-Endpunkte, wechseln Sie die Vorlage über das zweite Auswahlfeld und bearbeiten Sie den Rumpf frei. Nutzen Sie es, um die rohen Aufrufe /messages/text oder /messages/template zu prüfen, die keine eigene Karte haben, weil sie an keine Zuordnung gebunden sind. Beachten Sie, dass die Variablen dieser Vorlage noch body_1, body_2, body_3 heißen — so sieht eine nicht zugeordnete Vorlage aus, und genau dafür gibt es „Edit“.

Der Dialog „Test API“ mit Endpunkt-Auswahl, Vorlagen-Auswahl und frei bearbeitbarem Rumpf

Antworten

Webhooks — Antworten zurückerhalten

Senden ist nur die halbe Integration. Richten Sie einen Webhook auf Ihren eigenen HTTPS-Endpunkt, und WizMessage sendet eingehende Nachrichten und Zustellaktualisierungen per POST dorthin. Das Signaturgeheimnis wird bei der Erzeugung einmalig angezeigt; prüfen Sie es bei jeder Zustellung, damit Sie sicher sein können, dass der Aufruf wirklich von uns stammt.

Der Tab „Webhooks“, in dem ein HTTPS-Endpunkt eingehende Nachrichten und Zustellaktualisierungen empfängt

Welche Ereignisse Sie erhalten

Wählen Sie aus, welche Ereignisse dieser Endpunkt erhalten soll. Jedes kommt als eigener POST an.

EreignisWann es ausgelöst wird
message.receivedEin Kunde hat Ihnen eine Nachricht geschickt.
message.reactionJemand hat eine Emoji-Reaktion hinzugefügt oder entfernt. Wird in beide Richtungen ausgelöst — siehe Reaktionen.
message.sentEine Nachricht ging raus — über die API, über das Dashboard oder auf dem Telefon des Unternehmens getippt. data.source sagt Ihnen, welches davon.
message.deliveredDie Nachricht hat das Gerät des Empfängers erreicht.
message.readDer Empfänger hat sie geöffnet.
message.failedSenden oder Zustellung ist fehlgeschlagen; data.error enthält den Grund.

Hinweis: message.received und eingehende message.reaction werden nur zugestellt, wenn das Chatbot-System des Kontos auf Webhook steht. Steht es auf etwas anderes, gehen eingehende Nachrichten stattdessen an den Bot und Ihr Endpunkt wird nie aufgerufen — der Webhooks-Tab warnt Sie in diesem Fall. Reaktionen, die das Unternehmen selbst sendet (direction: "outbound"), sind von dieser Einstellung nicht betroffen.

Hinweis: Reaktionen, die das Unternehmen von seinem eigenen Telefon sendet, kamen früher als message.sent mit dem Body "[Unsupported message type]" an. Sie kommen jetzt als message.reaction mit direction: "outbound" an. Haken Sie das neue Ereignis an, falls Sie sich darauf verlassen haben.

Zustellungen erfolgen mindestens einmal (at-least-once). Entfernen Sie Duplikate anhand von event zusammen mit data.message_id statt allein anhand des Headers X-Webhook-Id, und antworten Sie zügig mit 2xx.

REST-API-Referenz

Alles bisher Beschriebene konfiguriert den Schlüssel. Das Folgende ist das, was Ihre Entwickler tatsächlich aufrufen. Die Basis-URL lautet https://wizmessage.com/api/v1/external. Jeder Endpunkt erfordert die untenstehenden Authentifizierungs-Header und unterliegt den Ratenbegrenzungen des Schlüssels.

Authentifizierung

Senden Sie Ihren API-Schlüssel bei jeder Anfrage. Ist für den Schlüssel „Require signature“ aktiviert, müssen Sie die Anfrage zusätzlich signieren — und ein Schlüssel mit dieser Einstellung weist jeden unsignierten Aufruf rundweg ab.

HeaderWert
X-API-KeyIhr API-Schlüssel — der vollständige pk_live_…-Wert, nicht nur das im Dashboard angezeigte Präfix.
X-TimestampUnix-Zeitstempel in Sekunden. Wird abgelehnt, wenn er mehr als 5 Minuten von der Serverzeit abweicht.
X-API-SignatureHMAC-SHA256 von timestamp + "." + rawBody, geschlüsselt mit SHA256(api_secret), Hex in Kleinbuchstaben.

Hinweis: Signaturen werden nur erzwungen, wenn für den Schlüssel require_signature aktiviert ist. Ist das nicht der Fall, genügt der API-Schlüssel allein zum Senden von Nachrichten — genau deshalb ist der Schlüssel ein Geheimnis und keine Kennung. Behandeln Sie ihn wie ein Passwort: Er wird einmal angezeigt, und wer ihn besitzt, kann Ihre Kunden anschreiben.

const crypto = require('node:crypto')

const body = JSON.stringify({ to: '+919876543210', message: 'Hello' })
const timestamp = Math.floor(Date.now() / 1000).toString()

const secretHash = crypto.createHash('sha256').update(API_SECRET).digest('hex')
const signature = crypto.createHmac('sha256', secretHash)
	.update(timestamp + '.' + body)
	.digest('hex')

await fetch('https://wizmessage.com/api/v1/external/messages/text', {
	method: 'POST',
	headers: {
		'Content-Type': 'application/json',
		'X-API-Key': API_KEY,
		'X-Timestamp': timestamp,
		'X-API-Signature': signature,
	},
	body,
})

Endpunkte

MethodePfadZweck
POST/messages/textSendet eine reine Textnachricht. Funktioniert nur innerhalb eines offenen 24-Stunden-Konversationsfensters.
POST/messages/mediaEin Dokument, Bild, Video oder eine Audiodatei senden. Funktioniert nur innerhalb eines offenen 24-Stunden-Fensters.
POST/messages/reactionMit einem Emoji auf eine Nachricht reagieren oder eine gesendete Reaktion entfernen.
POST/messages/templateSendet eine Vorlage, wobei Sie Metas rohes Komponenten-Array selbst liefern.
POST/messages/template/sendSendet eine Vorlage über die Zuordnung, die Sie im Dashboard konfiguriert haben. Dies ist der Endpunkt der Wahl.
POST/messages/interactive/listSendet eine interaktive Listennachricht.
POST/messages/interactive/buttonSendet bis zu drei Antwort-Schaltflächen.
GET/messages/:uuidRuft den Zustellstatus einer von Ihnen gesendeten Nachricht ab.
POST/media/uploadLädt ein PDF/Bild/Video zu Meta hoch und liefert eine media_id zur Verwendung in einem Vorlagen-Header.
GET/templatesListet die für diesen Schlüssel verfügbaren Vorlagen auf.
GET/templates/:nameRuft die Details einer einzelnen Vorlage ab.

Eine zugeordnete Vorlage senden

Dies ist die Nutzlast, die zum Tab „Templates“ gehört. Sie senden Variablen über den NAMEN — die Namen, die als Chips auf der Vorlagenkarte stehen — und die Plattform setzt Metas Komponenten für Sie zusammen. Genau darum geht es beim Zuordnen einer Vorlage: Ihre Abrechnungssoftware muss nichts über Metas Komponentenformat wissen.

POST /api/v1/external/messages/template/send

{
	"to": "+919876543210",
	"template_name": "payment_failed_alert",
	"language": "en",
	"variables": {
		"customer_name": "Priya Sharma",
		"renewal_date": "12 Aug 2026",
		"plan_name": "Wiz Pro"
	},
	"reference": "invoice-2026-0817"
}

Hinweis: Die Variablennamen müssen exakt mit der Zuordnung übereinstimmen — ein unbekannter Name wird ignoriert, ein fehlender Pflichtname mit einem 400 abgelehnt. reference gehört Ihnen: Der Wert wird über Webhooks zurückgespiegelt, sodass Sie eine Zustellmeldung einem Datensatz in Ihrem eigenen System zuordnen können.

Ratenbegrenzungen

Jeder Schlüssel hat eigene Grenzwerte, die im Tab „Overview“ sichtbar sind — standardmäßig 60 Anfragen/Minute und 1.000 Nachrichten/Tag. Die Antworten enthalten das verbleibende Kontingent; drosseln Sie also, wenn es zur Neige geht, statt blind weiterzuprobieren, bis nichts mehr geht.

Dateien über die API senden

Innerhalb eines offenen 24-Stunden-Fensters kann Ihre Software eine Datei direkt senden — ohne Vorlage, ohne Freigabe. Ein Endpunkt deckt Dokumente, Bilder, Video und Audio ab.

Die zwei Wege, eine Datei an eine Media-Nachricht zu hängenPOST /messages/medialinkeine öffentliche URL für WhatsAppbei jedem Versand neu abgerufenideal für bereits gehostete Dateienmedia_ideinmal hochladen, ID wiederverwenden30 Tage gültigideal für oft gesendete DateienEin Link muss öffentlich erreichbar sein — WhatsApp holt ihn ab, Ihr Server sendet ihn nicht.
Jeder Media-Versand trägt genau eines davon. Bei beidem gewinnt die media_id.

Was Sie senden können

Der im Request genannte Typ bestimmt die Grenzen. Größeres oder ein nicht gelistetes Format wird abgewiesen, bevor es WhatsApp erreicht.

TypFormateMax. GrößeBildunterschriftDateiname
documentpdf, doc, docx, xls, xlsx, ppt, pptx, txt100 MB
imagejpg, jpeg, png, webp5 MB
videomp4, 3gp16 MB
audioaac, amr, mp3, ogg, m4a16 MB
POST /api/v1/external/messages/media

{
	"to": "+919876543210",
	"type": "document",
	"link": "https://example.com/invoice-2026-0817.pdf",
	"filename": "Invoice 2026-0817.pdf",
	"caption": "Your invoice for August",
	"reference": "invoice-2026-0817"
}

Einmal hochladen, oft senden

Wenn Sie dieselbe Datei wiederholt senden — Preisliste, Katalog, AGB-PDF — laden Sie sie einmal hoch und behalten Sie die ID. Sie bleibt 30 Tage gültig und erspart WhatsApp das erneute Abrufen Ihrer URL bei jeder Nachricht.

Eine Datei einmal hochladen und wiederholt sendenPOST /media/uploaddie Datei selbstmedia_id30 Tage gültigPOST /messages/mediaso oft senden wie Sie wollenZugestelltWebhooks melden das Ergebnis
Die ID ist bis zum Ablauf wiederverwendbar; nur der Sendeschritt wiederholt sich.
POST /api/v1/external/messages/media

{
	"to": "+919876543210",
	"type": "image",
	"media_id": "1234567890",
	"caption": "This month’s catalogue"
}

Wann ein Versand abgelehnt wird

  • Außerhalb des 24-Stunden-Fensters. Freie Medien brauchen eine offene Konversation. Senden Sie stattdessen eine freigegebene Vorlage — siehe den Leitfaden zum gemeinsamen Posteingang.
  • Dem Schlüssel fehlt send_media. Prüfen Sie die Berechtigungs-Chips im Overview-Tab.
  • Bildunterschrift bei Audio. WhatsApp zeigt keine an, daher wird sie abgelehnt statt still verworfen.
  • Dateiname bei etwas anderem als einem Dokument. Nur Dokumente zeigen einen Namen.
  • Weder media_id noch link. Genau eines ist erforderlich.

Hinweis: Sie können all das ohne Code ausprobieren. Öffnen Sie den Schlüssel, drücken Sie Test API und wählen Sie POST /messages/media aus der Endpunktliste — der Body ist vorbelegt, und „Get code“ schreibt denselben Request in acht Sprachen.

Reaktionen

Eine Reaktion ist das Emoji, das jemand auf eine einzelne Nachricht tippt — 👍 auf eine Bestellbestätigung, ❤️ auf ein Foto. Sie ist keine eigene Nachricht: sie verweist auf eine. Ihre Software kann Reaktionen mitlesen, sobald sie passieren, und selbst welche senden.

Ein Ereignis, drei Ursprünge

Eine Reaktion kann von Ihrem Kunden kommen, davon, dass der Inhaber sie auf dem Telefon der Business-App antippt, oder von Ihrer eigenen Software über die API. Alle drei kommen über dasselbe Ereignis message.reaction an, sodass ein einziger Handler jeden Fall abdeckt — direction und source sagen Ihnen, welchen Sie vor sich haben.

Die drei Ursprünge einer Reaktion und die Felder, die jeden davon kennzeichnenIhr Kundehat auf Sie reagiertdirection: inboundkein source-Feldcontact nennt die PersonDas Business-App-Telefonder Inhaber tipptedirection: outboundsource: mobileIhre SoftwareSie riefen die API aufdirection: outboundsource: apireference kommt zurückNur eingehende Reaktionen führen Kontaktdaten — eine ausgehende ist das Unternehmen, das Sie ohnehin kennen.
Ein Ereignis, drei Ursprünge. Lesen Sie erst direction, dann source.

Wie ein Reaktions-Webhook aussieht

Hier fügt ein Kunde 👍 zu einer Nachricht hinzu, die Sie ihm gesendet haben.

{
	"version": 1,
	"event": "message.reaction",
	"timestamp": "2026-08-01T09:14:22.031Z",
	"data": {
		"message_id": "wamid.HBgMOTE5ODc2NTQzMjEwFQIAERgSQjkz…",
		"direction": "inbound",
		"from": "+919876543210",
		"to": "+911122334455",
		"reaction": {
			"message_id": "wamid.HBgMOTE5ODc2NTQzMjEwFQIAERgUQ0Uz…",
			"emoji": "👍",
			"action": "added"
		},
		"contact": {
			"name": "Priya Sharma",
			"wa_id": "919876543210"
		}
	}
}

In diesem Payload stehen zwei message_ids, und sie bedeuten nicht dasselbe. Das ist das eine Feld, das ein zweites Lesen verdient.

FeldWas es ist
data.message_idDie eigene ID der Reaktion — nicht die der Nachricht, auf die reagiert wurde.
data.reaction.message_idDie wamid der Nachricht, auf die reagiert wurde. Diese gleichen Sie mit Ihren eigenen Datensätzen ab.
data.reaction.emojiDas Emoji. Leerer String, wenn die Reaktion entfernt wurde.
data.reaction.actionadded oder removed. Wird aus dem Emoji abgeleitet, Sie können also direkt darauf verzweigen.
data.directioninbound — der Kunde hat reagiert. outbound — das Unternehmen.
data.sourceNur ausgehend: mobile (Telefon der Business-App) oder api (Ihre Software). Fehlt bei eingehenden.
data.from / data.toRichtungsabhängig, wie bei message.sent: eingehend ist Kunde → Unternehmen, ausgehend ist Unternehmen → Kunde.
data.referenceNur bei Reaktionen, die Ihre eigene Software gesendet hat, und nur wenn Sie eine mitgegeben haben.
data.contact, data.user_id, data.usernameNur eingehend — wer reagiert hat. Fehlt bei jeder ausgehenden Reaktion.

Hinweis: data.from ist normalerweise die Telefonnummer des Kunden, aber WhatsApp sendet nicht immer eine. Wenn nicht, erhalten Sie stattdessen dessen WhatsApp-Benutzer-ID — behandeln Sie from also als Kennung, nicht als etwas, das Sie immer anrufen können.

Eine Reaktion hinzufügen und entfernen

Das Entfernen einer Reaktion ist ein eigenes Ereignis, mit leerem emoji und action: "removed".

{
	"event": "message.reaction",
	"data": {
		"message_id": "wamid.HBgMOTE5ODc2NTQzMjEwFQIAERgSN0U3…",
		"direction": "inbound",
		"reaction": {
			"message_id": "wamid.HBgMOTE5ODc2NTQzMjEwFQIAERgUQ0Uz…",
			"emoji": "",
			"action": "removed"
		}
	}
}

Jedes Antippen ist eine eigene WhatsApp-Nachricht mit eigener ID. Mit 👍 reagieren, es auf ❤️ ändern und dann ganz entfernen ergibt drei Ereignisse, von denen keines die anderen in Ihrem Speicher ersetzt. Schlüsseln Sie auf data.reaction.message_id und behalten Sie das jeweils neueste — das ist die aktuelle Reaktion der Nachricht.

Eine Reaktion aus Ihrer Software senden

Derselbe Endpunkt fügt hinzu und entfernt. Was davon geschieht, hängt allein davon ab, ob Sie ein Emoji senden.

Wie derselbe Reaktions-Endpunkt eine Reaktion hinzufügt und entferntPOST /messages/reactionein Emojidas Emoji, das erscheinen solleines pro Person und Nachrichtfügt die Reaktion hinzuein leeres Emojiloescht Ihre vorherige ReaktionFeld senden, aber leerentfernt sieZum Entfernen einer Reaktion senden Sie emoji als leeren String. Das Feld wegzulassen wird abgelehnt.
Ein Endpunkt, zwei Ergebnisse. Das emoji-Feld entscheidet.
POST /api/v1/external/messages/reaction

{
	"to": "+919876543210",
	"message_id": "wamid.HBgMOTE5ODc2NTQzMjEwFQIAERgUQ0Uz…",
	"emoji": "👍",
	"reference": "invoice-2026-0817"
}

Die message_id ist hier WhatsApps ID — die whatsapp_message_id aus einer Sendeantwort oder die data.reaction.message_id aus einem Webhook. Es ist nie eine unserer UUIDs. Reaktionen nutzen die Berechtigung send_text, jeder Schlüssel, der dem Kunden schreiben darf, kann also reagieren.

Hinweis: Eine Reaktion erzeugt nie message.delivered oder message.read. WhatsApp sendet diese für eine Reaktion nicht — das einzig mögliche Folgeereignis ist message.failed, wenn die Reaktion abgelehnt wird. Ein Abruf über GET /messages/:uuid funktioniert wie bei jedem anderen Versand.

Wann eine Reaktion abgelehnt wird

Manche Ablehnungen passieren hier, bevor irgendetwas WhatsApp erreicht. Diese geben Ihrem API-Aufruf einen Fehler zurück und erzeugen überhaupt keinen Webhook — es gibt nichts zu melden, weil nichts gesendet wurde.

  • Dem Schlüssel fehlt send_text. 403. Reaktionen nutzen diese Berechtigung mit; es gibt keine eigene zu vergeben.
  • to ist nicht E.164. 422. Dasselbe +…-Format wie bei jedem anderen Endpunkt.
  • message_id fehlt oder ist leer. 422. Bis zu 255 Zeichen.
  • emoji fehlt. 422. Zum Entfernen einer Reaktion senden Sie "emoji": "" — senden Sie das Feld leer, lassen Sie es nicht weg. Bis zu 16 Zeichen.

Die übrigen passieren bei WhatsApp, nachdem wir den Aufruf angenommen haben. Sie erhalten zuerst ein 200 und einen message.reaction-Webhook, dann ein message.failed mit dem Fehler 131009, sobald WhatsApp die Reaktion ablehnt.

  • Die Nachricht ist älter als 30 Tage. WhatsApps Grenze für Reaktionen, nicht unsere — wir prüfen das Alter nicht.
  • Die Nachricht gehört nicht zu dieser Konversation. Eine wamid aus einem anderen Chat oder versehentlich eine unserer UUIDs.
  • Die Nachricht wurde gelöscht oder ist selbst eine Reaktion. Auf eine Reaktion kann man nicht reagieren.

Hinweis: Schlägt der Versand direkt fehl, statt später abgelehnt zu werden, erhalten Sie ein 500 und ein message.failed, dessen data.message_id unsere UUID ist, keine wamid — es gibt keine WhatsApp-ID zu melden, weil WhatsApp sie nie angenommen hat.

Hinweis: Wie bei jedem anderen Endpunkt können Sie das ohne Code ausprobieren. Öffnen Sie den Schlüssel, drücken Sie Test API und wählen Sie POST /messages/reaction — reagieren Sie auf eine Nachricht auf Ihrem eigenen Telefon und sehen Sie den Webhook eintreffen.