Ein Webhook ist ein HTTP-Callback, bei dem ein System einen HTTP-Request, meist einen POST mit JSON-Payload, an eine vom Abonnenten registrierte URL sendet, sobald ein bestimmtes Ereignis eintritt. Statt eine API regelmäßig abzufragen, wird der Empfänger nahezu in Echtzeit benachrichtigt. Zuverlässige Webhooks nutzen Signaturen, Retries mit Backoff und idempotente Verarbeitung.
Was ist ein Webhook?
Ein Webhook ist ein Weg, über den ein System ein anderes über ein Ereignis informiert, indem es einen HTTP-Endpunkt aufruft. Der Abonnent registriert eine URL, und der Anbieter sendet bei jedem Ereignis einen HTTP-Request an diese URL, typischerweise einen POST mit JSON-Body: eine Zahlung ist erfolgreich, ein Pull Request wurde gemergt, ein Alarm hat ausgelöst, ein Incident ist gelöst.
Webhooks werden oft als „umgekehrte API“ bezeichnet. Bei einer normalen API fragt der Client wiederholt nach, ob sich etwas geändert hat (Polling). Beim Webhook schiebt der Anbieter die Änderung in dem Moment, in dem sie passiert. Das spart Requests und verkürzt Verzögerungen, verlagert aber die Verantwortung für Verfügbarkeit, Sicherheit und Korrektheit auf den empfangenden Endpunkt.
So funktionieren Webhooks
- Der Abonnent registriert eine Endpunkt-URL, wählt Ereignistypen aus, und beide Seiten vereinbaren ein gemeinsames Secret.
- Tritt ein Ereignis ein, erstellt der Anbieter eine Payload mit Ereignis-ID, Typ, Zeitstempel und Daten.
- Der Anbieter signiert die Payload und sendet sie an den Endpunkt.
- Der Empfänger prüft die Signatur, speichert das Ereignis oder legt es in eine Queue und antwortet schnell mit einem
2xx-Status. - Bleibt die Antwort aus, läuft sie in einen Timeout oder ist sie kein
2xx, versucht der Anbieter es später erneut.
Ein typischer Request sieht beispielhaft so aus:
POST /hooks/alerts HTTP/1.1
Content-Type: application/json
Webhook-Id: evt_01J9X4K2
Webhook-Timestamp: 1760515200
Webhook-Signature: v1,K5oZfzN95Z9UVu1EsfQmfVNQhnkZ2pj9o9NDN/H/pI4=
{"id": "evt_01J9X4K2", "type": "alert.triggered", "data": {"service": "checkout", "severity": "critical"}}
Webhook-Signaturen mit HMAC prüfen
Da ein Webhook-Endpunkt eine öffentliche URL ist, muss der Empfänger prüfen, ob ein Request wirklich vom Anbieter stammt und unverändert ist. Üblich ist eine HMAC-Signatur: Der Anbieter berechnet mit dem gemeinsamen Secret einen HMAC, meist HMAC-SHA256, über den rohen Request-Body (oft zusammen mit Zeitstempel und Nachrichten-ID) und sendet ihn in einem Header. Der Empfänger berechnet den HMAC neu und vergleicht.
- Berechnen Sie die Signatur über die rohen Bytes des Bodys, vor jedem JSON-Parsing oder Umformatieren.
- Vergleichen Sie mit einer Funktion in konstanter Zeit, etwa
hmac.compare_digestin Python, um Timing-Angriffe zu vermeiden. - Nehmen Sie einen Zeitstempel in den signierten Inhalt auf und weisen Sie Requests außerhalb eines kurzen Toleranzfensters ab, zum Beispiel fünf Minuten. Das verhindert Replay-Angriffe.
- Unterstützen Sie Secret-Rotation, indem Sie während einer Übergangszeit Signaturen mit altem und neuem Secret akzeptieren.
Die Header-Namen unterscheiden sich je nach Anbieter: GitHub nutzt X-Hub-Signature-256, Stripe Stripe-Signature mit Zeitstempel, und die offene Spezifikation Standard Webhooks definiert webhook-id, webhook-timestamp und webhook-signature.
Retries und Idempotenz
Netzwerke fallen aus, Empfänger werden deployt, Endpunkte laufen in Timeouts. Deshalb wiederholen Anbieter fehlgeschlagene Zustellungen, meist mit exponentiellem Backoff und Jitter über Stunden oder Tage. Damit liefern die meisten Webhook-Systeme at-least-once: Dasselbe Ereignis kann mehrfach ankommen, und Ereignisse können in anderer Reihenfolge eintreffen.
- Verarbeitung idempotent machen. Speichern Sie die Ereignis-ID und überspringen Sie bereits verarbeitete Ereignisse. Ein Unique Constraint auf der ID in der Datenbank ist eine einfache, robuste Lösung.
- Schnell bestätigen, später verarbeiten. Prüfen, in eine Queue schreiben und innerhalb weniger Sekunden mit
2xxantworten. Lange Verarbeitung im Request führt zu Timeouts und doppelten Zustellungen. - Nicht auf die Reihenfolge verlassen. Nutzen Sie Zeitstempel oder Versionsnummern in der Payload oder holen Sie den aktuellen Zustand über die API des Anbieters.
- Statuscodes bewusst einsetzen.
2xx, sobald das Ereignis gespeichert ist,4xxfür Requests, die nie gelingen werden, etwa bei ungültiger Signatur, und5xxoder Timeout nur, wenn ein Retry sinnvoll ist. Manche Anbieter berücksichtigen auch Rate-Limiting-Antworten wie429.
Webhooks überwachen
Behandeln Sie Webhook-Empfänger wie Produktionsservices. Messen Sie die Request-Rate pro Ereignistyp, Signaturfehler, Antwortstatus und Latenz sowie die Tiefe der Verarbeitungs-Queue. Auf Senderseite überwachen Sie Zustellerfolg, Anzahl der Retries und Endpunkte, die nach wiederholten Fehlern deaktiviert wurden. Weil ein ausbleibender Webhook beim Empfänger keinen Fehler erzeugt, sollten Sie auch auf Stille achten: Kommen normalerweise alle paar Minuten Ereignisse, erkennt ein Alarm auf „keine Ereignisse empfangen“ defekte Abonnements, ähnlich wie beim Heartbeat Monitoring.
Typische Fehler
- Die Signaturprüfung weglassen oder erst nach dem Parsing prüfen, sodass die Bytes nicht mehr übereinstimmen.
- Aufwendige Arbeit synchron erledigen und in Timeouts laufen, was Retries und Duplikate auslöst.
- Jede Zustellung als einmalig behandeln und dadurch einen Kunden doppelt belasten oder einen Incident doppelt anlegen.
- Vollständige Payloads mit personenbezogenen Daten oder Secrets ins Log schreiben.
Wie Obseria hilft
Obseria tracet Webhook-Empfänger wie jeden anderen Endpunkt, sodass Sie Latenz, Fehler und Downstream-Aufrufe pro Ereignistyp sehen, und synthetische API-Checks prüfen, ob Endpunkte antworten. Workflows in Obseria Automation lassen sich per Webhook starten, Incidents können per Webhook an bestehende Paging-Tools weitergeleitet werden, und Nutzer abonnieren Updates von Statusseiten per Webhook.