---
title: "Webhook-Endpunkte"
description: "Verwalten Sie mehrere Webhook-URLs mit Secrets und Ereignisfiltern pro Endpunkt."
---

Das endpointbasierte Webhook-System ermöglicht Ihnen, **mehrere**
Ziele pro Organisation zu registrieren, jeweils mit eigenem Secret,
eigenem Status und eigenem Abonnement für eine Teilmenge von Ereignistypen. Dies ist
das empfohlene Modell für alle neuen Integrationen.

Vergleichen Sie dies mit dem [Legacy-Webhooks mit einzelner URL](/api-reference/organizations#legacy-single-url-webhook),
der aus Gründen der Abwärtskompatibilität beibehalten wird, aber nur eine URL pro
Organisation unterstützt.

## Endpunkte

| Methode | Pfad | Erforderliche Rolle | Beschreibung |
|--------|------|---------------|-------------|
| `GET` | `/v1/developer/webhook-endpoints` | `admin+` | Endpunkte auflisten |
| `POST` | `/v1/developer/webhook-endpoints` | `admin+` | Einen Endpunkt erstellen |
| `PATCH` | `/v1/developer/webhook-endpoints/{endpoint_id}` | `admin+` | Bezeichnung / URL / Ereignisse / Status aktualisieren |
| `DELETE` | `/v1/developer/webhook-endpoints/{endpoint_id}` | `admin+` | Einen Endpunkt löschen |
| `POST` | `/v1/developer/webhook-endpoints/{endpoint_id}/rotate-secret` | `admin+` | Das Signaturgeheimnis ersetzen |
| `POST` | `/v1/developer/webhook-endpoints/{endpoint_id}/test` | `admin+` | Eine signierte Testzustellung senden |
| `GET` | `/v1/developer/webhook-deliveries` | `admin+` | Aktuelle Ergebnisse von Endpunkten und Legacy-Zustellungen prüfen |

## Endpunktobjekt

```json
{
  "id": "c4d5e6f7-...",
  "label": "Production — Call events",
  "url": "https://example.com/thunderphone/hook",
  "events": ["telephony.incoming", "telephony.complete"],
  "status": "active",
  "agent_id": 42,
  "agent_name": "Support Agent",
  "secret_hint": "a1b2…9f0e",
  "paused_at": null,
  "pause_last_error": "",
  "pause_undelivered_count": null,
  "created_at": "2026-04-20T18:24:10.113Z",
  "updated_at": "2026-04-20T18:24:10.113Z"
}
```

| Feld | Typ | Beschreibung |
|-------|------|-------------|
| `id` | UUID | Endpunkt-ID |
| `label` | string | Anzeigename, 1–120 Zeichen |
| `url` | string | HTTPS-URL; `http://localhost` für die Entwicklung zulässig |
| `events` | array of string | Abonnierte Ereignistypen (siehe [gültige Werte](#valid-event-types)). Ein leeres Array abonniert alle Ereignisse außer den expliziten ereignisbezogenen Ereignissen pro Gesprächszug (`telephony.turn` / `web.turn`) |
| `status` | string | `active`, `disabled` (manuell pausiert) oder `failing` (automatisch gesetzt, wenn eine Zustellung ihren 24-h-Wiederholungszeitplan ohne einen einzigen 2xx-Status ausschöpft) |
| `agent_id` | integer \| null | Sprachagent, auf den dieser Endpunkt beschränkt ist; `null` bedeutet organisationsweit |
| `agent_name` | string \| null | Name des eingeschränkten Sprachagenten oder `null` für einen organisationsweiten Endpunkt |
| `secret_hint` | string | Erste 4 und letzte 4 Zeichen des Signaturgeheimnisses mit Auslassungszeichen (`a1b2…9f0e`) — ausreichend, um das lokal gespeicherte Geheimnis zuzuordnen, ohne den vollständigen Wert offenzulegen |
| `paused_at` | timestamp \| null | Zeitpunkt, zu dem ThunderPhone den Endpunkt auf `failing` gesetzt hat. `null`, solange er `active` oder `disabled` ist |
| `pause_last_error` | string | Der letzte Zustellfehler, als der Endpunkt pausiert wurde, z. B. `HTTP 503: Service Unavailable`. Leer, sofern nicht `failing` |
| `pause_undelivered_count` | integer \| null | Seit der letzten erfolgreichen Zustellung des Endpunkts nicht zugestellte Ereignisse, gezählt zum Zeitpunkt der Pausierung |
| `created_at`, `updated_at` | timestamp | |

<Note>
  Das vollständige `secret` des Endpunkts wird bei der Erstellung **einmal** zurückgegeben
  und danach nie wieder. Speichern Sie es sicher — wenn Sie es verlieren,
  [rotieren Sie es](#rotate-the-signing-secret), um ein neues zu erhalten.
</Note>

### Gültige Ereignistypen

`events` wird anhand genau dieser Menge validiert — Werte außerhalb der Liste
geben `400` zurück. Im [Ereigniskatalog](/de/webhooks/events) finden Sie die
Payload-Struktur jedes Typs.

- `telephony.incoming`, `telephony.complete`, `telephony.tool`, `telephony.turn`
- `web.incoming`, `web.complete`, `web.tool`, `web.turn`
- `sms.sent`, `sms.failed`
- `sms.received` (reserviert; noch nicht ausgelöst)
- `call.graded`, `call.data_extracted`, `call.transfer_completed`
- `campaign.completed`
- `issue.reported`, `issue.escalated`
- `test-call.completed`
- `alert.triggered`

`issue.escalated` hat keinen Agentenkontext und wird nur an
organisationsweite Endpunkte zugestellt.

`voice.ready` und `voice.failed` können nicht explizit ausgewählt werden. Um sie zu
empfangen, erstellen Sie einen organisationsweiten Endpunkt mit `events: []`. Eine leere
Ereignisliste empfängt jedes unterstützte Ereignis außer `telephony.turn` und `web.turn`,
die explizit ausgewählt werden müssen.

### Endpunktstatus

- `active` — Zustellungen erfolgen normal.
- `disabled` — manuell über `PATCH` pausiert. Es werden keine Anfragen gesendet. Wir
  ändern den Status eines `disabled`-Endpunkts niemals; ihn wieder auf
  `active` zu setzen, liegt immer bei Ihnen.
- `failing` — wird automatisch gesetzt, wenn eine Zustellung an den Endpunkt
  ihren gesamten Wiederholungszeitplan (8 Versuche über 24 Stunden) ausschöpft,
  ohne jemals einen 2xx-Status zu erhalten. Ein fehlgeschlagener Endpunkt erhält keinen weiteren Datenverkehr.
  In diesem Fall senden wir den Eigentümern und Administratoren Ihrer Organisation eine E-Mail, und
  das Dashboard zeigt den pausierten Endpunkt mit einer Schaltfläche „Reaktivieren“ an.
  Sobald der Endpunkt behoben ist, setzen Sie seinen Status per `PATCH` wieder auf `active`;
  Zustellungen, deren Wiederholungszeitplan noch nicht abgelaufen ist, werden dort fortgesetzt,
  wo sie aufgehört haben.

---

## Endpunkte auflisten

<CodeGroup>
```bash cURL
curl https://api.thunderphone.com/v1/developer/webhook-endpoints \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY"
```
</CodeGroup>

Gibt ein Array von [Endpunktobjekten](#endpoint-object) zurück.
Übergeben Sie `?agent_id=42`, um nur Endpunkte zurückzugeben, die auf diesen Agenten beschränkt sind.

### Agentenbezogene Endpunkte

Organisationsweite Endpunkte empfangen jedes passende Ereignis. Ein Endpunkt mit
`agent_id` empfängt nur passende Ereignisse für Anrufe, die von diesem Agenten bearbeitet werden;
Ereignisse ohne Agentenkontext, etwa `alert.triggered`, erreichen ihn nie. Sie
können diese Endpunkte auch im **Webhooks**-Bereich des
Agent-Builder erstellen und verwalten.

---

## Einen Endpunkt erstellen

<CodeGroup>
```bash cURL
curl -X POST https://api.thunderphone.com/v1/developer/webhook-endpoints \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "label":  "Production — Call events",
    "url":    "https://example.com/thunderphone/hook",
    "events": ["telephony.incoming", "telephony.complete"]
  }'
```

```python Python
result = requests.post(
    "https://api.thunderphone.com/v1/developer/webhook-endpoints",
    headers={"Authorization": "Bearer sk_live_YOUR_API_KEY"},
    json={
        "label":  "Production — Call events",
        "url":    "https://example.com/thunderphone/hook",
        "events": ["telephony.incoming", "telephony.complete"],
    },
).json()
secret = result["secret"]
endpoint_id = result["id"]
```
</CodeGroup>

### Anfragefelder

| Feld | Typ | Erforderlich | Beschreibung |
|-------|------|----------|-------------|
| `label` | string | ja | 1–120 Zeichen |
| `url` | string | ja | HTTPS-URL (`http` nur für `localhost` / `127.0.0.1` zulässig) |
| `events` | array | nein | Leer/nicht angegeben abonniert alle Ereignisse außer `telephony.turn` / `web.turn`, die ein explizites Abonnement erfordern. Muss die unter [Gültige Ereignistypen](#valid-event-types) aufgeführten Werte verwenden; Duplikate werden entfernt |
| `agent_id` | integer \| null | nein | Beschränkt die Zustellung auf einen Agenten in dieser Organisation; weglassen oder `null` für einen organisationsweiten Endpunkt verwenden |

Gibt `201 Created` mit dem [Endpunktobjekt](#endpoint-object) sowie
einem zusätzlichen `secret`-Feld der obersten Ebene zurück, das den rohen
Signaturschlüssel enthält — eine 48 Zeichen lange Hexadezimalzeichenfolge:

```json
{
  "id": "c4d5e6f7-…",
  "label": "Production — Call events",
  "url": "https://example.com/thunderphone/hook",
  "events": ["telephony.incoming", "telephony.complete"],
  "status": "active",
  "secret_hint": "a1b2…9f0e",
  "created_at": "2026-04-20T18:24:10.113Z",
  "updated_at": "2026-04-20T18:24:10.113Z",
  "secret": "a1b2c37e08d94f5b16a2c8d90e7f3a4b5c6d7e8f90a19f0e"
}
```

<Warning>
  `secret` wird **nur bei der Erstellung** zurückgegeben. Nachfolgende `GET`-Antworten
  enthalten nur `secret_hint`. Kopieren Sie den vollständigen Wert in Ihren Secret-Manager,
  bevor Sie die Antwort verwerfen.
</Warning>

---

## Einen Endpunkt aktualisieren

<CodeGroup>
```bash cURL
curl -X PATCH https://api.thunderphone.com/v1/developer/webhook-endpoints/c4d5e6f7-... \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "label":  "Production — Call + Grade events",
    "events": ["telephony.incoming", "telephony.complete", "call.graded"]
  }'
```
</CodeGroup>

| Feld | Typ | Beschreibung |
|-------|------|-------------|
| `label` | string | |
| `url` | string | |
| `events` | array | |
| `status` | string | `active` oder `disabled`. Setzen Sie `active`, um einen Endpunkt wieder zu aktivieren, den der Server als `failing` markiert hat |
| `agent_id` | integer \| null | Setzen Sie eine Agenten-ID, um den Endpunkt zu beschränken, oder `null`, um ihn organisationsweit zu machen |

Gibt `200 OK` mit dem aktualisierten [Endpunktobjekt](#endpoint-object) zurück.

---

## Signatur-Secret rotieren

Ersetzen Sie das Signatur-Secret eines Endpunkts, beispielsweise wenn es verloren ging
oder möglicherweise offengelegt wurde. Für einen agentenspezifischen Endpunkt können Sie auch das
Dashboard verwenden: Öffnen Sie den Bereich **Webhooks** des Agenten und wählen Sie am
Endpunkt **Secret neu generieren**. Organisationsweite Endpunkte werden über die API
rotiert.

<CodeGroup>
```bash cURL
curl -X POST https://api.thunderphone.com/v1/developer/webhook-endpoints/c4d5e6f7-.../rotate-secret \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
```
</CodeGroup>

| Feld | Typ | Erforderlich | Beschreibung |
|-------|------|-------------|-------------|
| `include_copies` | boolean | nein | Standardwert `true`. Gibt das neue Secret auch an die anderen Endpunkte Ihrer Organisation weiter, die dieselbe URL und dasselbe aktuelle Secret haben, beispielsweise Kopien dieses Endpunkts bei anderen Agenten, sodass ein Empfänger weiterhin mit einem Secret verifiziert |

Gibt `200 OK` zurück:

```json
{
  "endpoint": { "id": "c4d5e6f7-...", "secret_hint": "7f3a…c21d", "...": "..." },
  "secret": "7f3a90b2c4d5e6f708192a3b4c5d6e7f8091a2b3c4d5c21d",
  "rotated_endpoint_ids": ["c4d5e6f7-..."]
}
```

| Feld | Typ | Beschreibung |
|-------|------|-------------|
| `endpoint` | object | Das [Endpunktobjekt](#endpoint-object) mit seinem neuen `secret_hint` |
| `secret` | string | Das neue Signatur-Secret. Wird nur in dieser Antwort zurückgegeben |
| `rotated_endpoint_ids` | Array von UUIDs | Jeder Endpunkt, der jetzt das neue Secret verwendet |

<Warning>
  Das alte Secret wird sofort nicht mehr verwendet: Die nächste Zustellung,
  einschließlich Wiederholungsversuchen, wird mit dem neuen Secret signiert. Solange Ihr Empfänger
  das neue Secret nicht hat, schlagen Zustellungen bei seiner Signaturprüfung fehl; antwortet er darauf
  mit einem Nicht-2xx-Status, werden sie nach dem normalen 24-Stunden-
  Zeitplan erneut versucht. Aktualisieren Sie den Empfänger daher zeitnah. Wenn Ihr Empfänger
  schrittweise ausgerollt wird, lassen Sie ihn während des Rollouts beide Secrets akzeptieren — die SDK-
  Verifizierungshilfen akzeptieren eine Liste von Secrets (siehe
  [Webhook-Signaturen verifizieren](/de/guides/verify-webhook-signatures)).
</Warning>

---

## Testzustellung senden

Senden Sie ein synthetisches `webhook.test`-Ereignis über die normale
Zustellungspipeline an einen Endpunkt, einschließlich kanonischer JSON-Serialisierung,
beider Signatur-Header, Zustellungsprotokollierung und Wiederholungsverwaltung.
Der Test richtet sich unabhängig von seinem `events`-Filter an den ausgewählten Endpunkt.

<CodeGroup>
```bash cURL
curl -X POST https://api.thunderphone.com/v1/developer/webhook-endpoints/c4d5e6f7-.../test \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY"
```
</CodeGroup>

Der Endpunkt empfängt einen Umschlag wie diesen:

```json
{
  "data": {
    "message": "ThunderPhone webhook test",
    "sent_at": "2026-07-17T20:12:34.567890+00:00"
  },
  "event_id": "2ad6507c-7d19-4498-9b2d-7e8f944ab5a1",
  "type": "webhook.test"
}
```

Die API gibt nach dem ersten Versuch `200 OK` zurück, auch wenn das Ziel
einen Fehler zurückgibt. Prüfen Sie `success`, `status`, `response_code` und `error`
auf das Zustellungsergebnis:

```json
{
  "success": true,
  "event_id": "2ad6507c-7d19-4498-9b2d-7e8f944ab5a1",
  "event_type": "webhook.test",
  "status": "delivered",
  "response_code": 204,
  "error": ""
}
```

`webhook.test` ist synthetisch und kann nicht zum `events`-Abonnement eines Endpunkts
hinzugefügt werden. Wenn der erste Versuch fehlschlägt, wiederholt ThunderPhone ihn etwa
eine Minute später einmal und beendet ihn dann; die Zustellung zeigt anschließend `status: "failed"`
unter [Zustellungen debuggen](#debug-deliveries). Eine Testzustellung markiert
den Endpunkt niemals als `failing`.

Um einen Trigger mit einer echten Ereignisstruktur zu konfigurieren, übergeben Sie optional
`event_type`. Die Zustellung bleibt synthetisch und enthält `"sample": true`;
anrufbezogene Beispiele verwenden `call_id: 0` und `agent_id: 0`.

```bash
curl -X POST https://api.thunderphone.com/v1/developer/webhook-endpoints/c4d5e6f7-.../test \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event_type":"call.graded"}'
```

`event_type` akzeptiert jeden Wert aus [Gültige Ereignistypen](#valid-event-types).
Wenn Sie ihn weglassen, bleibt das allgemeine `webhook.test`-Verhalten erhalten.

---

## Endpunkt löschen

<CodeGroup>
```bash cURL
curl -X DELETE https://api.thunderphone.com/v1/developer/webhook-endpoints/c4d5e6f7-... \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY"
```
</CodeGroup>

Gibt `204 No Content` zurück. Die Zustellung an die URL wird sofort beendet;
laufende Wiederholungen werden abgebrochen.

---

## Zustellungen debuggen

Bevor Sie darauf schließen, dass ein Webhook nicht gesendet wurde, prüfen Sie
[`GET /v1/developer/webhook-deliveries`](/api-reference/webhook-deliveries).
Dort werden aktuelle Versuche aus beiden Webhook-Systemen angezeigt, einschließlich Anruf-ID,
URL-Ursprung, HTTP-Status, Anzahl der Versuche, zugelassener Fehlerkategorie und nächstem
Wiederholungszeitpunkt. Ereignis-Payload, Transkript, gespeicherter Fehlertext,
Response-Body oder URL-Pfad werden niemals zurückgegeben.

Sie können denselben aktuellen Verlauf auch unter **Agenten → Agenten auswählen → Webhooks →
Letzte Zustellungen** sehen. Zeilen zeigen die Endpunktbezeichnung und den URL-Ursprung, die beim neuesten
Versuch verwendet wurden. Dies ist ein Betriebsstatus und kein unveränderliches Auditprotokoll: Das Löschen eines Endpunkts
löscht auch dessen Zustellungszeilen.

Bei einem n8n-`404` bestätigen Sie zunächst, dass der Workflow aktiv ist, `POST` akzeptiert und
die Produktions-Webhook-URL statt der Test-URL verwendet. Ein `401` oder `403` weist auf
Authentifizierung oder Signaturvalidierung hin; Zeitüberschreitungen weisen auf Latenz
oder Verfügbarkeit des Ziels hin; TLS-Fehler weisen auf die Zertifikatskette,
den Hostnamen oder das Ablaufdatum hin.

---

## Verwandte Inhalte

<CardGroup cols={2}>
  <Card title="Ereigniskatalog" icon="list" href="/de/webhooks/events">
    Die vollständige Liste der `events`-Werte, die Sie abonnieren können.
  </Card>
  <Card title="Webhook-Übersicht" icon="bolt" href="/de/webhooks/overview">
    Signaturprüfung und Zustellungssemantik.
  </Card>
</CardGroup>
