---
title: "Ereigniskatalog"
description: "Alle Webhook-Ereignistypen, die ThunderPhone ausgibt."
---

Jeder Webhook-Body enthält ein Feld `type`, dessen Wert einem der Ereignistypen auf dieser Seite entspricht. Wenn Sie einen
[Endpunkt](/de/webhooks/endpoints) abonnieren, muss das Array `events` die
gewünschten Ereignistypen enthalten (oder leer sein, um alles zu abonnieren —
ausgenommen die Ereignisse pro Gesprächszug [`telephony.turn`](#telephony-turn) /
[`web.turn`](#web-turn), die nur an Endpunkte zugestellt werden, die sie
ausdrücklich nennen).

Diese Ereignisse werden in zwei Zustellungsarten übertragen:

* **Endpoint-Zustellungen** sind immer **nicht blockierende** Benachrichtigungen mit [Wiederholungsversuchen](/de/webhooks/overview): Antworten Sie mit einem beliebigen 2xx; der Umschlag enthält eine `event_id` zur Deduplizierung.
* **Blockierende** Austausche erfolgen nur über den [Legacy-Webhook mit einer einzelnen URL](/de/webhooks/overview): die Konfigurationsanfrage [`telephony.incoming` / `web.incoming`](/de/webhooks/call-incoming) (Nummern im Webhook-Modus: 13 s einschließlich eines Wiederholungsversuchs; Widget-Schlüssel im Webhook-Modus: 10 s) und die [Tool-Weiterleitung](/de/tools/overview) im Webhook-Modus. Ihre Antwort gestaltet den Live-Anruf.

Die folgenden Beispiel-Payloads zeigen den Endpunkt-Umschlag in seiner Übertragungsreihenfolge
(Schlüssel alphabetisch sortiert: `data`, `event_id`, `type`); Legacy-Zustellungen enthalten
dieselben `data` ohne `event_id`.

## Anrufereignisse

### `telephony.incoming`

Wird gesendet, wenn ein eingehender Anruf eine Ihrer
[Telefonnummern](/api-reference/phone-numbers) erreicht. Endpunktzustellungen sind
Fire-and-forget-Benachrichtigungen für **jeden** eingehenden Anruf, unabhängig
davon, ob die Nummer für einen Agenten oder einen Webhook konfiguriert ist. Nummern ohne
zugewiesenen Agenten erhalten zusätzlich die **blockierende** Konfigurationsanfrage
über den Legacy-Webhook — siehe
[`telephony.incoming` / `web.incoming`](/de/webhooks/call-incoming) für
das vollständige Anfrage-/Antwortschema.

```json
{
  "data": {
    "call_id": 987654321,
    "from_number": "+14155550199",
    "to_number": "+15551234567"
  },
  "event_id": "3f6b2ad0-1c9e-4a57-9f2b-8f6f0f9d2f11",
  "type": "telephony.incoming"
}
```

| Feld | Typ | Beschreibung |
|-------|------|-------------|
| `agent_id` | integer \| null | Agent, der den Anruf bearbeitet hat, sofern einer zugewiesen war |
| `agent_name` | string \| null | Agent, der den Anruf bearbeitet hat, sofern einer zugewiesen war |

### `telephony.complete`

Wird gesendet, wenn ein eingehender oder ausgehender Telefonanruf endet. Nicht blockierend.
Enthält das Transkript, die Aufzeichnungs-URL, sofern verfügbar, sowie eine Abrechnungsübersicht. Siehe
[`telephony.complete` / `web.complete`](/de/webhooks/call-complete) für
das Payload-Schema.

| Feld | Typ | Beschreibung |
|-------|------|-------------|
| `agent_id` | integer \| null | Agent, der den Anruf bearbeitet hat, sofern einer zugewiesen war |
| `agent_name` | string \| null | Agent, der den Anruf bearbeitet hat, sofern einer zugewiesen war |

### `telephony.tool`

Wird gesendet, nachdem ein Telefonanruf ein
[Funktions-Tool](/de/tools/overview) aufruft. Nicht blockierende Audit-Benachrichtigung —
das Tool wurde bereits ausgeführt, wenn dieses Ereignis zugestellt wird; es umfasst
Ihre eigenen Funktions-Tools sowie das integrierte Tool `send_sms` (nicht andere integrierte,
Wissensdatenbank-, App-Verbindungs- oder MCP-Tools). Für `send_sms`
werden sowohl `arguments.to` als auch `arguments.body` als `[REDACTED]` angezeigt.
Auch Abschluss-Transkripte schwärzen diese Werte; rufen Sie Inhalt und Empfänger über die
organisationsbezogene SMS-Ressource anhand der `message_id` der Antwort ab.

```json
{
  "data": {
    "arguments": { "date": "2026-04-21" },
    "call_id": 987654321,
    "from_number": "+14155550199",
    "response": {
      "response": { "available_slots": ["9:00 AM", "2:00 PM"] },
      "status": 200
    },
    "to_number": "+15551234567",
    "tool_name": "search_appointments"
  },
  "event_id": "1f0a7c3e-52d4-4a0e-8f4b-b1a6a1c0d9e2",
  "type": "telephony.tool"
}
```

`response` ist das Ausführungsergebnis: `{"status": <http status>,
"response": <your endpoint's JSON>}` bei Erfolg oder
`{"status": <status>, "error": "<message>"}` bei Fehlern.

| Feld | Typ | Beschreibung |
|-------|------|-------------|
| `agent_id` | integer \| null | Agent, der den Anruf bearbeitet hat, sofern einer zugewiesen war |
| `agent_name` | string \| null | Agent, der den Anruf bearbeitet hat, sofern einer zugewiesen war |

### `telephony.turn`

Wird während eines Telefonanrufs gesendet, der **läuft**, einmal für jeden
sprachhaltigen Turn, sobald er auftritt — die gesprochenen Antworten des
Agenten und die transkribierten Turns des Anrufers. Ermöglicht Ihnen, die Live-Unterhaltung
über einfache Webhooks zu verfolgen, anstatt
[`GET /v1/calls/{call_id}/transcript`](/api-reference/calls#get-transcript) abzufragen.
Nicht blockierend.

<Note>
  **Explizites Abonnement erforderlich.** Im Gegensatz zu allen anderen Ereignistypen
  werden Turn-Ereignisse niemals über ein leeres `events`-Array
  zugestellt (Alle abonnieren). Ein Endpunkt erhält sie nur, wenn seine `events`-
  Liste ausdrücklich `telephony.turn` / `web.turn` enthält.
</Note>

```json
{
  "data": {
    "call_id": 987654321,
    "entry_type": "completion",
    "from_number": "+14155550199",
    "position": 7,
    "role": "assistant",
    "start_ms": 15200,
    "text": "How many employees does your company have?",
    "to_number": "+15551234567"
  },
  "event_id": "8d3f5a2c-7b1e-4c9a-b6d0-2e4f6a8c0d1e",
  "type": "telephony.turn"
}
```

| Feld | Typ | Beschreibung |
|-------|------|-------------|
| `agent_id` | integer \| null | Agent, der den Anruf bearbeitet hat, sofern einer zugewiesen war |
| `agent_name` | string \| null | Agent, der den Anruf bearbeitet hat, sofern einer zugewiesen war |
| `position` | integer | Der Index des Turns im Anrufverlauf — eine stabile Kennung für die Sortierung |
| `role` | string | `assistant` (Sprache des Agenten) oder `user` (Sprache des Anrufers) |
| `text` | string | Der Transkripttext des Turns zum Zeitpunkt der Übermittlung |
| `entry_type` | string | Der zugrunde liegende Verlaufseintragstyp: `completion` (Agent) oder `user_turn` / `span` (Anrufer) |
| `start_ms`, `end_ms` | integer | Audio-Offsets in ms seit Anrufbeginn; nur vorhanden, wenn das Wiedergabe-Timing zum Zeitpunkt der Übermittlung bereits bekannt war |

<Note>
  Die Zustellung erfolgt mindestens einmal, und Turns können **in falscher Reihenfolge**
  eintreffen: Deduplizieren Sie anhand der `event_id` des Umschlags und sortieren Sie nach
  `position`. Anrufertranskripte können nach der Übermittlung noch verfeinert werden; das
  [`telephony.complete`](/de/webhooks/call-complete)-Transkript nach dem Anruf ist
  maßgeblich. Nur gesprochene Turns werden übermittelt — Tool-Aufrufe, Flüstern und
  andere interne Einträge erscheinen niemals in diesem Stream.
</Note>

### `web.incoming`

Das Webkanal-Äquivalent von `telephony.incoming`, gesendet, wenn eine
[Web-Widget](/de/widget/overview)-Sitzung oder ein Builder-Mikrofontestanruf
beginnt. Endpunktzustellungen erfolgen für jede Websitzung als Fire-and-forget.
Veröffentlichbare Schlüssel in `mode="webhook"` erhalten zusätzlich die
**blockierende** Konfigurationsanfrage über den Legacy-Webhook — diese
blockierende Anfrage hat eine andere Struktur (`origin_domain`,
`publishable_key_prefix`; keine Telefonnummern). Siehe
[`telephony.incoming` / `web.incoming`](/de/webhooks/call-incoming).

```json
{
  "data": {
    "call_id": 987654322,
    "from_number": "web",
    "origin_domain": "https://example.com",
    "publishable_key_prefix": "pk_live_a1b2",
    "to_number": "+15551234567"
  },
  "event_id": "9a2b4c6d-8e0f-4a1b-9c2d-3e4f5a6b7c8d",
  "type": "web.incoming"
}
```

`from_number` ist immer der Literalwert `"web"`. Bei Web-Widget-Sitzungen im Webhook-Modus
ist `to_number` leer (die Agentennummer der Sitzung wird nach der Konfiguration
zugewiesen); bei Builder-Mikrofontestanrufen sind `origin_domain` und
`publishable_key_prefix` leer.

| Feld | Typ | Beschreibung |
|-------|------|-------------|
| `agent_id` | integer \| null | Agent, der den Anruf bearbeitet hat, sofern einer zugewiesen war |
| `agent_name` | string \| null | Agent, der den Anruf bearbeitet hat, sofern einer zugewiesen war |

### `web.complete`

Das Webkanal-Äquivalent von `telephony.complete`, das Web-Widget-Anrufe
(`direction: "web"`) und Builder-Mikrofontestanrufe
(`direction: "test"`) abdeckt. Nicht blockierend. Gleiche Payload-Struktur wie
[`telephony.complete`](/de/webhooks/call-complete), zusätzlich mit `origin_domain`,
wobei `from_number` auf `"web"` gesetzt ist.

| Feld | Typ | Beschreibung |
|-------|------|-------------|
| `agent_id` | integer \| null | Agent, der den Anruf bearbeitet hat, sofern einer zugewiesen war |
| `agent_name` | string \| null | Agent, der den Anruf bearbeitet hat, sofern einer zugewiesen war |

<Note>
  Beim Legacy-Webhook mit einer einzelnen URL werden Builder-Mikrofontestanrufe
  historisch als `telephony.complete` gemeldet — nur Anrufe mit `direction:
  "web"` verwenden dort den Typ `web.complete`. Das Endpunktsystem
  ordnet sowohl Web- als auch Testanrufe `web.*` zu. Historische Payloads können
  die Legacy-Werte `widget` oder `mic` für `direction` enthalten.
</Note>

### `web.tool`

Das Webkanal-Äquivalent von `telephony.tool`. `data` enthält
`origin_domain` anstelle von `from_number` / `to_number`.

| Feld | Typ | Beschreibung |
|-------|------|-------------|
| `agent_id` | integer \| null | Agent, der den Anruf bearbeitet hat, sofern einer zugewiesen war |
| `agent_name` | string \| null | Agent, der den Anruf bearbeitet hat, sofern einer zugewiesen war |

### `web.turn`

Das Webkanal-Äquivalent von [`telephony.turn`](#telephony-turn), das
Web-Widget-Anrufe und Builder-Mikrofontestanrufe abdeckt. Gleiche Payload-
Struktur, mit `origin_domain` anstelle von `from_number` / `to_number`.
Wie `telephony.turn` erfordert es ein **explizites Abonnement** — es wird
niemals über ein leeres `events`-Array zugestellt.

| Feld | Typ | Beschreibung |
|-------|------|-------------|
| `agent_id` | integer \| null | Agent, der den Anruf bearbeitet hat, sofern einer zugewiesen war |
| `agent_name` | string \| null | Agent, der den Anruf bearbeitet hat, sofern einer zugewiesen war |

### `call.transfer_completed`

Wird einmal pro Anruf mit dem endgültigen Ergebnis einer
[Anrufweiterleitung](/de/guides/call-transfers) gesendet: einer kalten Weiterleitung oder der menschlichen
Verbindung, die bei einer warmen Weiterleitung verbleibt, nachdem der Agent ausscheidet.
Nicht blockierend und nur an Endpunkte zugestellt (nie an den Legacy-
Webhook mit einer einzelnen URL). Trifft nach `telephony.complete` des Anrufs ein:
wenn der Anbieter den Anruf übernimmt oder die Weiterleitung fehlschlägt oder, wenn
ThunderPhone den Anruf verbunden hat, sobald die Verbindung endet.

```json
{
  "data": {
    "agent_id": 12,
    "agent_name": "Front desk",
    "bridge_kind": "cold_fallback",
    "bridge_seconds": 255,
    "bridge_total_cents": 5,
    "call_id": 987654321,
    "destination": "+15555550102",
    "sip_status": 403,
    "transfer_outcome": "bridged"
  },
  "event_id": "5b0f6c1e-9d2a-5e7b-8c4d-1a2b3c4d5e6f",
  "type": "call.transfer_completed"
}
```

| Feld | Typ | Beschreibung |
|-------|------|-------------|
| `call_id` | integer | Der weitergeleitete Anruf |
| `agent_id` | integer \| null | Agent, der den Anruf bearbeitet hat, sofern einer zugewiesen war |
| `agent_name` | string \| null | Agent, der den Anruf bearbeitet hat, sofern einer zugewiesen war |
| `transfer_outcome` | string | `refer_accepted`: Der Anbieter hat den Anruf übernommen. `bridged`: ThunderPhone hat den Anrufer und das Ziel selbst verbunden gehalten, entweder weil der Anbieter eine kalte Weiterleitung abgelehnt hat oder weil der Agent bei einer warmen Weiterleitung ausgeschieden ist. `bridge_unanswered`: Der Anbieter hat eine kalte Weiterleitung abgelehnt und das Ziel hat den eigenen Anruf von ThunderPhone nicht beantwortet. `failed`: Die Weiterleitung wurde nicht durchgeführt und der Anruf endete |
| `destination` | string \| null | Die Nummer, an die der Anruf weitergeleitet wurde |
| `sip_status` | integer \| null | SIP-Status des Anbieters, als er die kalte Weiterleitung abgelehnt hat: `403` (zum Beispiel ein Twilio-Trunk ohne Anrufweiterleitung), `405` oder `501`. `null`, wenn der Anbieter sie nicht abgelehnt hat |
| `bridge_kind` | string \| null | Nur bei `bridged`: `cold_fallback` (eine abgelehnte kalte Weiterleitung, die ThunderPhone verbunden hat) oder `warm` (die zwei Personen einer warmen Weiterleitung, nachdem der Agent ausgeschieden ist) |
| `bridge_seconds` | integer \| null | Nur bei `bridged`: die von ThunderPhone abgerechnete Verbindungszeit in Sekunden |
| `bridge_total_cents` | integer \| null | Nur bei `bridged`: Kosten der Verbindung in US-Cent nach einem etwaigen kostenlosen Anrufguthaben, separat von `billing_total_cents` des Anrufs abgerechnet |

Dieselben Werte befinden sich im [Anrufobjekt](/api-reference/calls#call-object)
als `transfer_outcome`, `transfer_destination`, `transfer_sip_status`,
`transfer_bridge_kind`, `transfer_bridge_seconds` und
`transfer_bridge_total_cents`. `event_id` ist bei jeder Zustellung
für einen Anruf gleich, sodass eine wiederholte Meldung kein zweites Ereignis erzeugt.

---

## SMS-Ereignisse

SMS-Ereignisse beschreiben Nachrichten, die über das verbundene Twilio- oder
Telnyx-Konto der Organisation gesendet werden. Der Nachrichtentext wird ausgelassen und `to` wird geschwärzt.
Rufen Sie die organisationsbezogene Nachricht über
[`GET /v1/sms/{message_id}`](/api-reference/sms#retrieve-a-message) ab, wenn ihr
Inhalt oder Empfänger benötigt wird.

### `sms.sent`

Wird gesendet, wenn der Mobilfunkanbieter des Kunden eine ausgehende SMS-Anfrage akzeptiert. Dies ist keine
Zustellbestätigung des Endgeräts.

```json
{
  "data": {
    "accepted_at": "2026-09-19T15:42:10.113Z",
    "agent_id": 12,
    "call_id": 987654321,
    "created_at": "2026-09-19T15:42:09.901Z",
    "direction": "outbound",
    "error_code": null,
    "error_message": null,
    "from_number": "+15551234567",
    "id": "313a3117-827b-46e9-a01a-ac1493838724",
    "provider": "twilio",
    "provider_id": "SM0123456789abcdef0123456789abcdef",
    "segment_count": 1,
    "source": "agent_tool",
    "status": "accepted",
    "to": "[REDACTED]"
  },
  "event_id": "0ae347b4-1716-45bb-9a0e-b52373586e37",
  "type": "sms.sent"
}
```

### `sms.failed`

Wird nach einer dauerhaften Ablehnung durch den Mobilfunkanbieter, nach Ausschöpfung vorübergehender Wiederholungsversuche
oder bei einem endgültig unbekannten Ergebnis gesendet. `error_code` ist ein stabiler
ThunderPhone-Code, und `error_message` nennt die erforderliche Kundenaktion, sofern verfügbar. `status: "unknown"` bedeutet, dass der Mobilfunkanbieter die SMS möglicherweise akzeptiert hat;
gleichen Sie dies im Protokoll des Mobilfunkanbieters ab, da ThunderPhone sie nicht automatisch erneut sendet.

### `sms.received`

Für die Unterstützung eingehender SMS reserviert. In der aktuellen Version werden keine
`sms.received`-Ereignisse ausgegeben. Die Konfiguration eingehender Webhooks des Mobilfunkanbieters und die
Signaturprüfung werden separat bereitgestellt.

---

## Sprachereignisse

Die Erstellung benutzerdefinierter Stimmen erfolgt asynchron. Mit diesen nicht blockierenden Ereignissen können Sie
auf ein endgültiges Ergebnis reagieren, anstatt den
[Endpunkt für Klondetails](/api-reference/custom-voices#list-and-retrieve-clones) abzufragen.

`voice.ready` und `voice.failed` werden nur an einen organisationsweiten
Endpunkt mit `events: []` zugestellt. Sie können nicht als explizite Ereignisfilter ausgewählt werden.

### `voice.ready`

Wird gesendet, wenn die Verarbeitung einer benutzerdefinierten Stimme abgeschlossen ist und sie einem
Agenten zugewiesen werden kann.

```json
{
  "data": {
    "voice": {
      "created_at": "2026-07-30T14:12:08.317Z",
      "display_name": "Support voice",
      "failure_reason": "",
      "gender": "female",
      "id": "cv_2f6f90b0e9a34ee8b39be7d1",
      "language": "en",
      "name": "custom:cv_2f6f90b0e9a34ee8b39be7d1",
      "status": "ready",
      "updated_at": "2026-07-30T14:13:31.605Z"
    }
  },
  "event_id": "2d5f0a61-e9b5-4a3c-b684-29d7d9e4b214",
  "type": "voice.ready"
}
```

### `voice.failed`

Wird gesendet, wenn die Verarbeitung einer benutzerdefinierten Stimme dauerhaft fehlschlägt.

```json
{
  "data": {
    "reason": "audio sample could not be processed",
    "voice": {
      "created_at": "2026-07-30T14:12:08.317Z",
      "display_name": "Support voice",
      "failure_reason": "audio sample could not be processed",
      "gender": "female",
      "id": "cv_2f6f90b0e9a34ee8b39be7d1",
      "language": "en",
      "name": "custom:cv_2f6f90b0e9a34ee8b39be7d1",
      "status": "failed",
      "updated_at": "2026-07-30T14:13:31.605Z"
    }
  },
  "event_id": "3493e985-1a75-4f77-a10a-e74af440cd31",
  "type": "voice.failed"
}
```

| Feld | Typ | Beschreibung |
|-------|------|-------------|
| `voice.id` | string | Öffentliche ID der benutzerdefinierten Stimme |
| `voice.name` | string | Stimmenwert für Agenten im Format `custom:<public_id>` |
| `voice.display_name` | string | Für die Organisation sichtbarer Stimmenname |
| `voice.language` | string | Sprachcode der einzelnen Sprache des Klons |
| `voice.gender` | string | `male`, `female` oder eine leere Zeichenfolge |
| `voice.status` | string | `ready` für `voice.ready`; `failed` für `voice.failed` |
| `voice.failure_reason` | string | Bei Erfolg leer; Details zum Verarbeitungsfehler bei einem Fehler |
| `voice.created_at`, `voice.updated_at` | timestamp | ISO-8601-Zeitstempel |
| `reason` | string | Fehlerdetails; nur bei `voice.failed` vorhanden |

---

## Qualitätsereignisse

### `call.graded`

Wird gesendet, wenn eine [KI-Bewertung](/api-reference/calls#ai-call-grading)
für einen Anruf abgeschlossen ist. Nicht blockierend.

```json
{
  "data": {
    "call_id": 987654321,
    "grade": {
      "call_outcome": "success",
      "created_at": "2026-04-20T18:25:11.002Z",
      "detected_issues": [],
      "graded_at": "2026-04-20T18:25:11.002Z",
      "grader_model": "heuristic-v1",
      "id": 5512,
      "score": 92,
      "status": "completed",
      "summary": "Caller asked about their policy and got a full answer…"
    },
    "report": null
  },
  "event_id": "7c1d2e3f-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
  "type": "call.graded"
}
```

| Feld | Typ | Beschreibung |
|-------|------|-------------|
| `agent_id` | integer \| null | Agent, der den Anruf bearbeitet hat, sofern einer zugewiesen war |
| `agent_name` | string \| null | Agent, der den Anruf bearbeitet hat, sofern einer zugewiesen war |
| `grade.id` | integer | Bewertungs-ID |
| `grade.score` | integer \| null | 0–100 |
| `grade.call_outcome` | string | `success`, `failure`, `unknown` oder `no_conversation` |
| `grade.summary` | string | Zusammenfassung in einem Absatz |
| `grade.detected_issues` | array | Vom Bewerter erkannte Problemzeichenfolgen |
| `grade.status` | string | Immer `completed` — nur abgeschlossene Durchläufe senden ein Ereignis |
| `grade.grader_model` | string | Welcher Bewerter das Ergebnis erzeugt hat (z. B. `heuristic-v1`) |
| `grade.graded_at`, `grade.created_at` | timestamp | |
| `report` | object \| null | Der kundenorientierte [Anrufbericht](/api-reference/calls#call-report): Ergebnisbezeichnung, Markierung und Grund für erforderliche Aufmerksamkeit, Anrufer, einzeilige Zusammenfassung, Anrufererlebnis. Bei einer frühen heuristischen Bewertung ist er `null` oder ein `pending`-Bericht, dessen Felder Platzhalter sind; das Ereignis der vollständigen Bewertung enthält den abgeschlossenen Bericht |

<Note>
  Ein Anruf kann mehr als einmal bewertet werden — auf eine schnelle heuristische
  Bewertung folgt häufig eine vollständige Modellbewertung, sobald die Aufnahme
  verfügbar ist; auch manuelle Neubewertungen sind möglich. Jeder abgeschlossene
  Durchlauf sendet ein eigenes `call.graded`-Ereignis; behandeln Sie das neueste
  `graded_at` als maßgeblich.
</Note>

### `call.data_extracted`

Wird gesendet, wenn die Extraktion strukturierter Daten erfolgreich abgeschlossen
wurde, einschließlich eines späteren Wiederholungsversuchs nach `telephony.complete` /
`web.complete` oder einer manuellen erneuten Ausführung über
[`POST /v1/calls/{call_id}/extract`](/api-reference/calls#run-data-extraction).
Nicht blockierend.

In einem blockierenden Extraktionsmodus wartet das Abschlussereignis normalerweise
nicht länger als das Extraktionsbudget von 75 Sekunden. Wenn der
Extraktions-Worker-Prozess verloren geht, gibt der Produktionsabschluss-Drain
(alle fünf Minuten) einen Abschluss frei, dessen `blocking_deadline_at`
abgelaufen ist, bevor ein weiterer Extraktionsversuch gestartet wird. Ein späterer
Erfolg wird separat als dieses Ereignis zugestellt.

<Warning>
  Extrahierte Werte sind die Interpretation des Gesprächs durch ein Modell. Jeder
  Wert ungleich null enthält das zugrunde liegende Zitat, die Sprecherrolle und den
  Gesprächszugindex sowie ein Verifizierungskennzeichen auf Durchlaufebene.
  Überprüfen Sie das Ergebnis, bevor Sie Entscheidungen zu Geld, Identität oder
  Zugriff treffen.
</Warning>

```json
{
  "data": {
    "call_id": 987654321,
    "agent_id": 12,
    "agent_name": "Acme intake",
    "extracted_data": {
      "status": "completed",
      "fields": {
        "customer_name": "Alex Morgan",
        "appointment_date": "2026-04-23"
      },
      "evidence": {
        "customer_name": {
          "quote": "My name is Alex Morgan",
          "speaker_role": "caller",
          "turn_index": 4
        },
        "appointment_date": {
          "quote": "April 23 works for me",
          "speaker_role": "caller",
          "turn_index": 7
        }
      },
      "verification": "verified",
      "field_reasons": {},
      "schema_version": "92850758e231a3c95a..."
    },
    "extracted_at": "2026-04-20T18:25:11.002Z",
    "model": "<model id>",
    "summary": "Alex Morgan called to book a follow-up visit and confirmed Thursday, April 23."
  },
  "event_id": "4d79ef1d-c2b1-4ed6-85b8-8326bd2895ef",
  "type": "call.data_extracted"
}
```

| Feld | Typ | Beschreibung |
|-------|------|-------------|
| `agent_id` | integer \| null | Agent, der den Anruf bearbeitet hat, sofern einer zugewiesen war |
| `agent_name` | string \| null | Agent, der den Anruf bearbeitet hat, sofern einer zugewiesen war |
| `summary` | string \| null | Die abgeschlossene [Anrufzusammenfassung](/de/webhooks/call-complete), wenn für den Agenten **Anrufzusammenfassung generieren** aktiviert ist, sodass ein spätes Extraktionsereignis auch eine Zusammenfassung bereitstellt, die das Abschlussfenster verpasst hat; andernfalls `null`. Agenten mit einer Zusammenfassung, aber ohne Extraktionsfelder, senden dieses Ereignis nie: Lesen Sie eine späte Zusammenfassung über `GET /v1/calls/{call_id}` |
| `extracted_data.status` | string | Für dieses Ereignis immer `completed` |
| `extracted_data.fields` | object | Werte, die nach den konfigurierten Extraktionsfeldschlüsseln geordnet sind; nicht verfügbare Werte sind `null` |
| `extracted_data.evidence` | object | Nach Extraktionsfeld geordnete Nachweise. Ein Wert ungleich null enthält das exakte strukturell geprüfte Zitat (höchstens 1.000 Zeichen), `speaker_role` (`caller` oder `agent`) und `turn_index`; längere vom Modell zurückgegebene Zitate werden abgelehnt statt gekürzt, und Nachweise sind immer `null`, wenn ihr Feld `null` ist |
| `extracted_data.verification` | string | `verified` nur, wenn der unabhängige Nachweisdurchlauf für jedes Kandidatenfeld genau ein gültiges Urteil zurückgegeben hat. `unavailable` bedeutet, dass der Durchlauf fehlgeschlagen ist, eine Zeitüberschreitung hatte, nicht genügend Budget verfügbar war oder fehlerhafte beziehungsweise unvollständige Ausgabe zurückgab. Ein vollständig nicht verfügbarer Durchlauf bewahrt strukturell begründete Werte zur Kundenprüfung. Bei Teilausgabe werden gültige Urteile angewendet, und jeder Kandidat ohne genau ein gültiges Urteil wird auf null gesetzt |
| `extracted_data.field_reasons` | object | Gründe, geordnet nach Feldern, die durch strukturelle Begründung oder den unabhängigen Verifizierer auf null gesetzt wurden |
| `extracted_data.schema_version` | string | Hash des exakten für diese Extraktion verwendeten Feldschemas |
| `extracted_at` | timestamp | Abschlusszeit im Format ISO 8601 |
| `model` | string | Für die Extraktion verwendetes Modell |

### `campaign.completed`

Wird einmal gesendet, wenn eine Kampagne von `running` zu `completed` wechselt,
unabhängig davon, ob ihr Zeitplan endete oder alle Kontakte Endzustände erreicht
haben. Wiederholungsversuche des Runners senden kein weiteres Ereignis. Dieses
Lebenszyklusereignis auf Organisationsebene wird nur an Endpunkte mit
Organisationsbereich zugestellt, nicht an Endpunkte mit Agentenbereich. Nicht
blockierend.

```json
{
  "data": {
    "campaign_id": "3f6b2c9e-2a0d-4c63-b6d6-a708dc98f403",
    "name": "May win-back",
    "agent_id": 12,
    "status": "completed",
    "started_at": "2026-04-20T17:00:00Z",
    "completed_at": "2026-04-20T18:25:11Z",
    "counts": {
      "contacts_total": 150,
      "completed": 121,
      "failed": 11,
      "no_answer": 18,
      "remaining": 0
    }
  },
  "event_id": "8d8f52ce-6b46-423f-9dde-cea0b91ec135",
  "type": "campaign.completed"
}
```

Die vier Ergebnisanzahlen sind disjunkt und ergeben zusammen `contacts_total`:
`completed` enthält erfolgreiche Kontakte; `no_answer` enthält endgültig
fehlgeschlagene oder ausgeschöpfte Kontakte, deren finales Ergebnis keine Antwort
war; `failed` enthält alle anderen endgültig fehlgeschlagenen oder ausgeschöpften
Kontakte; und `remaining` enthält ausstehende, geplante oder aktuell angerufene
Kontakte. Ein Kontakt, der auf einen Wiederholungsversuch wartet, ist
`remaining`, selbst wenn sein jüngster Versuch keine Antwort ergab. Laufende
Anrufe werden vor dem einmaligen Abschluss-Snapshot abgeglichen. `started_at` ist
der konfigurierte Kampagnenstart oder die Erstellungszeit der Kampagne, wenn kein
Start konfiguriert wurde.

### `issue.reported`

Wird gesendet, wenn ein [Problembericht](/api-reference/issue-reports) erstellt
wird — entweder von einem Benutzer im Dashboard eingereicht (`source: "user"`)
oder automatisch durch die Anrufbewertung (`source: "system"`). Nicht blockierend.

```json
{
  "data": {
    "call_id": 987654321,
    "issue_report": {
      "created_at": "2026-04-20T18:25:11.002Z",
      "description": "Five-second silence before responding to the main question.",
      "id": 4321,
      "severity": "warning",
      "source": "system",
      "status": "open",
      "title": "Agent paused too long"
    }
  },
  "event_id": "5e6f7a8b-9c0d-4e1f-8a2b-3c4d5e6f7a8b",
  "type": "issue.reported"
}
```

| Feld | Typ | Beschreibung |
|-------|------|-------------|
| `agent_id` | integer \| null | Agent, der den Anruf bearbeitet hat, sofern einer zugewiesen war |
| `agent_name` | string \| null | Agent, der den Anruf bearbeitet hat, sofern einer zugewiesen war |
| `issue_report.severity` | string | `critical`, `warning` oder `info` |
| `issue_report.status` | string | `open` oder `resolved` |
| `issue_report.source` | string | `user` (über das Dashboard eingereicht) oder `system` (durch Bewertung erstellt) |

<Note>
  Die Neubewertung eines Anrufs erstellt dessen systemgenerierte Problemberichte
  neu und sendet dadurch `issue.reported` erneut für die neu erstellten Berichte.
  Deduplizieren Sie nach `call_id` + `title`, wenn Sie nur eine Benachrichtigung
  pro zugrunde liegendem Problem erhalten möchten.
</Note>

### `issue.escalated`

Wird gesendet, wenn ein Problemmuster zur Überprüfung durch Mitarbeitende an
ThunderPhone gesendet wird: nach **An ThunderPhone melden** oder wenn Mit KI
beheben keine kundenseitige Behebung bestätigen kann und das Problem automatisch
weiterleitet. Nur organisationsweite Endpunkte erhalten dieses Ereignis.

```json
{
  "data": {
    "automatic": false,
    "cluster_id": "7ac2844c-2df0-4fa8-a560-7378da649e19",
    "escalation_id": "ec99f52b-c8c0-41dd-a4f2-dd8a07b10894",
    "status": "open"
  },
  "event_id": "d8f8f420-7a42-45ba-bcf1-b747f9bbecda",
  "type": "issue.escalated"
}
```

| Feld | Typ | Beschreibung |
|-------|------|-------------|
| `automatic` | boolean | `true` für eine automatische Eskalation; `false` für eine manuelle Eskalation |
| `cluster_id` | UUID | Eskaliertes Problemmuster |
| `escalation_id` | UUID | Eskalationsdatensatz |
| `status` | string | `open`, wenn das Ereignis gesendet wird |

Dies ist eine Benachrichtigung, nicht das Nachweispaket. Verwenden Sie
`cluster_id`, um sie mit dem Problemmuster zu korrelieren. Siehe
[An ThunderPhone melden](/de/guides/issues).

---

## Testanrufereignisse

### `test-call.completed`

Wird gesendet, wenn ein
[Testanrufdurchlauf](/api-reference/test-calls#test-call-run-object)
einen Endstatus erreicht — `completed` oder `failed`, einschließlich Durchläufen,
die beim Start fehlgeschlagen sind und nie einen Anruf erzeugt haben. Nicht blockierend. Nützlich
zum Verbinden von Batch-CI-Durchläufen mit Ihren Chat-/Benachrichtigungssystemen.

```json
{
  "data": {
    "test_call_run": {
      "call_id": 987654321,
      "completed_at": "2026-04-20T18:25:04.822Z",
      "error_message": "",
      "id": 7110,
      "status": "completed",
      "target_id": 12,
      "target_type": "agent"
    }
  },
  "event_id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
  "type": "test-call.completed"
}
```

| Feld | Typ | Beschreibung |
|-------|------|-------------|
| `agent_id` | integer \| null | Sprachagent, der den Anruf bearbeitet hat, sofern einer zugewiesen war |
| `agent_name` | string \| null | Sprachagent, der den Anruf bearbeitet hat, sofern einer zugewiesen war |
| `test_call_run.target_type` | string | `agent` oder `phone_number` |
| `test_call_run.target_id` | integer | Die Sprachagent-ID oder Telefonnummern-ID, auf die der Durchlauf ausgerichtet war, entsprechend `target_type` |
| `test_call_run.status` | string | `completed` oder `failed` |
| `test_call_run.call_id` | integer \| null | `null`, wenn der Durchlauf fehlgeschlagen ist, bevor ein Anruf aufgebaut wurde |
| `test_call_run.error_message` | string | Bei Erfolg leer |

---

## Warnungsereignisse

### `alert.triggered`

Wird gesendet, wenn eine [Warnungsregel](/de/guides/alerts) mit aktiviertem Kanal
**An Entwickler-Webhooks senden** ihren Schwellenwert
überschreitet. Nicht blockierend. Eine Regel wird einmal ausgelöst und berücksichtigt dann ihre
Abklingzeit. Daher erzeugt eine anhaltende Überschreitung ein Ereignis pro Abklingzeitfenster.

```json
{
  "data": {
    "comparator": "lt",
    "event_id": "b8e6a1d4-2c3f-4a5b-9c8d-7e6f5a4b3c2d",
    "fired_at": "2026-04-20T18:00:00+00:00",
    "metric": "success_rate",
    "metric_value": 71.4,
    "rule_id": "d2c3b4a5-6f7e-4d8c-9b0a-1c2d3e4f5a6b",
    "rule_name": "Success rate below 80%",
    "threshold": 80.0,
    "window_hours": 24
  },
  "event_id": "4d5e6f7a-8b9c-4d0e-9f1a-2b3c4d5e6f7a",
  "type": "alert.triggered"
}
```

| Feld | Typ | Beschreibung |
|-------|------|-------------|
| `event_id` (in `data`) | UUID | Die ID der **Auslösung der Warnung** — unterscheidet sich von der Übermittlungs-`event_id` des Umschlags |
| `rule_id`, `rule_name` | UUID, string | Die ausgelöste Regel |
| `metric` | string | `success_rate`, `failure_rate`, `avg_score`, `call_volume` oder `suite_regression` |
| `comparator` | string | `lt`, `lte`, `gt` oder `gte` |
| `metric_value` | number | Der Wert der Metrik im Fenster zum Zeitpunkt der Regelauslösung |
| `threshold` | number | Der konfigurierte Schwellenwert |
| `window_hours` | integer | Nachlaufendes Auswertungsfenster |
| `fired_at` | timestamp | |

Weitere Informationen zum Erstellen von Regeln, Metriken,
Abklingzeiten sowie den E-Mail-/Slack-Kanälen finden Sie im [Leitfaden zu Warnungen](/de/guides/alerts).

---

## Migrationsereignisse

### `migration.call.complete`

Wird gesendet, wenn ein über
[`POST /v1/migrations/{id}/calls`](/api-reference/migration-calls) initiierter Anruf endet,
unabhängig davon, welche Plattform ihn entgegengenommen hat. Nicht blockierend. Es trifft bis zu etwa 5 Minuten
nach Ende des Anrufs ein. `data` enthält jedes Feld von
[`telephony.complete`](/de/webhooks/call-complete) sowie einen `migration`-Block. Ein von
ThunderPhone initiierter Anruf sendet wie gewohnt auch `telephony.complete` mit derselben
`call_id`. Ein Anruf auf der anderen Plattform, der nach 2
Stunden noch nicht beendet ist oder dessen Migration vorher abgeschlossen wurde oder ihren Schlüssel verloren hat, wird mit
`status: "unknown"` und ohne Transkript gesendet.

```json
{
  "data": {
    "agent_id": 42,
    "agent_name": "Front desk",
    "billable_minutes": null,
    "billing_total_cents": null,
    "call_id": null,
    "direction": "outbound",
    "duration_seconds": 94,
    "end_reason": "user_hangup",
    "end_time": "2026-10-06T17:01:34+00:00",
    "extracted_data": null,
    "from_number": "+15551234567",
    "migration": {
      "arm": "vendor",
      "id": "5f0c2a9e-7b1d-4c3e-8a6f-2d9e1b4c7a30",
      "metadata": {
        "lead_id": "8812"
      },
      "routing_id": "9b2f8c1e-4d3a-4f6b-8e2d-1a7c5b9e0f34",
      "vendor": "retell",
      "vendor_call_id": "call_6a1f0e",
      "vendor_cost_usd": "0.1240"
    },
    "product": "",
    "recording_mode": "vendor",
    "recording_url": "https://…",
    "start_time": "2026-10-06T17:00:00+00:00",
    "status": "completed",
    "summary": "The callee booked a table for two on Thursday.",
    "thunderphone_retained_call_content": true,
    "to_number": "+14155552671",
    "transcripts": [
      {
        "content": "Hi Ada, this is Rosa's calling about your booking.",
        "role": "agent"
      },
      {
        "content": "Yes, Thursday works.",
        "role": "user"
      }
    ],
    "transfer_number": null,
    "unresolved_variables": [],
    "variables": {
      "first_name": "Ada"
    },
    "voice": ""
  },
  "event_id": "7c1e2f3a-4b5c-4d6e-8f7a-9b0c1d2e3f4a",
  "type": "migration.call.complete"
}
```

| Feld | Typ | Beschreibung |
|-------|------|-------------|
| `migration.id` | UUID | Die Migration |
| `migration.routing_id` | UUID | Der weitergeleitete Anruf, wie bei seiner Initiierung zurückgegeben |
| `migration.arm` | string | `ours` (ThunderPhone hat ihn initiiert) oder `vendor` (die andere Plattform hat ihn initiiert) |
| `migration.vendor` | string | `retell`, `vapi`, `elevenlabs` oder `bland` |
| `migration.vendor_call_id` | string \| null | Die Anruf-ID der anderen Plattform; `null` für `ours` |
| `migration.metadata` | object | Die `metadata`, die Sie beim Initiieren des Anrufs gesendet haben |
| `migration.vendor_cost_usd` | string \| null | Die von der anderen Plattform gemeldeten Anrufkosten, falls sie diese gemeldet hat |
| `call_id` | integer \| null | Die ThunderPhone-Anruf-ID; `null` für `vendor` |
| `status` | string | Für `vendor`: `completed`, wenn der Angerufene gesprochen hat, `failed`, wenn nicht, `unknown` wie oben. Für `ours`: wie in `telephony.complete` |

Für einen `vendor`-Anruf verfügt ThunderPhone über keine Abrechnungs- oder Extraktionsdaten:
`billable_minutes`, `billing_total_cents` und `extracted_data` sind `null`,
`product` und `voice` sind leer, `recording_mode` ist `vendor` und
`recording_url` ist der Link der anderen Plattform, falls sie einen bereitgestellt hat.

### `migration.rollback`

Wird gesendet, wenn die schrittweise Umstellung einer Migration alle Anrufe automatisch zurück auf die andere
Plattform verschiebt: 3 Anrufe konnten innerhalb von 15 Minuten keine Verbindung zu ThunderPhone herstellen, 2 an
ThunderPhone gesendete Anrufe endeten, bevor der Agent antwortete, oder ThunderPhones Ergebnisquote bei Aufgaben fiel um mehr als die konfigurierte Differenz unter die der
anderen Plattform. Blockiert nicht, einmal pro Rollback. Danach beträgt ThunderPhones
Anteil 0 % und die Migration wird pausiert, bis jemand sie auf dem Tab Migration des
Agenten fortsetzt. Die Nutzdaten enthalten keine Telefonnummern, Transkripte oder
Anruf-IDs.

```json
{
  "data": {
    "agent_id": 42,
    "agent_name": "Front desk",
    "dropped": 0,
    "migration_id": "5f0c2a9e-7b1d-4c3e-8a6f-2d9e1b4c7a30",
    "ours": {
      "graded": 20,
      "success_rate": 0.8
    },
    "ours_failed": 3,
    "ours_percent": 0,
    "previous_percent": 25,
    "reason": "ours_failed_burst",
    "rolled_back_at": "2026-10-10T12:05:00+00:00",
    "step": 1,
    "theirs": {
      "graded": 20,
      "success_rate": 0.8
    },
    "vendor": "retell"
  },
  "event_id": "3d1f6b2a-8c4e-5a7b-9d0e-2f1a3b4c5d6e",
  "type": "migration.rollback"
}
```

| Feld | Typ | Beschreibung |
|-------|------|-------------|
| `migration_id` | UUID | Die Migration |
| `vendor` | string | `retell`, `vapi`, `elevenlabs` oder `bland` |
| `reason` | string | `ours_failed_burst` (3 fehlgeschlagene Verbindungen in 15 Minuten), `dropped_calls` (2 Anrufe endeten innerhalb von 30 Minuten, bevor der Agent antwortete) oder `rate_gap` (Differenz der Ergebnisquote bei Aufgaben über mindestens `rollback_min_calls` bewertete Anrufe pro Seite) |
| `previous_percent` | integer | ThunderPhones Anrufanteil vor dem Rollback |
| `ours_percent` | integer | Immer `0` |
| `step` | integer \| null | Der Zeitplan-Schritt, auf dem die Migration war (0-basiert) |
| `ours` / `theirs` | object \| null | Bewertete Anrufe im aktuellen Schritt und ihre Erfolgsquote; für `theirs` können die letzten 30 Tage verwendet werden, wenn der Schritt zu wenige Anrufe hat. `null`, wenn keine vorhanden waren |
| `ours_failed` | integer | Fehlgeschlagene Verbindungen, die in den letzten 15 Minuten gezählt wurden |
| `dropped` | integer | Anrufe, die in den letzten 30 Minuten als abgebrochen gezählt wurden |
| `rolled_back_at` | timestamp | |

---

## Verwandte Inhalte

<CardGroup cols={2}>
  <Card title="telephony.incoming / web.incoming" icon="phone" href="/de/webhooks/call-incoming">
    Die blockierende Payload für eingehende Anrufe, auf die Sie reagieren müssen.
  </Card>
  <Card title="telephony.complete / web.complete" icon="phone-slash" href="/de/webhooks/call-complete">
    Transkript und Metriken nach dem Anruf.
  </Card>
  <Card title="Webhook-Endpunkte" icon="bolt" href="/de/webhooks/endpoints">
    Abonnieren Sie eine URL für eine Teilmenge dieser Ereignisse.
  </Card>
  <Card title="Funktions-Tools" icon="screwdriver-wrench" href="/de/tools/overview">
    So werden `telephony.tool`- / `web.tool`-Ereignisse erzeugt.
  </Card>
</CardGroup>
