Webhooks

Owlat unterstützt sowohl ausgehende Kunden-Webhooks als auch eingehende Provider-Webhooks.

Owlat unterstützt sowohl ausgehende Kunden-Webhooks als auch eingehende Provider-Webhooks.

Ausgehende Kunden-Webhooks

Konfiguration unter Einstellungen → Webhooks.

Unterstützte ausgehende Events:

  • email.sent
  • email.delivered
  • email.opened
  • email.clicked
  • email.bounced
  • email.complained
  • contact.created
  • topic.unsubscribed

Hinweise zur Zustellung

  • Der Endpunkt muss POST akzeptieren
  • Verwenden Sie öffentlich erreichbare HTTP/HTTPS-URLs
  • Hosts in privaten/lokalen Netzwerken werden abgelehnt
  • Fehlgeschlagene Zustellungen werden erfasst und können erneut versucht werden

Signaturprüfung

Webhook-Secrets verwenden das Format whsec_... und werden bei der Erstellung des Webhooks generiert.

Jede Zustellung enthält diese Header:

HeaderBeschreibung
X-SignatureHMAC-SHA256-Hex-Digest des JSON-Payload-Bodys
X-TimestampUnix-Zeitstempel (Sekunden) zum Zeitpunkt des Versands der Anfrage
X-Webhook-IdDie Webhook-ID
Content-Typeapplication/json
User-AgentOwlat-Webhooks/1.0

Aufbau des Payloads

{
  "event": "email.delivered",
  "timestamp": "2026-03-15T12:00:00.000Z",
  "data": { /* event-specific data */ }
}

Beispiel zur Prüfung (Node.js)

import crypto from 'crypto'

function verifyWebhookSignature(
  payload: string,
  signature: string,
  secret: string
): boolean {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex')
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  )
}

// In your webhook handler:
const payload = await request.text()
const signature = request.headers.get('X-Signature')!
const isValid = verifyWebhookSignature(payload, signature, webhookSecret)

Wiederholungsverhalten

Fehlgeschlagene Zustellungen werden bis zu 3-mal erneut versucht:

  1. Sofort
  2. Nach 1 Minute
  3. Nach 5 Minuten

Jede Anfrage hat ein Timeout von 30 Sekunden. Endpunkte, die auf IPs in privaten/lokalen Netzwerken auflösen, werden abgelehnt.

Eingehende Provider-Webhook-Routen

Das sind die Endpunkte, die Owlat selbst bereitstellt, um Zustellstatus und eingehende Mail von seinem Versandprovider entgegenzunehmen. Sie sind von den oben beschriebenen ausgehenden Webhooks zu unterscheiden, die Owlat an Ihre Endpunkte sendet.

Jeder rückmeldefähige Versandweg besitzt eine feste eingehende Route:

RouteProviderWann sie verwendet wird
POST /webhooks/mtaMitgelieferte Owlat-MTAStandard beim Self-Hosting
POST /webhooks/sesAmazon SES über SNSWenn SES-Feedback konfiguriert ist
POST /webhooks/resendResendWenn als Versandprovider konfiguriert
POST /webhooks/mandrillMailchimp TransactionalWenn Mandrill-Feedback konfiguriert ist
POST /webhooks/emailitEmailitWenn Emailit-Feedback konfiguriert ist

Route der mitgelieferten MTA

POST /webhooks/mta

Bei selbst gehosteten Deployments ist die mitgelieferte MTA der Standardversandweg, daher ist dies die primäre eingehende Route. Sie verarbeitet Zustellstatus, eingehende Mail und betriebliche Reputationsereignisse:

EventWirkung
bouncedErfasst den Bounce (hard/soft, von der MTA vorklassifiziert) und aktualisiert Blockliste + Kontaktaktivität
complainedErfasst die Spam-Beschwerde und aktualisiert Blockliste + Kontaktaktivität
sentMarkiert den Versand als abgesetzt
inbound.receivedNimmt eingehende Mail (z. B. Kampagnenantworten) in das Team-Postfach auf
org.circuit_breakerLöst den Versands-Circuit-Breaker bei hoher Bounce-Rate aus
ip.blocklisted / ip.delisted / ip.warming_complete / all_ips_blockedMacht Änderungen der IP-Reputation sichtbar

