Webhooks & Ereignisse
Konto-Webhooks senden, was in Ihrem ganzen Konto passiert, in Echtzeit an eine URL Ihrer Wahl: einen neuen Lead, einen gebuchten Termin, einen Deal, der die Phase wechselt. Die Integrationen für Zapier und n8n nutzen sie im Hintergrund, und Sie können sie auch auf Ihren eigenen Endpunkt richten.
Sie ergänzen den Projekt-Webhook auf der Antwortseite einer einzelnen E-Mail, der weiter wie bisher funktioniert. Ein Projekt-Webhook deckt die Interaktionen einer E-Mail ab. Ein Konto-Webhook deckt alle E-Mails ab, dazu die Ereignisse unten, und wird genauso signiert.
Einen Webhook hinzufügen
- Gehen Sie im Dashboard zu Entwickler und suchen Sie die Karte Webhooks.
- Geben Sie die Endpunkt-URL ein (eine öffentliche
https://-URL) und wählen Sie die gewünschten Ereignisse. - Klicken Sie auf Webhook hinzufügen und kopieren Sie das Signatur-Secret. Es wird nur dieses eine Mal angezeigt.
Jeder Webhook zeigt, wie er angelegt wurde (Dashboard, API, Zapier oder n8n), seinen Status und seine letzte Zustellung. Test senden schickt ein Beispiel des gewählten Ereignisses, mit "test": true in data. Löschen entfernt den Webhook. Ein Konto kann bis zu 50 haben.
Nur der Kontoinhaber kann Webhooks hinzufügen oder löschen, und unter Umständen wird er vorher um eine erneute Anmeldung gebeten.
Ereignisse
| Ereignis | Wird ausgelöst, wenn |
|---|---|
interaction.received | Ein Empfänger mit einer E-Mail interagiert: Umfragestimme, Bewertung, Quiz-Antwort, verfolgter Klick, Kauf und so weiter. Deduplizierte Wiederholungen lösen nichts aus. |
form.submitted | Ein Formular in einer E-Mail abgesendet wird (source: "email-form") oder ein Anmeldeformular (source: "signup-form"). |
contact.created | Ein Kontakt einer Liste hinzugefügt wird. |
contact.updated | Sich die Felder eines Kontakts ändern. Das Speichern identischer Daten löst nichts aus. |
lead.hot | Der Engagement-Score eines Kontakts Ihren Schwellenwert für heiße Leads nach oben überschreitet. |
lead.new | Ein neuer Lead über ein Anmeldeformular oder ein Formular in einer E-Mail eintrifft. |
booking.created | Ein Termin gebucht wird. |
booking.cancelled | Eine Buchung storniert wird, mit cancelledBy. Eine Verschiebung löst keines der beiden Buchungsereignisse aus. |
deal.created | Ein Deal angelegt wird, egal wo: Board, Automatikregel, Journey, Angebot oder API. |
deal.stage_changed | Ein Deal die Phase wechselt, gewonnen und verloren eingeschlossen. |
purchase.completed | Ein Empfänger über einen Checkout in der E-Mail bezahlt. |
journey.completed | Ein Kontakt das Ende einer Journey erreicht. Wer vorzeitig aussteigt, zählt nicht. |
Die Kontaktereignisse werden bei Importen, Anmeldeformularen, der API, Synchronisationen und KI-Connectoren ausgelöst. Ein einzelner Schreibvorgang mit mehr als 500 Kontakten (etwa ein großer CSV-Import) löst keine aus, damit ein Import nicht Tausende Workflows startet. Bearbeitungen im Kontaktraster, Journey-Schritte Feld aktualisieren und gespeicherte Antworten lösen sie ebenfalls nicht aus.
lead.hot und lead.new werden unabhängig von den Schaltern und Grenzen Ihrer Lead-Benachrichtigungen ausgelöst: Das Abonnement ist die Zustimmung.
Payload
Jede Zustellung ist ein JSON-POST mit demselben Umschlag:
{
"id": "evt_8c1f…",
"type": "deal.stage_changed",
"createdAt": 1790000000000,
"data": {
"deal": {
"id": "deal_abc123",
"title": "Annual plan",
"value": 1200,
"currency": "USD",
"pipelineId": "owner_default",
"stageId": "proposal-sent",
"stage": "Proposal sent",
"status": "open",
"source": "manual",
"listId": "list_abc123",
"rowId": "3f6c1b0e2d…",
"email": "[email protected]"
},
"fromStageId": "meeting-booked"
}
}
id ist bei jeder Zustellung desselben Ereignisses gleich und wird auch im Header X-MailInApp-Idempotency-Key mitgeschickt, sodass Sie eine bereits verarbeitete erneute Zustellung gefahrlos verwerfen können. createdAt ist in Epoch-Millisekunden.
Um das data jedes Ereignistyps zu sehen, rufen Sie GET /api/v1/events/sample auf oder verwenden Sie Test senden.
Die Signatur prüfen
Zustellungen tragen die Header X-MailInApp-Timestamp und X-MailInApp-Signature, berechnet genau wie bei einem Projekt-Webhook. Prüfen Sie sie mit Ihrem Signatur-Secret gegen den rohen Body und weisen Sie Zeitstempel zurück, die älter als ein paar Minuten sind. Die Dokumentation des Projekt-Webhooks enthält eine fertige Node.js-Funktion.
Wiederholungen
Ihr Endpunkt hat 5 Sekunden Zeit, mit einem 2xx zu antworten. Alles andere (Zeitüberschreitung, Fehlerstatus, Weiterleitung) ist ein Fehlschlag, und die Zustellung wird automatisch mit wachsenden Abständen über mehrere Stunden wiederholt, mit demselben Body und demselben Idempotenzschlüssel, an die aktuelle URL des Webhooks. Antworten Sie schnell und erledigen Sie langsame Arbeit danach.
- Antwortet Ihr Endpunkt mit
410 Gone, wird der Webhook deaktiviert. So melden sich REST-Hooks-Clients ab. - Das Widerrufen eines API-Schlüssels deaktiviert die damit angelegten Webhooks.
- Das Löschen eines Webhooks beendet seine ausstehenden Wiederholungen.
Über die API abonnieren
Zapier, n8n und Ihr eigener Code können Webhooks mit einem API-Schlüssel verwalten (Authorization: Bearer mia_live_…):
curl https://mailinapp.com/api/v1/webhooks \
-H "Authorization: Bearer mia_live_..." \
-H "Content-Type: application/json" \
-d '{"url": "https://hooks.example.com/mailinapp", "events": ["lead.hot", "booking.created"]}'
Die Antwort 201 enthält die id des Abonnements und sein secret, das jede Zustellung signiert. Bewahren Sie es auf: Es wird nicht noch einmal geliefert. GET /api/v1/webhooks listet Ihre Abonnements, und DELETE /api/v1/webhooks/{id} entfernt eines. Ein einziger unbekannter Ereignisname lässt die ganze Anfrage scheitern. Diese Routen erlauben 30 Anfragen pro Minute und Schlüssel.
Der vollständige Vertrag steht in der OpenAPI-Spezifikation.