Was ist ein Webhook?
Ein HTTP-POST, der automatisch gesendet wird, wenn ein Event auftritt. Umkehrung des Pollings: Services pushen statt du fragst.
Was ist ein Webhook?
Ein Webhook ist ein HTTP-POST-Request, den ein Service automatisch an einen anderen Service sendet, wenn etwas passiert. Der empfangende Service registriert vorher eine URL beim sendenden Service; wenn das Trigger-Event auftritt, POSTet der Sender ein JSON- (oder Form-encoded-) Payload an diese URL. Der Empfänger gibt ein 200 OK zur Bestätigung zurück, und der Sender macht weiter. Kein Polling, kein Warten — Events werden geliefert, wenn sie passieren.
Webhooks sind das Plumbing moderner Internet-Integrationen. Wenn Stripe eine Karte belastet, POSTet es ein charge.succeeded-Event an deine registrierte Webhook-URL. Wenn GitHub einen PR merged, POSTet es ein pull_request.closed-Event. Wenn Shopify eine Bestellung versendet, bekommt deine App einen order.fulfilled-POST. Das Muster ist über tausende SaaS-Produkte hinweg identisch: Ich sage dir eine URL, du POSTest mir, wenn was passiert.
Webhooks vs. Polling: Warum Webhooks gewonnen haben
Vor Webhooks bedeutete Integration Polling: Dein Service fragt die API alle paar Sekunden "gibt's was Neues?". Polling hat drei Probleme:
- Latenz. Wenn du alle 60 s pollst, ist deine durchschnittliche Event-Detection-Verzögerung 30 s. Realtime-Features (Chat, Payments, Alerts) tolerieren das nicht.
- Verschwendete Last. 99% der Polls geben "nichts Neues" zurück. Du hämmerst die API für leere Antworten und zahlst Compute und Bandbreite für nichts.
- Rate Limits. Die meisten APIs deckeln Requests pro Minute. Aggressives Polling sprengt das Budget; konservatives Polling verschlechtert die Latenz.
Webhooks invertieren das Modell. Der Provider weiß, wann ein Event passiert (er hat es ausgelöst), also POSTet er sofort an dich — typischerweise innerhalb von Hunderten Millisekunden. Null Polling, null verschwendete Requests, null Rate-Limit-Verschwendung. Der Provider bekommt einfachere Integration-Logik; der Consumer bekommt Near-Realtime-Updates.
Wie eine Webhook-Auslieferung funktioniert (Schritt für Schritt)
Ein typischer Webhook-Lifecycle:
- Du registrierst eine URL beim Provider. Üblicherweise in einer Settings-UI: "Sende Webhooks an
https://api.myapp.com/webhooks/stripe". Der Provider speichert diese URL. - Ein Event passiert auf der Provider-Seite. Ein Nutzer zahlt, ein Build wird fertig, eine Zeile wird aktualisiert.
- Der Provider baut ein Payload. Üblicherweise JSON:
{"event": "charge.succeeded", "data": {"id": "ch_123", "amount": 1500}}. - Der Provider POSTet das Payload an deine URL. Header enthalten üblicherweise den Event-Typ, eine Delivery-ID für Idempotenz und einen Signature-Header zur Verifikation.
- Dein Endpoint empfängt den POST und verarbeitet ihn. Signatur verifizieren, JSON parsen, machen, was das Event erfordert (DB updaten, E-Mail senden, an andere Services fan-outen).
- Dein Endpoint gibt schnell 200 OK zurück. Die meisten Provider werten Non-2xx-Responses als Delivery-Failure und retryen mit Exponential Backoff. Wenn die Verarbeitung länger als ein paar Sekunden dauert, akzeptiere den Webhook (200) und queue die Arbeit für asynchrone Verarbeitung.
Webhook-Authentizität verifizieren (überspringe das nicht)
Jeder, der deine Webhook-URL kennt, kann an sie POSTen. Ohne Verifikation kann ein Angreifer Events fälschen — vortäuschen, dass Stripe dich bezahlt hat, vortäuschen, dass GitHub einen bösartigen PR merged hat, vortäuschen, dass eine Sendung angekommen ist. Drei häufige Verifikationsmuster:
- HMAC-Signatur. Der Provider signiert das Payload mit einem geteilten Secret per HMAC-SHA256, sendet die Signatur in einem Header (
Stripe-Signature,X-Hub-Signature-256, etc.). Dein Endpoint berechnet die HMAC neu und lehnt nicht-passende Requests ab. Die meisten modernen Provider (Stripe, GitHub, Shopify) nutzen das. - Bearer-Token im Header. Einfacher aber weniger robust: Provider sendet ein statisches Secret-Token in
Authorization: Bearer .... Wer einen gültigen Request abfängt, kann ihn replayen; weniger üblich in modernen Systemen. - IP-Allowlist. Akzeptiere POSTs nur aus dokumentierten Provider-IP-Bereichen. Nützlich als Defence-in-Depth, bricht aber, wenn Provider IPs rotieren.
HMAC-Signatur ist der richtige Default. Kombiniere mit einem kurzen Replay-Window (Requests mit Timestamps älter als ein paar Minuten ablehnen), um Replay-Angriffe zu verhindern.
Idempotenz: Doppelte Auslieferungen handhaben
Netzwerke fallen aus. Provider retryen. Dein Endpoint wird denselben Webhook zweimal empfangen — manchmal mehr. Naive Integrationen erstellen doppelte Datenbank-Zeilen, senden doppelte E-Mails, belasten Kunden zweimal. Idempotenz verhindert das.
Zwei häufige Ansätze:
- Idempotency-Key vom Provider. Die meisten Provider liefern eine Delivery-ID in Headern (
Stripe-Webhook-Id,X-GitHub-Delivery) — global einzigartig pro Event. ID nach Verarbeitung speichern und Duplikate ablehnen. Einfach, zuverlässig. - Application-Level-Dedup. Berechne einen Hash aus Event-Typ + Schlüsselfeldern (z.B. Order-ID + Status) und behandle wiederholte Hashes innerhalb einer TTL als Duplikate. Nützlich, wenn die Delivery-ID des Providers nicht zuverlässig ist.
Webhook-Reliability-Patterns
Schnell bestätigen, async verarbeiten
Der Webhook-Empfänger sollte in unter 1-2 Sekunden 200 zurückgeben, auch wenn die eigentliche Arbeit länger dauert. Schiebe das Payload auf eine Queue (SQS, Redis-Stream, Postgres LISTEN/NOTIFY) und verarbeite von einem Worker aus. Langsame synchrone Verarbeitung verursacht Provider-Timeouts, Retries und doppelte Auslieferungen.
Outbox-/Inbox-Tabelle implementieren
Persistiere eingehende Webhooks in eine Inbox-Tabelle BEVOR du irgendeine Verarbeitung machst. Wenn dein Worker mitten in der Verarbeitung crashed, kannst du aus der Inbox replayen. Die Delivery-ID des Providers wird zum Inbox-Primärschlüssel für Idempotenz.
Delivery-Erfolg monitoren
Die meisten Provider exponieren ein Delivery-Log (Stripe → Webhooks → recent deliveries). Prüfe es periodisch. Ein Spike in 5xx- oder 4xx-Responses auf deinem Endpoint bedeutet üblicherweise, dass deine Inbox kaputt ist, bevor du es sonst bemerken würdest.
Webhook-Tunnel in der Entwicklung nutzen
Tools wie ngrok, Smee und Cloudflare Tunnel exponieren dein localhost ans öffentliche Internet, damit Provider an deine Dev-Umgebung POSTen können. Essenziell für lokales Debugging — Webhooks können localhost:3000 ohne Tunnel nicht von Stripes Servern aus erreichen.
Häufige Webhook-Gotchas
- Out-of-Order-Auslieferung. Provider liefern Events üblicherweise in Reihenfolge, aber Netzwerk-Retries können die Reihenfolge umdrehen. Geh nicht davon aus, dass
order.createdvororder.fulfilledankommt — handle beide Möglichkeiten. - Payload-Größenlimits. Viele Provider deckeln Payloads bei 4-8 MB. Große Entities (z.B. ein 50.000-Zeilen-Export) werden als URL zum separaten Abrufen geliefert, nicht inline.
- HTTP/HTTPS-Strictness. Die meisten Provider verlangen HTTPS; manche lehnen Self-Signed-Certs ab. Nutze ein echtes Zertifikat (Let's Encrypt ist kostenlos).
- Body-Parsing vor Signaturverifikation. Viele HMAC-Schemata signieren den Raw Body. Wenn dein Framework JSON zuerst parst, hast du die Raw-Bytes vielleicht nicht mehr. Nutze Middleware, die den Raw Body für die Verifikation erhält, dann parst.
FAQ: Webhooks
Sind Webhooks dasselbe wie eine Callback-URL?
Ja — "Webhook", "HTTP-Callback" und "Reverse API" beschreiben alle dasselbe Muster. Verschiedene Begriffe kamen aus verschiedenen Communities (Web-Entwickler, API-Provider, REST-Anwälte), aber der technische Mechanismus ist identisch.
Was ist der Unterschied zwischen Webhooks und WebSockets?
Webhooks sind unidirektionale HTTP-POSTs, die gesendet werden, wenn Events auftreten. WebSockets sind persistente bidirektionale TCP-Verbindungen. Nutze Webhooks für gelegentliche Events zwischen Services; nutze WebSockets für hochfrequente bidirektionale Kommunikation (Chat, Live-Cursors, Realtime-Collaboration).
Kann mein Empfänger auf Serverless gehostet sein?
Ja — Webhooks passen großartig zu AWS Lambda, Cloudflare Workers oder Vercel Functions. Das kurze Bestätigungsmodell (gib schnell 200 zurück, verarbeite async) mappt gut auf Serverless. Sieze die Funktion einfach für schnelle Cold Starts; manche Provider timeouten aggressiv.
Wie teste ich Webhook-Handler lokal?
Nutze einen Tunnel: ngrok, Smee, Cloudflare Tunnel. Der Tunnel exponiert dein localhost über eine öffentliche HTTPS-URL, an die Provider POSTen können. Stripe, GitHub und die meisten modernen Provider bieten auch ein CLI, um Events ohne Tunnel direkt an localhost zu forwarden.
Was passiert, wenn mein Endpoint down ist, wenn ein Event passiert?
Die meisten Provider retryen mit Exponential Backoff (1 min, 5 min, 30 min, etc.) für 24-72 Stunden. Danach wird das Event verworfen — und deine Daten sind permanent inkonsistent. Monitore Delivery-Failures und habe einen idempotenten Replay-Mechanismus für Ausfälle länger als das Retry-Window.
Sollte ich Webhooks oder Polling für meinen Use Case nutzen?
Webhooks für: Realtime-Events, niederfrequente Trigger, Payment-Notifications, alles wo Latenz zählt. Polling für: Bulk-Daten-Sync, Situationen wo der Provider keine Webhooks anbietet, oder wenn du keinen öffentlichen HTTPS-Endpoint betreiben kannst. In der Praxis nutzen moderne Integrationen beides: Webhooks für sofortige Alerts, periodisches Polling als Sicherheitsnetz, um verpasste Auslieferungen zu fangen.
Wie LoadFocus Webhooks nutzt
LoadFocus exponiert Webhooks für Test-Completion- und Alert-Events: Wenn dein geplanter Lasttest fertig ist, POSTen wir die Results-URL an deinen registrierten Endpoint, damit deine CI-Pipeline reagieren kann (an Slack posten, einen Deploy gaten, ein Dashboard updaten). Wenn ein API-Monitor einen Alert auslöst, liefert dasselbe Payload-Muster den Incident an PagerDuty, Opsgenie oder deinen Custom-Service. Konfiguriere Webhooks in deinen Account-Settings; HMAC-Signaturen sind standardmäßig enthalten.
Verwandte LoadFocus-Tools
Setze dieses Konzept mit LoadFocus in die Praxis um — derselben Plattform, die alles antreibt, was du gerade gelesen hast.