Zum Inhalt springen
Doku

Referenz

Das genaue Format von Webhook-Anfragen von Emailit, von Methode und Headern bis zum JSON-Array der Events, außerdem Reihenfolge, Duplikate und wie Sie antworten.

Aktualisiert am 1. Okt. 2026

Diese Seite beschreibt, was an Ihrem Endpunkt ankommt: die HTTP-Anfrage, ihre Header, den JSON-Body und was Emailit als Antwort erwartet. Nutzen Sie sie, wenn Sie einen Webhook-Handler schreiben oder debuggen.

Anfrage

Eigenschaft Wert
Methode POST
Body Ein JSON-Array mit 1 bis 100 Events, kompakt (ohne zusätzliche Leerzeichen)
Timeout 30 Sekunden
Redirects Werden nicht verfolgt. Eine 3xx-Antwort gilt als Fehlschlag.
Parallelität Eine Anfrage gleichzeitig pro Webhook. Batches werden nacheinander gesendet.
Latenz Emailit prüft alle paar Sekunden auf neue Events, daher kommen die meisten Events innerhalb von Sekunden an.
HTTP
POST /webhooks/emailit HTTP/1.1
Host: acme.com
Content-Type: application/json
User-Agent: Emailit-Webhooks/2.0
X-Emailit-Signature: 7242b580f77ec488f8ac21b57f092e3db61a431694f13074c7b4c85a4dd04be3
X-Emailit-Timestamp: 1790846045

Header

Header Beschreibung
Content-Type Immer application/json.
User-Agent Immer Emailit-Webhooks/2.0.
X-Emailit-Signature Hexadezimal kodierter HMAC-SHA256 von {timestamp}.{raw body}, mit dem vollständigen Secret des Webhooks (einschließlich whsec_) als Schlüssel. Siehe Anfragesignatur.
X-Emailit-Timestamp Unix-Zeit in Sekunden, zu der Emailit die Anfrage signiert hat. Jeder Versuch, auch jede Wiederholung, wird mit einem neuen Zeitstempel erneut signiert.

Body

Der Body ist immer ein JSON-Array, auch wenn er nur ein einzelnes Event enthält. Jedes Element hat diese Form:

Feld Typ Beschreibung
event_id string Die ID des Events, beginnend mit evt_. Dasselbe Event behält über Wiederholungen hinweg dieselbe ID. Test-Events beginnen mit evt_test_.
type string Der Event-Typ, etwa email.delivered.
object object Die Ressource, um die es im Event geht.
data object Enthält object noch einmal. data.object und das object der obersten Ebene sind identisch; lesen Sie, welches Sie bevorzugen.

Die Felder in object hängen vom Typ ab. E-Mail-Status-Events beschreiben die E-Mail; email.clicked und email.loaded beschreiben den Klick oder Ladevorgang und enthalten die E-Mail verschachtelt; Ressourcen-Events wie contact.created beschreiben die Ressource.

Beispiel-Batch

Diese Anfrage enthält zwei Events: eine Zustellung und einen späteren Klick auf einen Link in derselben E-Mail.

JSON
[
  {
    "event_id": "evt_2xGk7Nq1VbD5sR8tLmW3eYhC6aP",
    "type": "email.delivered",
    "object": {
      "id": "em_2xGk7Lr3XcB8pQ1wYzK4dTfG9hJ",
      "object": "email",
      "from": "billing@acme.com",
      "to": "ada@example.com",
      "subject": "Your receipt #1042",
      "status": "delivered",
      "meta": { "order_id": "1042" },
      "updated_at": "2026-10-01T09:14:03.512000+00:00",
      "created_at": "2026-10-01T09:14:01.207000+00:00"
    },
    "data": {
      "object": {
        "id": "em_2xGk7Lr3XcB8pQ1wYzK4dTfG9hJ",
        "object": "email",
        "from": "billing@acme.com",
        "to": "ada@example.com",
        "subject": "Your receipt #1042",
        "status": "delivered",
        "meta": { "order_id": "1042" },
        "updated_at": "2026-10-01T09:14:03.512000+00:00",
        "created_at": "2026-10-01T09:14:01.207000+00:00"
      }
    }
  },
  {
    "event_id": "evt_2xGkC8w2TnF4yR7bMqL1sVdJ6pE",
    "type": "email.clicked",
    "object": {
      "id": "click_2xGkC7v5PmD3xQ9aLnK2rUcH8oW",
      "object": "click",
      "email_id": "em_2xGk7Lr3XcB8pQ1wYzK4dTfG9hJ",
      "email": {
        "id": "em_2xGk7Lr3XcB8pQ1wYzK4dTfG9hJ",
        "rcpt_to": "ada@example.com",
        "mail_from": "billing@acme.com",
        "subject": "Your receipt #1042",
        "created_at": "2026-10-01T09:14:01.207000+00:00",
        "campaign": null,
        "meta": { "order_id": "1042" }
      },
      "link": {
        "id": "link_2xGk7Mb6QwE1zS8cNpT4vXfK3gB",
        "url": "https://acme.com/orders/1042"
      },
      "contact": { "id": "con_2xFh3Ka9LmP2nR6tVwB8cDqY5sZ", "email": "ada@example.com" },
      "ip_address": "203.0.113.24",
      "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 18_0 like Mac OS X)",
      "created_at": "2026-10-01T09:20:47.884000+00:00"
    },
    "data": {
      "object": {
        "id": "click_2xGkC7v5PmD3xQ9aLnK2rUcH8oW",
        "object": "click",
        "email_id": "em_2xGk7Lr3XcB8pQ1wYzK4dTfG9hJ",
        "email": {
          "id": "em_2xGk7Lr3XcB8pQ1wYzK4dTfG9hJ",
          "rcpt_to": "ada@example.com",
          "mail_from": "billing@acme.com",
          "subject": "Your receipt #1042",
          "created_at": "2026-10-01T09:14:01.207000+00:00",
          "campaign": null,
          "meta": { "order_id": "1042" }
        },
        "link": {
          "id": "link_2xGk7Mb6QwE1zS8cNpT4vXfK3gB",
          "url": "https://acme.com/orders/1042"
        },
        "contact": { "id": "con_2xFh3Ka9LmP2nR6tVwB8cDqY5sZ", "email": "ada@example.com" },
        "ip_address": "203.0.113.24",
        "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 18_0 like Mac OS X)",
        "created_at": "2026-10-01T09:20:47.884000+00:00"
      }
    }
  }
]

