Webhooks
Webhooks sind automatisierte Benachrichtigungen an definierte URLs, die in Echtzeit über Ereignisse informieren. Sie sind nützlich, da sie eine sofortige Reaktion auf spezifische Ereignisse ermöglichen, ohne dass eine kontinuierliche Abfrage erforderlich ist. Webhooks tragen dazu bei, die Systeme effizient und reaktionsschnell zu halten.
Ihre Webhooks werden sofort bei Eintritt eines Ereignisses aufgerufen. Können wir Ihre URL nicht erreichen oder antwortet sie mit einem Fehlerstatus, wiederholen wir den Versand nach einem festen Plan und prüfen über mehrere Tage hinweg automatisch, ob der Empfänger dauerhaft ausfällt. Details dazu finden Sie weiter unten unter Zustellung & Retries.
Zustellung & Retries
Wann wir einen Webhook wiederholen
Ein Webhook wird ausschließlich dann erneut zugestellt, wenn die Antwort Ihres Servers auf einen temporären Fehler hindeutet:
- Name
HTTP 429- Type
- Rate-Limit
- Description
Ihr Endpunkt signalisiert, dass er gerade zu viele Anfragen erhält.
- Name
HTTP 5xx- Type
- Server-Fehler
- Description
Konkret
500,502,503und504.
- Name
Verbindungsfehler- Type
- Netzwerk
- Description
Timeout, DNS-Auflösungsfehler, TLS-/Handshake-Fehler oder ein Verbindungsabbruch während des Requests.
Alle übrigen Antworten gelten als final und führen nicht zu einem erneuten Versand. Das gilt auch für 4xx-Codes wie 400, 401, 403 oder 404, da diese in der Regel auf einen Konfigurationsfehler bei der Empfängerseite hinweisen, der durch ein bloßes Wiederholen nicht behoben werden kann. Antworten im Bereich 2xx und 3xx werden als erfolgreich gewertet.
Request-Timeout
Jeder einzelne Zustellversuch hat ein Timeout von 5 Sekunden. Antwortet Ihr Server nicht in dieser Zeit, werten wir den Versuch als Fehler und planen einen Retry nach dem unten beschriebenen Plan ein.
Retry-Plan
Schlägt ein Versuch fehl, wird der nächste nach einem festen, ansteigenden Intervall geplant. Insgesamt unternehmen wir bis zu 14 Versuche, danach wird der Job verworfen. Die gesamte Zustellspanne beträgt damit ca. 3,5 Tage.
| Versuch | Wartezeit seit vorigem Versuch |
|---|---|
| 1 (initial) | sofort |
| 2 | 1 Minute |
| 3 | 5 Minuten |
| 4 | 30 Minuten |
| 5 | 60 Minuten |
| 6 | 2 Stunden |
| 7 bis 14 | je 10 Stunden |
Automatische Deaktivierung bei dauerhaften Fehlern
Zusätzlich zu den Einzel-Retries beobachten wir laufend die Tages-Fehlerquote pro Webhook. Ein Webhook wird als „problematisch" eingestuft, sobald an einem Tag
- die heutige Failure-Rate über 80 % liegt und
- mindestens 10 Fehler an dem Tag aufgetreten sind.
Ab diesem Zeitpunkt wird der Webhook über mehrere Tage hinweg beobachtet. Verbessert sich das Verhalten nicht, eskaliert das System schrittweise:
| Tag | Schwelle (rolling Failure-Rate) | Aktion |
|---|---|---|
| 1 | über 80 % | Warn-E-Mail Stufe 1 |
| 3 | über 85 % | Warn-E-Mail Stufe 2 |
| 5 | über 90 % | Warn-E-Mail Stufe 3 |
| 7 | über 95 % | Webhook wird automatisch deaktiviert, Eintrag im Audit-Log und Deaktivierungs-E-Mail |
Die Tageszähler werden ab dem Tag der Problemerkennung gemessen.
Nach einer Auto-Deaktivierung
Ein automatisch deaktivierter Webhook bleibt inaktiv, bis Sie ihn manuell im Dashboard wieder aktivieren. Nach der Reaktivierung startet die Statistik frisch.
Was zählt als „erfolgreich"?
Für die Failure-Rate-Auswertung gilt jede Antwort als „ok", die kein Retry-Auslöser ist. Konkret zählen 2xx, 3xx und auch 4xx-Antworten (mit Ausnahme von 429) als erfolgreich, weil sie aus Sicht des Versandsystems eine eindeutige, finale Rückmeldung darstellen.
Das bedeutet: ein dauerhaft mit 404 antwortender Endpunkt wird nicht automatisch deaktiviert, sondern muss von Ihnen manuell entfernt oder korrigiert werden.
Sicherheit
Quell IP prüfen
Alle Webhooks stammen von unserer IPv4 195.201.160.143 bzw. von der IPv6 2a01:4f8:13a:8e7::2. Sollte sich dies ändern, erfahren Sie alle weiteren Details dazu in unserem Changelog.
Signatur prüfen
Alle Webhooks an Ihren Server werden mit dem Signierschlüssel Ihres Accounts signiert. Anhand dieser Daten können Sie bei jedem empfangenen Webhook die Echtheit der Requests von uns validieren und eine Doppelung oder betrügerische Anfragen vermeiden. Überprüfen Sie dazu die Signatur wie auf der Seite Signierung beschrieben.
Folgende Header senden wir Ihnen in jedem Webhook:
- Name
X-Signature- Type
- string
- Description
Die von uns generierte Signatur
- Name
X-Timestamp- Type
- integer
- Description
Zeitstempel, zu dem die Signatur von uns erstellt wurde
- Name
X-Nonce- Type
- string
- Description
Zufällig generierter String mit 32 Zeichen
Beispiele als JSON Payload
SMS
Eingehende SMS (sms_mo)
{
"data": {
"id": "681590",
"sender": "SMS",
"system": "491771783130",
"text": "Hello World",
"time": "1605878104",
"message_type": "SMS"
},
"webhook_event": "sms_mo",
"webhook_timestamp": "2020-12-02 11:55:44"
}
SMS-Statusänderung (dlr)
{
"data": {
"msg_id": "77149843739",
"status": "TRANSMITTED",
"timestamp": "1760972114.3369"
},
"webhook_event": "dlr",
"webhook_timestamp": "1760973114.1684"
}
Performance Tracking (tracking)
{
"webhook_event": "tracking",
"webhook_timestamp": "2022-07-27T07:38:18+02:00",
"data": {
"sms_id": "77182424125",
"sms_label": null,
"tracking_url": "https://svn.me/7oz",
"final_url": "https://www.google.com",
"type": "click",
"total_clicks": 5,
"total_views": 3
}
}
Voice
Sprachnachricht-Statusänderung (voice_status)
{
"data": {
"callerId": "49176123456789",
"duration": "4",
"id": "284195",
"pricePerMinute": 0.075,
"recipient": "4943160049851",
"status": "completed",
"timestamp": 1629786769
},
"webhook_event": "voice_status",
"webhook_timestamp": "2021-08-24T08:32:50+02:00"
}
Eingehender Anruf (voice_call)
{
"webhook_event": "voice_call",
"webhook_timestamp": "2024-08-02T07:28:59+02:00",
"data": {
"id": 0,
"caller": "4943160049851",
"time": 1722576539,
"system": "4915170517246"
}
}
DTMF-Signal (voice_dtmf)
{
"webhook_event": "voice_dtmf",
"webhook_timestamp": "2024-08-02T07:28:59+02:00",
"data": {
"id": 0,
"callerId": "4943160049851",
"recipient": "4943160049851",
"status": "completed",
"system": "4915170517246",
"timestamp": 1722576539,
"duration": 2.76,
"pricePerMinute": 0.045,
"dtmf_digit": 9,
"total_price": 0.045
}
}
RCS
Nachricht wurde zugestellt
{
"webhook_event": "rcs",
"webhook_timestamp": "2024-03-08T10:01:07+01:00",
"data":
{
"msg_id": "77233699836",
"status": "DELIVERED",
"timestamp": "1709888466.254410",
"foreign_id": null,
"agent_id": "myfancyagent"
}
}
Nachricht wurde gelesen
{
"webhook_event": "rcs",
"webhook_timestamp": "2024-03-08T10:01:09+01:00",
"data":
{
"msg_id": "77233699836",
"status": "READ",
"timestamp": "1709888468.065783",
"foreign_id": null,
"agent_id": "myfancyagent"
}
}
Statusbericht einer gesendeten Nachricht
{
"webhook_event": "rcs",
"webhook_timestamp": "2024-03-08T10:00:18+01:00",
"data":
{
"sender": "4915153952979",
"status": "IS_TYPING",
"agent_id": "myfancyagent"
}
}
Es wurde eine Textnachricht gesendet
{
"webhook_event": "rcs",
"webhook_timestamp": "2024-03-08T09:47:12+01:00",
"data": {
"id": 1871353,
"sender": "4915153952979",
"time": 1709870553,
"message_type": "RCS",
"content_type": "text",
"text": "Hallo",
"agent_id": "myfancyagent"
}
}
Es wurde eine vorgeschlagene Antwort ausgewählt
{
"webhook_event": "rcs",
"webhook_timestamp": "2024-03-08T05:59:33+01:00",
"data": {
"id": 1870983,
"sender": "4915153952979",
"time": 1709870129,
"message_type": "RCS",
"content_type": "suggestion_response",
"suggestion_response": {
"postbackData": "suggestion_2",
"text": "Suggestion #2",
"type": "REPLY"
},
"agent_id": "myfancyagent"
}
}
Es wurde ein Bild gesendet
{
"webhook_event": "rcs",
"webhook_timestamp": "2024-03-08T08:58:20+01:00",
"data": {
"id": 1871195,
"sender": "4915153952979",
"time": 1709870556,
"message_type": "RCS",
"content_type": "user_file",
"user_file": {
"thumbnail": {
"mimeType": "image/jpeg",
"fileSizeBytes": 10166,
"fileUri": "https://static.seven.io/uploads/rbm/61513d3d/6176746a5177553d/4f36357145416a773452537737696e495a366a68454a42344639574937716e62704156765358664d486e42776730337334675a76522b6d4f574b6e32626632546842493d.jpeg"
},
"payload": {
"mimeType": "image/jpeg",
"fileSizeBytes": 611314,
"fileName": "IMG_20240308_050231_01.jpg",
"fileUri": "https://static.seven.io/uploads/rbm/61513d3d/6176746a5177553d/4f76746e45515768746866717653444e6166336a513852375249614d753637656f414a6f4758624d5358417269306e767331493645372b47446654325a66764b3168453d.jpeg"
}
},
"agent_id": "myfancyagent"
}
}
Es wurde eine Datei gesendet
{
"webhook_event": "rcs",
"webhook_timestamp": "2024-03-08T11:07:51+01:00",
"data": {
"id": 1871485,
"sender": "4915153952979",
"time": 1709892233,
"message_type": "RCS",
"content_type": "user_file",
"user_file": {
"payload": {
"mimeType": "application/pdf",
"fileSizeBytes": 18810,
"fileName": "sample (1).pdf",
"fileUri": "https://static.seven.io/uploads/rbm/61513d3d/617678715267303d/4f616c675256696b73524c6c75337a4b5a66336a51705570464e665a752f6d4e70464d37546e504b5458423730556a7337314e70514c3241436650304d616e4b3078493d.pdf"
}
},
"agent_id": "myfancyagent"
}
}
Es wurde ein Standort geteilt
{
"webhook_event": "rcs",
"webhook_timestamp": "2024-03-08T11:07:51+01:00",
"data": {
"id": 1871485,
"sender": "4915153952979",
"time": 1709892233,
"message_type": "RCS",
"content_type": "location",
"location": {
"latitude": 54.3216562,
"longitude": 10.1350767
},
"agent_id": "myfancyagent"
}
}