# Webhook-Anfragen

> 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.

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](/de/docs/webhooks/request-signature/). |
| `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](/de/docs/webhooks/event-types/), 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](/de/docs/api-reference/emails/get/) 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](/de/docs/webhooks/retries-and-failures/).

## Siehe auch

  - [Anfragesignatur](/de/docs/webhooks/request-signature/)
  - [Event-Typen](/de/docs/webhooks/event-types/)

---
Quelle: https://emailit.com/de/docs/webhooks/webhook-requests/