Zeitstempel sind im Format ISO 8601 in UTC angegeben. meta enthält die Metadaten, die Sie beim Senden angehängt haben, oder null. contact ist null, wenn der Empfänger keiner Ihrer Kontakte ist, und campaign ist bei E-Mails per API und SMTP null.

Reihenfolge

Innerhalb einer Anfrage sind die Events nach Alter geordnet, die ältesten zuerst. Über Anfragen hinweg gibt es keine Garantie für die Reihenfolge: Ein fehlgeschlagener Batch wird später wiederholt, während neuere Events womöglich schon angekommen sind, und eine manuelle Wiederholung kann alte Events nach neuen erneut senden.

Verlassen Sie sich nicht auf die Ankunftsreihenfolge. Verwenden Sie bei E-Mail-Events status und updated_at der E-Mail und behalten Sie den am weitesten fortgeschrittenen Zustand, den Sie gesehen haben (überschreiben Sie zum Beispiel clicked nicht mit einem verspäteten delivered). Rufen Sie im Zweifel den aktuellen Zustand mit E-Mail abrufen ab.

Duplikate

Dasselbe Event kann mehrfach ankommen:

  • Wenn Ihr Endpunkt nach der Verarbeitung eines Teils eines Batches in ein Timeout läuft oder einen Fehler zurückgibt, wird der ganze Batch wiederholt, einschließlich der Events, die Sie bereits verarbeitet haben.
  • Wenn Sie Retry failed verwenden oder eine einzelne Anfrage wiederholen.

Speichern Sie jede verarbeitete event_id mit einem Unique-Constraint und überspringen Sie Events, die Sie bereits gesehen haben.

Antworten

Ihre Antwort Ergebnis
Jede 2xx-Antwort innerhalb von 30 Sekunden Jedes Event im Batch wird als Delivered markiert. Der Antwort-Body wird ignoriert.
3xx, 4xx oder 5xx Der Batch ist fehlgeschlagen und wird wiederholt.
Keine Antwort innerhalb von 30 Sekunden, Verbindungsfehler, TLS-Fehler Der Batch ist fehlgeschlagen und wird wiederholt. Die Weboberfläche zeigt den Statuscode 0.

Bei fehlgeschlagenen Anfragen speichert Emailit die ersten 2.000 Zeichen Ihres Antwort-Bodys. Sie können ihn im Tab Requests des Webhooks lesen; eine kurze Fehlermeldung in der Antwort hilft daher beim Debuggen.

Empfehlungen:

  • Erst verifizieren, dann schnell bestätigen. Prüfen Sie die Signatur, legen Sie die Events in eine Warteschlange oder Tabelle und geben Sie 200 zurück. Erledigen Sie langsame Arbeit, etwa Aufrufe anderer APIs, in einem Hintergrundjob.
  • Auch für ignorierte Events 2xx zurückgeben. Andernfalls werden sie tagelang wiederholt.
  • Bei ungültiger Signatur 401 oder 403 zurückgeben. Die Anfrage wird wie jeder Fehlschlag wiederholt, was Ihnen Zeit gibt, ein falsch konfiguriertes Secret zu korrigieren.

Den Wiederholungsplan und was passiert, wenn ein Endpunkt dauerhaft fehlschlägt, finden Sie unter Wiederholungen und Fehlschläge.

War diese Seite hilfreich?

Danke für Ihr Feedback.

Danke, wir lesen jede Nachricht.