---
title: "Katalog zdarzeń"
description: "Wszystkie typy zdarzeń webhook wysyłane przez ThunderPhone."
---

Każdy korpus webhooka zawiera pole `type`, którego wartość jest jednym z typów zdarzeń na tej stronie. Gdy subskrybujesz
[punt końcowy](/pl/webhooks/endpoints), tablica `events` musi zawierać
typy zdarzeń, które chcesz otrzymywać (lub być pusta, aby subskrybować wszystko —
z wyjątkiem zdarzeń dla poszczególnych tur [`telephony.turn`](#telephony-turn) /
[`web.turn`](#web-turn), które są dostarczane tylko do punktów końcowych
wskazujących je jawnie).

Te zdarzenia są dostarczane na dwa sposoby:

* **Dostarczenia do endpointu** to zawsze **nieblokujące** powiadomienia
  z [ponownymi próbami](/pl/webhooks/overview): odpowiedz
  dowolnym kodem 2xx; koperta zawiera `event_id` do deduplikacji.
* **Blokujące** wymiany zachodzą wyłącznie w
  [starszym webhooku z jednym adresem URL](/pl/webhooks/overview): żądanie konfiguracji
  [`telephony.incoming` / `web.incoming`](/pl/webhooks/call-incoming)
  (numery w trybie webhooka: 13 s, w tym jedna ponowna próba; klucze widżetu w trybie webhooka: 10 s) oraz
  [wywołanie narzędzia](/pl/tools/overview) w trybie webhooka. Twoja odpowiedź
  kształtuje połączenie na żywo.

Poniższe przykładowe ładunki pokazują kopertę punktu końcowego w kolejności przesyłania
(klucze posortowane alfabetycznie: `data`, `event_id`, `type`); starsze dostawy
zawierają te same `data` bez `event_id`.

## Zdarzenia połączeń

### `telephony.incoming`

Wysyłane, gdy połączenie przychodzące dociera na jeden z Twoich
[numerów telefonów](/api-reference/phone-numbers). Dostarczenia do endpointu są
powiadomieniami typu fire-and-forget wysyłanymi dla **każdego** połączenia przychodzącego, niezależnie od tego,
czy numer jest skonfigurowany dla agenta, czy webhooka. Numery bez
przypisanego agenta dodatkowo otrzymują **blokujące** żądanie
konfiguracji w starszym webhooku — pełny schemat żądania / odpowiedzi znajdziesz w
[`telephony.incoming` / `web.incoming`](/pl/webhooks/call-incoming).

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

| Pole | Typ | Opis |
|-------|------|-------------|
| `agent_id` | integer \| null | Agent, który obsłużył połączenie, jeśli został przypisany |
| `agent_name` | string \| null | Agent, który obsłużył połączenie, jeśli został przypisany |

### `telephony.complete`

Wysyłane po zakończeniu przychodzącego lub wychodzącego połączenia telefonicznego. Nieblokujące.
Obejmuje transkrypcję, adres URL nagrania, gdy jest dostępny, oraz podsumowanie rozliczenia. Schemat
ładunku znajdziesz w
[`telephony.complete` / `web.complete`](/pl/webhooks/call-complete).

| Pole | Typ | Opis |
|-------|------|-------------|
| `agent_id` | integer \| null | Agent, który obsłużył połączenie, jeśli został przypisany |
| `agent_name` | string \| null | Agent, który obsłużył połączenie, jeśli został przypisany |

### `telephony.tool`

Wysyłane po tym, jak połączenie telefoniczne wywoła
[narzędzie funkcji](/pl/tools/overview). Nieblokujące powiadomienie audytowe —
narzędzie zostało już wykonane, gdy to zdarzenie jest dostarczane; obejmuje
Twoje własne narzędzia funkcji oraz wbudowane narzędzie `send_sms` (nie inne wbudowane
narzędzia, narzędzia bazy wiedzy, połączeń aplikacji ani MCP). W przypadku `send_sms`
zarówno `arguments.to`, jak i `arguments.body` mają wartość `[REDACTED]`. Transkrypcje
ukończenia również je redagują; pobierz treść i odbiorcę z zasobu SMS
o zakresie organizacji, używając `message_id` z odpowiedzi.

```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` to wynik wykonania: `{"status": <http status>,
"response": <your endpoint's JSON>}` w przypadku powodzenia lub
`{"status": <status>, "error": "<message>"}` w przypadku niepowodzenia.

| Pole | Typ | Opis |
|-------|------|-------------|
| `agent_id` | integer \| null | Agent, który obsłużył połączenie, jeśli został przypisany |
| `agent_name` | string \| null | Agent, który obsłużył połączenie, jeśli został przypisany |

### `telephony.turn`

Wysyłane w trakcie **trwania** połączenia telefonicznego, raz dla każdej
tury zawierającej wypowiedź, gdy się pojawia — wypowiedziane odpowiedzi agenta
oraz transkrybowane tury rozmówcy. Umożliwia śledzenie rozmowy na żywo
za pomocą zwykłych webhooków zamiast odpytywania
[`GET /v1/calls/{call_id}/transcript`](/api-reference/calls#get-transcript).
Nieblokujące.

<Note>
  **Wymagana jest jawna subskrypcja.** W przeciwieństwie do wszystkich innych typów zdarzeń,
  zdarzenia tur nigdy nie są dostarczane przez pustą tablicę `events`
  (subskrypcja wszystkich). Endpoint otrzymuje je tylko wtedy, gdy jego lista `events`
  zawiera jawnie `telephony.turn` / `web.turn`.
</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"
}
```

| Pole | Typ | Opis |
|-------|------|-------------|
| `agent_id` | integer \| null | Agent, który obsłużył połączenie, jeśli został przypisany |
| `agent_name` | string \| null | Agent, który obsłużył połączenie, jeśli został przypisany |
| `position` | integer | Indeks tury w historii połączenia — stabilny identyfikator do ustalania kolejności |
| `role` | string | `assistant` (wypowiedź agenta) lub `user` (wypowiedź rozmówcy) |
| `text` | string | Tekst transkrypcji tury znany w momencie emisji |
| `entry_type` | string | Typ podstawowego wpisu historii: `completion` (agent) albo `user_turn` / `span` (rozmówca) |
| `start_ms`, `end_ms` | integer | Przesunięcia audio w ms od rozpoczęcia połączenia; obecne tylko wtedy, gdy czas odtwarzania był znany w momencie emisji |

<Note>
  Dostarczanie odbywa się co najmniej raz, a tury mogą nadejść **w niewłaściwej kolejności**:
  usuwaj duplikaty na podstawie `event_id` koperty i porządkuj według `position`. Transkrypcje
  rozmówcy mogą być nadal doprecyzowywane po emisji; transkrypcja
  [`telephony.complete`](/pl/webhooks/call-complete) po zakończeniu połączenia jest
  autorytatywna. Emitowane są tylko wypowiedziane tury — wywołania narzędzi, szepty
  i inne wewnętrzne wpisy nigdy nie pojawiają się w tym strumieniu.
</Note>

### `web.incoming`

Odpowiednik `telephony.incoming` dla kanału internetowego, wysyłany po rozpoczęciu
sesji [widżetu internetowego](/pl/widget/overview) lub testowego połączenia mikrofonowego w kreatorze.
Dostarczenia do endpointu są powiadomieniami typu fire-and-forget dla każdej sesji internetowej.
Klucze publikowalne w `mode="webhook"` dodatkowo otrzymują
**blokujące** żądanie konfiguracji w starszym webhooku — to blokujące
żądanie ma inny format (`origin_domain`,
`publishable_key_prefix`; bez numerów telefonów). Zobacz
[`telephony.incoming` / `web.incoming`](/pl/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` zawsze ma dosłowną wartość `"web"`. W przypadku sesji widżetu
w trybie webhook `to_number` jest puste (numer agenta sesji jest przypisywany
po konfiguracji); w przypadku testowych połączeń mikrofonowych w kreatorze wartości
`origin_domain` i `publishable_key_prefix` są puste.

| Pole | Typ | Opis |
|-------|------|-------------|
| `agent_id` | integer \| null | Agent, który obsłużył połączenie, jeśli został przypisany |
| `agent_name` | string \| null | Agent, który obsłużył połączenie, jeśli został przypisany |

### `web.complete`

Odpowiednik `telephony.complete` dla kanału internetowego, obejmujący połączenia
widżetu internetowego (`direction: "web"`) oraz testowe połączenia mikrofonowe w kreatorze
(`direction: "test"`). Nieblokujące. Taki sam format ładunku jak
[`telephony.complete`](/pl/webhooks/call-complete), dodatkowo z `origin_domain`,
a `from_number` ma wartość `"web"`.

| Pole | Typ | Opis |
|-------|------|-------------|
| `agent_id` | integer \| null | Agent, który obsłużył połączenie, jeśli został przypisany |
| `agent_name` | string \| null | Agent, który obsłużył połączenie, jeśli został przypisany |

<Note>
  W starszym webhooku z jednym adresem URL testowe połączenia mikrofonowe w kreatorze
  historycznie są raportowane jako `telephony.complete` — tylko połączenia z `direction:
  "web"` używają tam typu `web.complete`. System endpointów
  mapuje zarówno połączenia internetowe, jak i testowe na `web.*`. Historyczne ładunki mogą
  zawierać starsze wartości `direction`: `widget` lub `mic`.
</Note>

### `web.tool`

Odpowiednik `telephony.tool` dla kanału internetowego. `data` zawiera
`origin_domain` zamiast `from_number` / `to_number`.

| Pole | Typ | Opis |
|-------|------|-------------|
| `agent_id` | integer \| null | Agent, który obsłużył połączenie, jeśli został przypisany |
| `agent_name` | string \| null | Agent, który obsłużył połączenie, jeśli został przypisany |

### `web.turn`

Odpowiednik [`telephony.turn`](#telephony-turn) dla kanału internetowego,
obejmujący połączenia widżetu internetowego i testowe połączenia mikrofonowe w kreatorze. Taki sam format
ładunku, z `origin_domain` zamiast `from_number` / `to_number`.
Podobnie jak `telephony.turn`, wymaga **jawnej subskrypcji** —
nigdy nie jest dostarczane przez pustą tablicę `events`.

| Pole | Typ | Opis |
|-------|------|-------------|
| `agent_id` | integer \| null | Agent, który obsłużył połączenie, jeśli został przypisany |
| `agent_name` | string \| null | Agent, który obsłużył połączenie, jeśli został przypisany |

### `call.transfer_completed`

Wysyłane raz na połączenie z końcowym wynikiem
[przekazania połączenia](/pl/guides/call-transfers): przekazania bez konsultacji lub połączenia
między osobami, które pozostaje po przekazaniu z konsultacją, gdy agent się rozłączy.
Nie blokuje wykonywania i jest dostarczane wyłącznie do punktów końcowych (nigdy do starszego
webhooka z jednym adresem URL). Dociera po zdarzeniu `telephony.complete` połączenia:
gdy operator przejmie połączenie lub przekazanie się nie powiedzie albo, gdy
ThunderPhone połączył rozmowę, po zakończeniu połączenia między stronami.

```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"
}
```

| Pole | Typ | Opis |
|-------|------|-------------|
| `call_id` | integer | Połączenie, które zostało przekazane |
| `agent_id` | integer \| null | Agent, który obsłużył połączenie, jeśli został przypisany |
| `agent_name` | string \| null | Agent, który obsłużył połączenie, jeśli został przypisany |
| `transfer_outcome` | string | `refer_accepted`: operator przejął połączenie. `bridged`: ThunderPhone sam utrzymał połączenie między rozmówcą a numerem docelowym, ponieważ operator odmówił przekazania bez konsultacji lub agent przekazania z konsultacją się rozłączył. `bridge_unanswered`: operator odmówił przekazania bez konsultacji, a numer docelowy nie odebrał własnego połączenia ThunderPhone. `failed`: przekazanie nie doszło do skutku, a połączenie się zakończyło |
| `destination` | string \| null | Numer, na który przekazano połączenie |
| `sip_status` | integer \| null | Status SIP operatora, gdy odmówił przekazania bez konsultacji: `403` (na przykład trunk Twilio bez przekazywania połączeń), `405` lub `501`. `null`, gdy operator nie odmówił |
| `bridge_kind` | string \| null | Tylko `bridged`: `cold_fallback` (odrzucone przekazanie bez konsultacji, które ThunderPhone połączył) lub `warm` (dwie osoby w przekazaniu z konsultacją po rozłączeniu agenta) |
| `bridge_seconds` | integer \| null | Tylko `bridged`: czas połączenia między stronami rozliczony przez ThunderPhone, w sekundach |
| `bridge_total_cents` | integer \| null | Tylko `bridged`: koszt połączenia między stronami w centach USD po uwzględnieniu ewentualnego bezpłatnego kredytu na połączenia, rozliczany oddzielnie od `billing_total_cents` połączenia |

Te same wartości znajdują się w [obiekcie połączenia](/api-reference/calls#call-object)
jako `transfer_outcome`, `transfer_destination`, `transfer_sip_status`,
`transfer_bridge_kind`, `transfer_bridge_seconds` oraz
`transfer_bridge_total_cents`. `event_id` jest taki sam przy każdym dostarczeniu
dla połączenia, więc ponowne zgłoszenie nigdy nie tworzy drugiego zdarzenia.

---

## Zdarzenia SMS

Zdarzenia SMS opisują wiadomości wysyłane przez połączone konto Twilio lub
Telnyx organizacji. Treść wiadomości jest pomijana, a `to` jest redagowane.
Pobierz wiadomość w zakresie organizacji za pomocą
[`GET /v1/sms/{message_id}`](/api-reference/sms#retrieve-a-message), gdy potrzebujesz jej
treści lub odbiorcy.

### `sms.sent`

Wysyłane, gdy operator klienta zaakceptuje żądanie wysłania SMS-a. Nie jest to
potwierdzenie dostarczenia na urządzenie.

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

Wysyłane po trwałym odrzuceniu przez operatora, po wyczerpaniu ponownych prób
w przypadku błędów przejściowych lub gdy wynik jest trwale nieznany. `error_code` to stabilny
kod ThunderPhone, a `error_message` określa działanie klienta, gdy jest ono
dostępne. `status: "unknown"` oznacza, że operator mógł zaakceptować SMS;
uzgodnij jego status w dzienniku operatora, ponieważ ThunderPhone nie wyśle go
automatycznie ponownie.

### `sms.received`

Zarezerwowane dla obsługi przychodzących SMS-ów. W obecnej wersji nie są
emitowane żadne zdarzenia `sms.received`. Konfiguracja webhooka operatora dla
wiadomości przychodzących oraz weryfikacja podpisu zostaną udostępnione osobno.

---

## Zdarzenia głosowe

Tworzenie niestandardowego głosu jest asynchroniczne. Te nieblokujące zdarzenia
pozwalają reagować na wynik końcowy zamiast odpytywać
[punkt końcowy szczegółów klonu](/api-reference/custom-voices#list-and-retrieve-clones).

`voice.ready` i `voice.failed` są dostarczane wyłącznie do punktu końcowego
obejmującego całą organizację z `events: []`. Nie można ich wybrać jako jawnych
filtrów zdarzeń.

### `voice.ready`

Wysyłane, gdy niestandardowy głos zakończy przetwarzanie i może zostać przypisany
do agenta.

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

Wysyłane, gdy przetwarzanie niestandardowego głosu zakończy się trwałym błędem.

```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"
}
```

| Pole | Typ | Opis |
|-------|------|-------------|
| `voice.id` | string | Publiczny identyfikator niestandardowego głosu |
| `voice.name` | string | Wartość głosu agenta w formacie `custom:<public_id>` |
| `voice.display_name` | string | Nazwa głosu widoczna dla organizacji |
| `voice.language` | string | Kod jedynego języka klonu |
| `voice.gender` | string | `male`, `female` lub pusty ciąg |
| `voice.status` | string | `ready` dla `voice.ready`; `failed` dla `voice.failed` |
| `voice.failure_reason` | string | Puste w przypadku powodzenia; szczegóły błędu przetwarzania w przypadku niepowodzenia |
| `voice.created_at`, `voice.updated_at` | timestamp | Znaczniki czasu ISO 8601 |
| `reason` | string | Szczegóły błędu; obecne tylko w `voice.failed` |

---

## Zdarzenia jakości

### `call.graded`

Wysyłane za każdym razem, gdy dla połączenia zostanie ukończone [uruchomienie oceny AI](/api-reference/calls#ai-call-grading).
Nieblokujące.

```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"
}
```

| Pole | Typ | Opis |
|-------|------|-------------|
| `agent_id` | integer \| null | Agent, który obsłużył połączenie, jeśli został przypisany |
| `agent_name` | string \| null | Agent, który obsłużył połączenie, jeśli został przypisany |
| `grade.id` | integer | Identyfikator oceny |
| `grade.score` | integer \| null | 0–100 |
| `grade.call_outcome` | string | `success`, `failure`, `unknown` lub `no_conversation` |
| `grade.summary` | string | Jednoakapitowe podsumowanie |
| `grade.detected_issues` | array | Ciągi opisujące problemy wykryte przez oceniający model |
| `grade.status` | string | Zawsze `completed` — emitowane są tylko ukończone uruchomienia |
| `grade.grader_model` | string | Model oceniający, który utworzył wynik (np. `heuristic-v1`) |
| `grade.graded_at`, `grade.created_at` | timestamp | |
| `report` | object \| null | Widoczny dla klienta [raport z połączenia](/api-reference/calls#call-report): etykieta wyniku, flaga i powód wymagania uwagi, rozmówca, jednozdaniowe podsumowanie, doświadczenie rozmówcy. Przy wczesnej ocenie heurystycznej jest to `null` lub raport `pending`, którego pola są wartościami zastępczymi; zdarzenie pełnej oceny zawiera ukończony raport |

<Note>
  Połączenie może zostać ocenione więcej niż raz — po szybkiej ocenie heurystycznej
  często następuje pełna ocena modelowa, gdy nagranie jest dostępne, możliwe są
  również ręczne ponowne oceny. Każde ukończone uruchomienie emituje własne zdarzenie
  `call.graded`; za wiążącą uznawaj najnowszą wartość `graded_at`.
</Note>

### `call.data_extracted`

Wysyłane za każdym razem, gdy pomyślnie zakończy się ekstrakcja danych strukturalnych, w tym
opóźniona ponowna próba po `telephony.complete` / `web.complete` lub ręczne ponowne uruchomienie przez
[`POST /v1/calls/{call_id}/extract`](/api-reference/calls#run-data-extraction).
Nieblokujące.

W trybie blokującej ekstrakcji zdarzenie ukończenia zwykle czeka nie dłużej
niż 75-sekundowy limit ekstrakcji. Jeśli proces roboczy ekstrakcji zostanie
utracony, produkcyjny proces finalizacji (co pięć minut) zwalnia zdarzenie
ukończenia, którego `blocking_deadline_at` minął, zanim rozpocznie kolejną
próbę ekstrakcji. Późniejszy sukces jest dostarczany osobno jako to zdarzenie.

<Warning>
  Wyodrębnione wartości są interpretacją rozmowy przez model. Każda wartość
  różna od null zawiera cytat, rolę rozmówcy i indeks tury, na których została
  oparta, a także flagę weryfikacji na poziomie uruchomienia. Zweryfikuj wynik
  przed podjęciem decyzji dotyczących pieniędzy, tożsamości lub dostępu.
</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"
}
```

| Pole | Typ | Opis |
|-------|------|-------------|
| `agent_id` | integer \| null | Agent, który obsłużył połączenie, jeśli został przypisany |
| `agent_name` | string \| null | Agent, który obsłużył połączenie, jeśli został przypisany |
| `summary` | string \| null | Ukończone [podsumowanie połączenia](/pl/webhooks/call-complete), gdy agent ma włączoną opcję **Generuj podsumowanie połączenia**, dzięki czemu opóźnione zdarzenie ekstrakcji dostarcza również podsumowanie, które nie zmieściło się w oknie ukończenia; w przeciwnym razie `null`. Agenci z podsumowaniem, ale bez pól ekstrakcji, nigdy nie emitują tego zdarzenia: odczytaj opóźnione podsumowanie przez `GET /v1/calls/{call_id}` |
| `extracted_data.status` | string | Dla tego zdarzenia zawsze `completed` |
| `extracted_data.fields` | object | Wartości kluczowane skonfigurowanymi kluczami pól ekstrakcji; niedostępne wartości to `null` |
| `extracted_data.evidence` | object | Dowody kluczowane według pola ekstrakcji. Wartość różna od null zawiera dokładny cytat sprawdzony strukturalnie, liczący najwyżej 1 000 znaków, `speaker_role` (`caller` lub `agent`) oraz `turn_index`; dłuższe cytaty zwrócone przez model są odrzucane zamiast skracane, a dowód ma wartość `null`, gdy jego pole ma wartość `null` |
| `extracted_data.verification` | string | `verified` tylko wtedy, gdy niezależny etap weryfikacji dowodów zwrócił dokładnie jeden prawidłowy werdykt dla każdego pola kandydującego. `unavailable` oznacza, że etap nie powiódł się, przekroczył limit czasu, nie miał wystarczającego budżetu albo zwrócił nieprawidłowe lub częściowe dane wyjściowe. Całkowicie niedostępny etap zachowuje wartości oparte strukturalnie do przeglądu przez klienta. W przypadku częściowych danych wyjściowych prawidłowe werdykty są stosowane, a każde pole kandydujące bez dokładnie jednego prawidłowego werdyktu otrzymuje wartość null |
| `extracted_data.field_reasons` | object | Przyczyny kluczowane według pól, którym nadano wartość null przez ugruntowanie strukturalne lub niezależny weryfikator |
| `extracted_data.schema_version` | string | Hash dokładnego schematu pól użytego do tej ekstrakcji |
| `extracted_at` | timestamp | Czas ukończenia w formacie ISO 8601 |
| `model` | string | Model użyty do ekstrakcji |

### `campaign.completed`

Wysyłane raz, gdy kampania przechodzi ze stanu `running` do `completed`, niezależnie od tego,
czy zakończył się jej harmonogram, czy wszystkie kontakty osiągnęły stany końcowe. Ponowne próby
procesu wykonawczego nie emitują kolejnego zdarzenia. To zdarzenie cyklu życia na poziomie organizacji
jest dostarczane tylko do punktów końcowych o zakresie organizacji, a nie do punktów końcowych
o zakresie agenta. Nieblokujące.

```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"
}
```

Cztery liczby wyników są rozłączne i sumują się do `contacts_total`:
`completed` zawiera kontakty zakończone sukcesem; `no_answer` zawiera końcowe
kontakty nieudane lub wyczerpane, których końcowym wynikiem był brak odpowiedzi;
`failed` zawiera wszystkie pozostałe końcowe kontakty nieudane lub wyczerpane;
a `remaining` zawiera kontakty oczekujące, zaplanowane lub będące obecnie w trakcie
połączenia. Kontakt oczekujący na ponowną próbę ma status `remaining`, nawet jeśli
jego ostatnia próba zakończyła się brakiem odpowiedzi. Połączenia w toku są uzgadniane
przed jednorazowym migawkowym zakończeniem. `started_at` to skonfigurowany początek
kampanii lub czas utworzenia kampanii, gdy nie skonfigurowano początku.

### `issue.reported`

Wysyłane, gdy zostanie utworzony [raport problemu](/api-reference/issue-reports) —
zgłoszony przez użytkownika z panelu (`source: "user"`) albo automatycznie
przez ocenę połączenia (`source: "system"`). Nieblokujące.

```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"
}
```

| Pole | Typ | Opis |
|-------|------|-------------|
| `agent_id` | integer \| null | Agent, który obsłużył połączenie, jeśli został przypisany |
| `agent_name` | string \| null | Agent, który obsłużył połączenie, jeśli został przypisany |
| `issue_report.severity` | string | `critical`, `warning` lub `info` |
| `issue_report.status` | string | `open` lub `resolved` |
| `issue_report.source` | string | `user` (zgłoszone z panelu) lub `system` (utworzone przez ocenę) |

<Note>
  Ponowna ocena połączenia odbudowuje jego raporty problemów wygenerowane przez system,
  co ponownie emituje `issue.reported` dla odtworzonych raportów. Wykonaj deduplikację
  według `call_id` + `title`, jeśli chcesz otrzymywać tylko jedno powiadomienie dla
  każdego podstawowego problemu.
</Note>

### `issue.escalated`

Wysyłane, gdy wzorzec problemu zostanie przekazany do ThunderPhone do przeglądu przez
zespół: po wybraniu **Zgłoś do ThunderPhone** albo gdy funkcja Napraw za pomocą AI nie
może potwierdzić poprawki po stronie klienta i automatycznie przekierowuje problem.
To zdarzenie otrzymują wyłącznie punkty końcowe obejmujące całą organizację.

```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"
}
```

| Pole | Typ | Opis |
|-------|------|-------------|
| `automatic` | boolean | `true` dla automatycznej eskalacji; `false` dla ręcznej eskalacji |
| `cluster_id` | UUID | Eskalowany wzorzec problemu |
| `escalation_id` | UUID | Rekord eskalacji |
| `status` | string | `open` w momencie emisji zdarzenia |

To jest powiadomienie, a nie pakiet dowodowy. Użyj `cluster_id`, aby powiązać
je ze wzorcem problemu. Zobacz [Zgłoś do ThunderPhone](/pl/guides/issues).

---

## Zdarzenia połączeń testowych

### `test-call.completed`

Wysyłane, gdy
[uruchomienie testowe](/api-reference/test-calls#test-call-run-object)
osiągnie status końcowy — `completed` lub `failed`, w tym uruchomienia,
które zakończyły się niepowodzeniem przy starcie i nigdy nie wygenerowały połączenia. Nieblokujące. Przydatne do integrowania wsadowych uruchomień CI z systemami czatu i powiadomień.

```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"
}
```

| Pole | Typ | Opis |
|-------|------|-------------|
| `agent_id` | integer \| null | Agent, który obsłużył połączenie, gdy został przypisany |
| `agent_name` | string \| null | Agent, który obsłużył połączenie, gdy został przypisany |
| `test_call_run.target_type` | string | `agent` lub `phone_number` |
| `test_call_run.target_id` | integer | Identyfikator agenta lub numeru telefonu, którego dotyczyło uruchomienie, zgodny z `target_type` |
| `test_call_run.status` | string | `completed` lub `failed` |
| `test_call_run.call_id` | integer \| null | `null`, gdy uruchomienie nie powiodło się przed wykonaniem połączenia |
| `test_call_run.error_message` | string | Puste w przypadku powodzenia |

---

## Zdarzenia alertów

### `alert.triggered`

Wysyłane, gdy [reguła alertu](/pl/guides/alerts) z włączonym kanałem **Dostarczaj do
webhooków deweloperskich** przekroczy swój próg.
Nieblokujące. Reguła uruchamia się raz, a następnie uwzględnia okres wyciszenia, dlatego utrzymujące się przekroczenie generuje jedno zdarzenie na każde okno okresu wyciszenia.

```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"
}
```

| Pole | Typ | Opis |
|-------|------|-------------|
| `event_id` (w `data`) | UUID | Identyfikator **uruchomienia** alertu — odrębny od `event_id` dostarczenia w kopercie |
| `rule_id`, `rule_name` | UUID, string | Reguła, która została uruchomiona |
| `metric` | string | `success_rate`, `failure_rate`, `avg_score`, `call_volume` lub `suite_regression` |
| `comparator` | string | `lt`, `lte`, `gt` lub `gte` |
| `metric_value` | number | Wartość metryki w oknie, gdy reguła została uruchomiona |
| `threshold` | number | Skonfigurowany próg |
| `window_hours` | integer | Kroczące okno oceny |
| `fired_at` | timestamp | |

Informacje o tworzeniu reguł, metrykach, okresach wyciszenia oraz kanałach e-mail / Slack znajdziesz w [przewodniku po alertach](/pl/guides/alerts).

---

## Zdarzenia migracji

### `migration.call.complete`

Wysyłane, gdy połączenie zainicjowane przez
[`POST /v1/migrations/{id}/calls`](/api-reference/migration-calls) zakończy się,
niezależnie od platformy, która je obsłużyła. Nie blokuje. Przychodzi do około 5 minut
po zakończeniu połączenia. `data` zawiera wszystkie pola z
[`telephony.complete`](/pl/webhooks/call-complete) oraz blok `migration`. Połączenie
zainicjowane przez ThunderPhone wysyła również standardowo `telephony.complete` z tym
samym `call_id`. Połączenie na innej platformie, które nie zakończyło się po 2
godzinach albo którego migracja zakończyła się lub wcześniej utraciła klucz, jest wysyłane
ze `status: "unknown"` i bez transkrypcji.

```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"
}
```

| Pole | Typ | Opis |
|-------|------|-------------|
| `migration.id` | UUID | Migracja |
| `migration.routing_id` | UUID | Przekierowane połączenie, zwrócone podczas jego inicjowania |
| `migration.arm` | string | `ours` (ThunderPhone je zainicjował) lub `vendor` (zrobiła to inna platforma) |
| `migration.vendor` | string | `retell`, `vapi`, `elevenlabs` lub `bland` |
| `migration.vendor_call_id` | string \| null | Identyfikator połączenia na innej platformie; `null` dla `ours` |
| `migration.metadata` | object | `metadata` wysłane podczas inicjowania połączenia |
| `migration.vendor_cost_usd` | string \| null | Koszt połączenia zgłoszony przez inną platformę, jeśli go podała |
| `call_id` | integer \| null | Identyfikator połączenia ThunderPhone; `null` dla `vendor` |
| `status` | string | Dla `vendor`: `completed`, gdy rozmówca mówił, `failed`, gdy nie mówił, `unknown` jak powyżej. Dla `ours`: jak w `telephony.complete` |

W przypadku połączenia `vendor` ThunderPhone nie ma danych rozliczeniowych ani danych
ekstrakcji: `billable_minutes`, `billing_total_cents` i `extracted_data` mają wartość
`null`, `product` i `voice` są puste, `recording_mode` ma wartość `vendor`, a
`recording_url` jest linkiem z innej platformy, jeśli go podała.

### `migration.rollback`

Wysyłane, gdy stopniowe przełączanie migracji samoczynnie przekierowuje wszystkie połączenia z powrotem na drugą platformę: 3 połączenia nie zdołały połączyć się z ThunderPhone w ciągu 15 minut, 2 połączenia skierowane do ThunderPhone zakończyły się, zanim agent odebrał, albo wskaźnik realizacji zadań ThunderPhone spadł o więcej niż skonfigurowana różnica poniżej wskaźnika drugiej platformy. Nie blokuje, wysyłane raz na każde wycofanie. Po nim udział ThunderPhone wynosi 0%, a migracja jest wstrzymana, dopóki ktoś nie wznowi jej na karcie Migracja agenta. Ładunek nie zawiera numerów telefonów, transkrypcji ani identyfikatorów połączeń.

```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"
}
```

| Pole | Typ | Opis |
|-------|------|-------------|
| `migration_id` | UUID | Migracja |
| `vendor` | ciąg znaków | `retell`, `vapi`, `elevenlabs` lub `bland` |
| `reason` | ciąg znaków | `ours_failed_burst` (3 nieudane połączenia w ciągu 15 minut), `dropped_calls` (2 połączenia zakończone, zanim agent odebrał, w ciągu 30 minut) lub `rate_gap` (różnica wskaźników realizacji zadań przy co najmniej `rollback_min_calls` ocenionych połączeniach po każdej stronie) |
| `previous_percent` | liczba całkowita | Udział połączeń ThunderPhone przed wycofaniem |
| `ours_percent` | liczba całkowita | Zawsze `0` |
| `step` | liczba całkowita \| null | Krok harmonogramu, w którym się znajdowała (indeksowany od 0) |
| `ours` / `theirs` | obiekt \| null | Ocenione połączenia w bieżącym kroku i ich wskaźnik powodzenia; `theirs` może obejmować ostatnie 30 dni, gdy krok ma zbyt mało połączeń. `null`, gdy nie było żadnych |
| `ours_failed` | liczba całkowita | Nieudane połączenia zliczone w ciągu ostatnich 15 minut |
| `dropped` | liczba całkowita | Połączenia zliczone jako przerwane w ciągu ostatnich 30 minut |
| `rolled_back_at` | znacznik czasu | |

---

## Powiązane

<CardGroup cols={2}>
  <Card title="telephony.incoming / web.incoming" icon="phone" href="/pl/webhooks/call-incoming">
    Blokujący ładunek danych połączenia przychodzącego, na który musisz odpowiedzieć.
  </Card>
  <Card title="telephony.complete / web.complete" icon="phone-slash" href="/pl/webhooks/call-complete">
    Transkrypcja i metryki po połączeniu.
  </Card>
  <Card title="Punkty końcowe webhooków" icon="bolt" href="/pl/webhooks/endpoints">
    Zasubskrybuj adres URL do wybranego podzbioru tych zdarzeń.
  </Card>
  <Card title="Narzędzia funkcji" icon="screwdriver-wrench" href="/pl/tools/overview">
    Jak generowane są zdarzenia `telephony.tool` / `web.tool`.
  </Card>
</CardGroup>