Anfragen werden mit HMAC-SHA256 über ${timestamp}.${body} signiert:

HeaderBeschreibung
X-MTA-SignatureHMAC-SHA256-Hex-Digest
X-MTA-TimestampUnix-Zeitstempel (Sekunden); wird abgelehnt, wenn er mehr als 5 Minuten von der Serverzeit abweicht

Das gemeinsame Secret stammt aus der Umgebungsvariablen MTA_WEBHOOK_SECRET. Ist sie nicht gesetzt, schlägt der Endpunkt sicherheitshalber mit 503 fehl.

Resend-Route

POST /webhooks/resend

Resend sendet eine größere Menge an Provider-Events, doch Owlat handelt nur bei zweien davon:

EventWirkung
email.bouncedErfasst den Bounce (anhand der Provider-Nachricht als hard/soft klassifiziert) und aktualisiert Blockliste + Kontaktaktivität
email.complainedErfasst die Spam-Beschwerde und aktualisiert Blockliste + Kontaktaktivität

Die übrigen Resend-Events — email.sent, email.delivered, email.delivery_delayed, email.opened, email.clicked — werden empfangen und mit 200 {"success": true, "ignored": true} quittiert, aber von Owlat nicht verarbeitet. Der Versandstatus wird zum Zeitpunkt des Absetzens festgehalten, und Öffnungs- sowie Klickdaten stammen aus Owlats eigenem Tracking-Pixel und den Link-Weiterleitungen, nicht aus den Zählern von Resend.

Keine Delivered-/Open-/Click-Effekte aus dem eingehenden Pfad

Bauen Sie keine Integrationen, die erwarten, dass die eingehende Resend-Route Auswertungen zu Zustellungen, Öffnungen oder Klicks speist — nur Bounce- und Beschwerde-Events haben eine Wirkung. Nutzen Sie die oben beschriebenen ausgehenden Webhooks, um die Events email.delivered, email.opened und email.clicked zu erhalten.

Resend-Anfragen werden mit dem Signaturverfahren von Svix geprüft:

HeaderBeschreibung
svix-idNachrichten-ID
svix-timestampUnix-Zeitstempel (Sekunden); wird abgelehnt, wenn er mehr als 5 Minuten von der Serverzeit abweicht
svix-signatureEine oder mehrere durch Leerzeichen getrennte HMAC-Signaturen der Form v1,<sig>

Die Signatur wird gegen die Umgebungsvariable RESEND_WEBHOOK_SECRET geprüft (das whsec_-Base64-Secret aus Ihrem Resend-Dashboard). Ist sie nicht gesetzt, schlägt der Endpunkt sicherheitshalber mit 503 fehl.

Emailit-Route

POST /webhooks/emailit

Die Emailit-Events accepted, attempted, delivered, bounced, complained, failed, rejected und suppressed durchlaufen dieselbe normalisierte Lifecycle-Pipeline wie die etablierten Provider. Unterdrückungsgründe werden auf Owlats geschlossenes, empfängersicheres Vokabular abgebildet; Loaded-/Clicked-Events werden ignoriert, weil das eigene Tracking maßgeblich bleibt.

Anfragen erfordern X-Emailit-Timestamp und X-Emailit-Signature. Owlat berechnet den kleingeschriebenen hexadezimalen HMAC-SHA256 von <timestamp>.<raw body> mit dem vollständigen EMAILIT_WEBHOOK_SECRET und lehnt Zeitstempel außerhalb von fünf Minuten ab. Ein nicht gesetztes Secret führt sicherheitshalber zu 503.

Payload-Vertrag

Die vollständigen Payload-Strukturen je Event für die ausgehenden Webhooks, die Owlat an Ihre Endpunkte sendet, finden Sie unter Webhook-Payloads.