---
title: "Catálogo de eventos"
description: "Todos os tipos de eventos de webhook emitidos pelo ThunderPhone."
---

Todo corpo de webhook tem um campo `type` cujo valor é um dos tipos de evento
nesta página. Quando você assina um
[endpoint](/pt/webhooks/endpoints), o array `events` deve conter os
tipos de evento desejados (ou ficar vazio para assinar tudo —
exceto os eventos por turno [`telephony.turn`](#telephony-turn) /
[`web.turn`](#web-turn), que são entregues apenas aos endpoints que
os nomeiam explicitamente).

Dois estilos de entrega transportam esses eventos:

* As **entregas de endpoint** são sempre notificações **não bloqueantes** com [tentativas](/pt/webhooks/overview): responda com qualquer 2xx; o envelope inclui um `event_id` para deduplicação.
* As trocas **bloqueantes** ocorrem apenas no [webhook legado de URL única](/pt/webhooks/overview): a solicitação de configuração [`telephony.incoming` / `web.incoming`](/pt/webhooks/call-incoming) (números no modo webhook: 13 s, incluindo uma tentativa; chaves de widget no modo webhook: 10 s) e o [despacho de ferramentas](/pt/tools/overview) no modo webhook. Sua resposta molda a chamada em tempo real.

Os exemplos de payload abaixo mostram o envelope de endpoint na ordem de transmissão
(chaves ordenadas alfabeticamente: `data`, `event_id`, `type`); as
entregas legadas incluem o mesmo `data` sem `event_id`.

## Eventos de chamada

### `telephony.incoming`

Enviado quando uma chamada recebida chega a um dos seus
[números de telefone](/api-reference/phone-numbers). As entregas ao endpoint são
notificações sem confirmação enviadas para **todas** as chamadas recebidas, quer
o número esteja configurado com um agente ou com um webhook. Números sem
um agente atribuído também recebem a solicitação de configuração
**bloqueante** no webhook legado — consulte
[`telephony.incoming` / `web.incoming`](/pt/webhooks/call-incoming) para
o esquema completo de solicitação / resposta.

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

| Campo | Tipo | Descrição |
|-------|------|-------------|
| `agent_id` | integer \| null | Agente que atendeu a chamada, quando um foi atribuído |
| `agent_name` | string \| null | Agente que atendeu a chamada, quando um foi atribuído |

### `telephony.complete`

Enviado quando uma chamada de telefonia recebida ou realizada termina. Não bloqueante.
Inclui a transcrição, a URL da gravação quando disponível e o resumo de cobrança. Consulte
[`telephony.complete` / `web.complete`](/pt/webhooks/call-complete) para
o esquema da carga útil.

| Campo | Tipo | Descrição |
|-------|------|-------------|
| `agent_id` | integer \| null | Agente que atendeu a chamada, quando um foi atribuído |
| `agent_name` | string \| null | Agente que atendeu a chamada, quando um foi atribuído |

### `telephony.tool`

Enviado após uma chamada de telefonia invocar uma
[ferramenta de função](/pt/tools/overview). Notificação de auditoria não bloqueante —
a ferramenta já foi executada quando este evento é entregue; ela abrange
suas próprias ferramentas de função e a ferramenta integrada `send_sms` (não outras ferramentas
integradas, de base de conhecimento, de conexão de aplicativo ou MCP). Para `send_sms`,
tanto `arguments.to` quanto `arguments.body` são `[REDACTED]`. As
transcrições de conclusão também os ocultam; recupere o conteúdo e o destinatário do
recurso SMS com escopo da organização usando o `message_id` da resposta.

```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` é o resultado executado: `{"status": <http status>,
"response": <your endpoint's JSON>}` em caso de sucesso, ou
`{"status": <status>, "error": "<message>"}` em caso de falha.

| Campo | Tipo | Descrição |
|-------|------|-------------|
| `agent_id` | integer \| null | Agente que atendeu a chamada, quando um foi atribuído |
| `agent_name` | string \| null | Agente que atendeu a chamada, quando um foi atribuído |

### `telephony.turn`

Enviado enquanto uma chamada de telefonia está **em andamento**, uma vez para cada
turno com fala conforme ele ocorre — as conclusões faladas pelo agente e
os turnos transcritos de quem liga. Permite acompanhar a conversa ao vivo
por webhooks simples, em vez de consultar repetidamente
[`GET /v1/calls/{call_id}/transcript`](/api-reference/calls#get-transcript).
Não bloqueante.

<Note>
  **É necessária uma assinatura explícita.** Diferentemente de todos os outros tipos de evento,
  eventos de turno nunca são entregues por meio de uma matriz `events`
  vazia (assinar todos). Um endpoint só os recebe quando sua lista
  `events` contém `telephony.turn` / `web.turn` explicitamente.
</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"
}
```

| Campo | Tipo | Descrição |
|-------|------|-------------|
| `agent_id` | integer \| null | Agente que atendeu a chamada, quando um foi atribuído |
| `agent_name` | string \| null | Agente que atendeu a chamada, quando um foi atribuído |
| `position` | integer | O índice do turno no histórico da chamada — uma identidade estável para ordenação |
| `role` | string | `assistant` (fala do agente) ou `user` (fala de quem liga) |
| `text` | string | O texto da transcrição do turno conforme conhecido no momento da emissão |
| `entry_type` | string | O tipo de entrada subjacente do histórico: `completion` (agente) ou `user_turn` / `span` (quem liga) |
| `start_ms`, `end_ms` | integer | Deslocamentos de áudio em ms desde o início da chamada; presentes somente quando o tempo de reprodução já era conhecido no momento da emissão |

<Note>
  A entrega é pelo menos uma vez e os turnos podem chegar **fora de ordem**:
  remova duplicatas usando o `event_id` do envelope e ordene por `position`. As
  transcrições de quem liga ainda podem ser refinadas após a emissão; a transcrição
  de [`telephony.complete`](/pt/webhooks/call-complete) após a chamada é
  autoritativa. Somente turnos falados são emitidos — chamadas de ferramenta, sussurros e
  outras entradas internas nunca aparecem neste fluxo.
</Note>

### `web.incoming`

O equivalente no canal web de `telephony.incoming`, enviado quando uma
sessão do [widget web](/pt/widget/overview) ou uma chamada de teste de microfone do builder
começa. As entregas ao endpoint são sem confirmação para todas as sessões web.
Chaves publicáveis em `mode="webhook"` também recebem a
solicitação de configuração **bloqueante** no webhook legado — essa
solicitação bloqueante tem um formato diferente (`origin_domain`,
`publishable_key_prefix`; sem números de telefone). Consulte
[`telephony.incoming` / `web.incoming`](/pt/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` é sempre o literal `"web"`. Para sessões do widget no modo webhook,
`to_number` fica vazio (o número do agente da sessão é atribuído
após a configuração); para chamadas de teste de microfone do builder, `origin_domain` e
`publishable_key_prefix` ficam vazios.

| Campo | Tipo | Descrição |
|-------|------|-------------|
| `agent_id` | integer \| null | Agente que atendeu a chamada, quando um foi atribuído |
| `agent_name` | string \| null | Agente que atendeu a chamada, quando um foi atribuído |

### `web.complete`

O equivalente no canal web de `telephony.complete`, abrangendo chamadas do
widget web (`direction: "web"`) e chamadas de teste de microfone do builder
(`direction: "test"`). Não bloqueante. Tem o mesmo formato de carga útil que
[`telephony.complete`](/pt/webhooks/call-complete), além de `origin_domain`,
com `from_number` definido como `"web"`.

| Campo | Tipo | Descrição |
|-------|------|-------------|
| `agent_id` | integer \| null | Agente que atendeu a chamada, quando um foi atribuído |
| `agent_name` | string \| null | Agente que atendeu a chamada, quando um foi atribuído |

<Note>
  No webhook legado de URL única, chamadas de teste de microfone do builder
  historicamente são informadas como `telephony.complete` — somente chamadas com `direction:
  "web"` usam o tipo `web.complete` nesse caso. O sistema de endpoints
  mapeia chamadas web e de teste para `web.*`. Cargas úteis históricas podem
  conter os valores legados de `direction`, `widget` ou `mic`.
</Note>

### `web.tool`

O equivalente no canal web de `telephony.tool`. O `data` contém
`origin_domain` em vez de `from_number` / `to_number`.

| Campo | Tipo | Descrição |
|-------|------|-------------|
| `agent_id` | integer \| null | Agente que atendeu a chamada, quando um foi atribuído |
| `agent_name` | string \| null | Agente que atendeu a chamada, quando um foi atribuído |

### `web.turn`

O equivalente no canal web de [`telephony.turn`](#telephony-turn),
abrangendo chamadas do widget web e chamadas de teste de microfone do builder. Tem o mesmo formato
de carga útil, com `origin_domain` em vez de `from_number` / `to_number`.
Assim como `telephony.turn`, exige uma **assinatura explícita** —
nunca é entregue por meio de uma matriz `events` vazia.

| Campo | Tipo | Descrição |
|-------|------|-------------|
| `agent_id` | integer \| null | Agente que atendeu a chamada, quando um foi atribuído |
| `agent_name` | string \| null | Agente que atendeu a chamada, quando um foi atribuído |

### `call.transfer_completed`

Enviado uma vez por chamada com o resultado final de uma
[transferência de chamada](/pt/guides/call-transfers): uma transferência fria ou a ponte
entre pessoas que uma transferência assistida deixa após o agente sair.
Não bloqueia e é entregue apenas a endpoints (nunca ao webhook legado
de URL única). Chega após o `telephony.complete` da chamada:
quando a operadora assume a chamada ou a transferência falha ou, quando
o ThunderPhone faz a ponte da chamada, quando a ponte termina.

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

| Campo | Tipo | Descrição |
|-------|------|-------------|
| `call_id` | integer | A chamada que foi transferida |
| `agent_id` | integer \| null | Agente que atendeu a chamada, quando um foi atribuído |
| `agent_name` | string \| null | Agente que atendeu a chamada, quando um foi atribuído |
| `transfer_outcome` | string | `refer_accepted`: a operadora assumiu a chamada. `bridged`: o ThunderPhone manteve quem liga e o destino conectados, seja porque a operadora recusou uma transferência fria, seja porque o agente de uma transferência assistida saiu. `bridge_unanswered`: a operadora recusou uma transferência fria e o destino não atendeu à chamada feita pelo próprio ThunderPhone. `failed`: a transferência não foi concluída e a chamada terminou |
| `destination` | string \| null | O número para o qual a chamada foi transferida |
| `sip_status` | integer \| null | O status SIP da operadora quando ela recusou a transferência fria: `403` (por exemplo, um tronco Twilio sem transferência de chamada), `405` ou `501`. `null` quando a operadora não a recusou |
| `bridge_kind` | string \| null | Apenas `bridged`: `cold_fallback` (uma transferência fria recusada que o ThunderPhone conectou) ou `warm` (as duas pessoas de uma transferência assistida após a saída do agente) |
| `bridge_seconds` | integer \| null | Apenas `bridged`: o tempo em ponte que o ThunderPhone cobrou, em segundos |
| `bridge_total_cents` | integer \| null | Apenas `bridged`: o custo da ponte em centavos de USD após qualquer crédito de chamada gratuita, cobrado separadamente de `billing_total_cents` da chamada |

Os mesmos valores estão no [objeto de chamada](/api-reference/calls#call-object)
como `transfer_outcome`, `transfer_destination`, `transfer_sip_status`,
`transfer_bridge_kind`, `transfer_bridge_seconds` e
`transfer_bridge_total_cents`. `event_id` é o mesmo em cada entrega
de uma chamada, portanto um relatório repetido nunca produz um segundo evento.

---

## Eventos de SMS

Os eventos de SMS descrevem mensagens enviadas pela conta Twilio ou Telnyx
conectada da organização. O corpo da mensagem é omitido e `to` é ocultado.
Recupere a mensagem no escopo da organização em
[`GET /v1/sms/{message_id}`](/api-reference/sms#retrieve-a-message) quando seu
conteúdo ou destinatário for necessário.

### `sms.sent`

Enviado quando a operadora do cliente aceita uma solicitação de SMS de saída. Isto não
é uma confirmação de entrega no aparelho.

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

Enviado após uma rejeição permanente da operadora, após esgotar as tentativas
transitórias ou quando o resultado é permanentemente desconhecido. `error_code` é um
código estável do ThunderPhone, e `error_message` informa a ação necessária do cliente
quando disponível. `status: "unknown"` significa que a operadora pode ter aceitado o SMS;
reconcilie-o no log da operadora, pois o ThunderPhone não o reenviará
automaticamente.

### `sms.received`

Reservado para suporte a SMS de entrada. Nenhum evento `sms.received` é emitido na
versão atual. A configuração de webhook de entrada da operadora e a verificação de
assinatura serão disponibilizadas separadamente.

---

## Eventos de voz

A criação de voz personalizada é assíncrona. Esses eventos não bloqueantes permitem
reagir a um resultado final em vez de consultar repetidamente o
[endpoint de detalhes do clone](/api-reference/custom-voices#list-and-retrieve-clones).

`voice.ready` e `voice.failed` são entregues apenas a um endpoint de toda a
organização com `events: []`. Eles não podem ser selecionados como filtros explícitos de eventos.

### `voice.ready`

Enviado quando uma voz personalizada conclui o processamento e pode ser atribuída a um
agente.

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

Enviado quando o processamento de uma voz personalizada apresenta uma falha permanente.

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

| Campo | Tipo | Descrição |
|-------|------|-------------|
| `voice.id` | string | ID público da voz personalizada |
| `voice.name` | string | Valor da voz do agente no formato `custom:<public_id>` |
| `voice.display_name` | string | Nome da voz exibido para a organização |
| `voice.language` | string | Código do único idioma do clone |
| `voice.gender` | string | `male`, `female` ou uma string vazia |
| `voice.status` | string | `ready` para `voice.ready`; `failed` para `voice.failed` |
| `voice.failure_reason` | string | Vazio em caso de sucesso; detalhes da falha de processamento em caso de falha |
| `voice.created_at`, `voice.updated_at` | timestamp | Carimbos de data e hora ISO 8601 |
| `reason` | string | Detalhes da falha; presente apenas em `voice.failed` |

---

## Eventos de qualidade

### `call.graded`

Enviado sempre que uma [execução de avaliação por IA](/api-reference/calls#ai-call-grading)
é concluída para uma chamada. Não bloqueante.

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

| Campo | Tipo | Descrição |
|-------|------|-------------|
| `agent_id` | inteiro \| nulo | Agente que atendeu a chamada, quando um foi atribuído |
| `agent_name` | string \| nulo | Agente que atendeu a chamada, quando um foi atribuído |
| `grade.id` | inteiro | ID da avaliação |
| `grade.score` | inteiro \| nulo | 0–100 |
| `grade.call_outcome` | string | `success`, `failure`, `unknown` ou `no_conversation` |
| `grade.summary` | string | Resumo de um parágrafo |
| `grade.detected_issues` | array | Strings de problemas encontrados pelo avaliador |
| `grade.status` | string | Sempre `completed` — apenas execuções concluídas emitem |
| `grade.grader_model` | string | Qual avaliador produziu o resultado (por exemplo, `heuristic-v1`) |
| `grade.graded_at`, `grade.created_at` | timestamp | |
| `report` | objeto \| nulo | O [relatório da chamada](/api-reference/calls#call-report) voltado ao cliente: rótulo do resultado, indicador e motivo de necessidade de atenção, quem liga, resumo de uma linha, experiência de quem liga. Em uma avaliação heurística inicial, é `null` ou um relatório `pending` cujos campos são marcadores de posição; o evento da avaliação completa contém o concluído |

<Note>
  Uma chamada pode ser avaliada mais de uma vez — uma avaliação heurística rápida
  geralmente é seguida por uma avaliação completa do modelo assim que a gravação
  estiver disponível, e reavaliações manuais são possíveis. Cada execução concluída
  emite seu próprio evento `call.graded`; considere o `graded_at` mais recente como
  a fonte confiável.
</Note>

### `call.data_extracted`

Enviado sempre que a extração de dados estruturados é concluída com êxito, incluindo
uma nova tentativa tardia após `telephony.complete` / `web.complete` ou uma nova execução
manual por meio de
[`POST /v1/calls/{call_id}/extract`](/api-reference/calls#run-data-extraction).
Não bloqueante.

Em um modo de extração bloqueante, o evento de conclusão normalmente não espera mais
do que o orçamento de extração de 75 segundos. Se o processo de trabalho da extração
for perdido, o processo de finalização de produção (a cada cinco minutos) libera uma
conclusão cujo `blocking_deadline_at` expirou antes de iniciar outra tentativa de
extração. Um sucesso posterior é entregue separadamente por meio deste evento.

<Warning>
  Os valores extraídos são a interpretação do modelo sobre a conversa. Cada valor
  não nulo inclui a citação, a função de quem falou e o índice do turno nos quais
  se baseou, além de uma sinalização de verificação no nível da execução. Verifique
  o resultado antes de tomar decisões que envolvam dinheiro, identidade ou acesso.
</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"
}
```

| Campo | Tipo | Descrição |
|-------|------|-------------|
| `agent_id` | integer \| null | Agente que atendeu a chamada, quando um foi atribuído |
| `agent_name` | string \| null | Agente que atendeu a chamada, quando um foi atribuído |
| `summary` | string \| null | O [resumo da chamada](/pt/webhooks/call-complete) concluído quando o agente tem **Gerar um resumo da chamada** ativado, para que um evento de extração tardio também entregue um resumo que não foi incluído na janela de conclusão; caso contrário, `null`. Agentes com resumo, mas sem campos de extração, nunca emitem este evento: leia um resumo tardio em `GET /v1/calls/{call_id}` |
| `extracted_data.status` | string | Sempre `completed` para este evento |
| `extracted_data.fields` | object | Valores identificados pelas chaves de campo de extração configuradas; valores indisponíveis são `null` |
| `extracted_data.evidence` | object | Evidências identificadas pelo campo de extração. Um valor não nulo tem a citação exata verificada estruturalmente, com no máximo 1.000 caracteres, `speaker_role` (`caller` ou `agent`) e `turn_index`; citações mais longas retornadas pelo modelo são rejeitadas em vez de truncadas, e a evidência é `null` sempre que seu campo for `null` |
| `extracted_data.verification` | string | `verified` somente quando a etapa independente de evidências retornou exatamente um veredito válido para cada campo candidato. `unavailable` significa que a etapa falhou, expirou, não teve orçamento suficiente ou retornou saída malformada ou parcial. Uma etapa totalmente indisponível preserva valores estruturalmente fundamentados para revisão do cliente. Para saída parcial, vereditos válidos são aplicados e cada candidato sem exatamente um veredito válido é definido como nulo |
| `extracted_data.field_reasons` | object | Motivos identificados pelos campos que foram definidos como nulos pela fundamentação estrutural ou pelo verificador independente |
| `extracted_data.schema_version` | string | Hash do schema exato de campos usado para esta extração |
| `extracted_at` | timestamp | Horário de conclusão no formato ISO 8601 |
| `model` | string | Modelo usado para a extração |

### `campaign.completed`

Enviado uma vez quando uma campanha passa de `running` para `completed`, seja porque
a programação terminou ou porque todos os contatos chegaram a estados terminais. Novas
tentativas do executor não emitem outro evento. Este evento de ciclo de vida no nível da
organização é entregue apenas a endpoints com escopo de organização, não a endpoints com
escopo de agente. Não bloqueante.

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

As quatro contagens de resultado são mutuamente exclusivas e somam `contacts_total`:
`completed` contém contatos bem-sucedidos; `no_answer` contém contatos com falha/esgotados
em estado terminal cujo resultado final foi sem resposta; `failed` contém todos os demais
contatos com falha/esgotados em estado terminal; e `remaining` contém contatos pendentes,
agendados ou em chamada no momento. Um contato aguardando uma nova tentativa é
`remaining`, mesmo quando sua tentativa mais recente não teve resposta. Chamadas em
andamento são reconciliadas antes do snapshot de conclusão emitido uma única vez.
`started_at` é o início configurado da campanha ou o horário de criação da campanha
quando nenhum início foi configurado.

### `issue.reported`

Enviado quando um [relatório de problema](/api-reference/issue-reports) é criado —
seja enviado por um usuário no painel (`source: "user"`) ou automaticamente pela
avaliação de chamadas (`source: "system"`). Não bloqueante.

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

| Campo | Tipo | Descrição |
|-------|------|-------------|
| `agent_id` | integer \| null | Agente que atendeu a chamada, quando um foi atribuído |
| `agent_name` | string \| null | Agente que atendeu a chamada, quando um foi atribuído |
| `issue_report.severity` | string | `critical`, `warning` ou `info` |
| `issue_report.status` | string | `open` ou `resolved` |
| `issue_report.source` | string | `user` (enviado pelo painel) ou `system` (criado pela avaliação) |

<Note>
  Reavaliar uma chamada recria seus relatórios de problemas gerados pelo sistema,
  o que emite novamente `issue.reported` para os relatórios recriados. Faça a
  desduplicação por `call_id` + `title` se quiser apenas uma notificação para cada
  problema subjacente.
</Note>

### `issue.escalated`

Enviado quando um padrão de problema é enviado ao ThunderPhone para análise da equipe:
após **Reportar ao ThunderPhone**, ou quando Corrigir com IA não consegue confirmar uma
correção no lado do cliente e encaminha o problema automaticamente. Somente endpoints
de toda a organização recebem este evento.

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

| Campo | Tipo | Descrição |
|-------|------|-------------|
| `automatic` | boolean | `true` para um escalonamento automático; `false` para um escalonamento manual |
| `cluster_id` | UUID | Padrão de problema escalonado |
| `escalation_id` | UUID | Registro de escalonamento |
| `status` | string | `open` quando o evento é emitido |

Esta é uma notificação, não o pacote de evidências. Use `cluster_id` para correlacioná-la
ao padrão de problema. Consulte [Reportar ao ThunderPhone](/pt/guides/issues).

---

## Eventos de chamadas de teste

### `test-call.completed`

Enviado quando uma
[execução de chamada de teste](/api-reference/test-calls#test-call-run-object)
atinge um status terminal — `completed` ou `failed`, incluindo execuções
que falharam na inicialização e nunca produziram uma chamada. Não bloqueante. Útil
para integrar execuções de CI em lote aos seus sistemas de chat/notificações.

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

| Campo | Tipo | Descrição |
|-------|------|-------------|
| `agent_id` | integer \| null | Agente que atendeu a chamada, quando um foi atribuído |
| `agent_name` | string \| null | Agente que atendeu a chamada, quando um foi atribuído |
| `test_call_run.target_type` | string | `agent` ou `phone_number` |
| `test_call_run.target_id` | integer | O id do agente ou o id do número de telefone que a execução teve como destino, correspondente a `target_type` |
| `test_call_run.status` | string | `completed` ou `failed` |
| `test_call_run.call_id` | integer \| null | `null` quando a execução falhou antes de uma chamada ser iniciada |
| `test_call_run.error_message` | string | Vazio em caso de sucesso |

---

## Eventos de alerta

### `alert.triggered`

Enviado quando uma [regra de alerta](/pt/guides/alerts) com o canal **Entregar aos
webhooks de desenvolvedor** ativado ultrapassa seu limite.
Não bloqueante. Uma regra é acionada uma vez e então respeita seu período de espera, de modo que uma
violação contínua produz um evento por janela de período de espera.

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

| Campo | Tipo | Descrição |
|-------|------|-------------|
| `event_id` (em `data`) | UUID | O id de **disparo** do alerta — distinto do `event_id` de entrega do envelope |
| `rule_id`, `rule_name` | UUID, string | A regra que foi acionada |
| `metric` | string | `success_rate`, `failure_rate`, `avg_score`, `call_volume` ou `suite_regression` |
| `comparator` | string | `lt`, `lte`, `gt` ou `gte` |
| `metric_value` | number | O valor da métrica na janela quando a regra foi acionada |
| `threshold` | number | O limite configurado |
| `window_hours` | integer | Janela de avaliação retroativa |
| `fired_at` | timestamp | |

Consulte o [guia de Alertas](/pt/guides/alerts) para criar regras, métricas,
períodos de espera e os canais de e-mail / Slack.

---

## Eventos de migração

### `migration.call.complete`

Enviado quando uma chamada realizada por meio de
[`POST /v1/migrations/{id}/calls`](/api-reference/migration-calls) termina,
independentemente de qual plataforma a tenha realizado. Não bloqueante. Chega em até cerca de 5 minutos
após o término da chamada. `data` contém todos os campos de
[`telephony.complete`](/pt/webhooks/call-complete), além de um bloco `migration`. Uma
chamada realizada pelo ThunderPhone também envia `telephony.complete` normalmente, com o
mesmo `call_id`. Uma chamada na outra plataforma que não tenha terminado após 2
horas, ou cuja migração tenha terminado ou perdido sua chave antes disso, é enviada com
`status: "unknown"` e sem transcrição.

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

| Campo | Tipo | Descrição |
|-------|------|-------------|
| `migration.id` | UUID | A migração |
| `migration.routing_id` | UUID | A chamada roteada, conforme retornada quando você a realizou |
| `migration.arm` | string | `ours` (o ThunderPhone realizou a chamada) ou `vendor` (a outra plataforma realizou) |
| `migration.vendor` | string | `retell`, `vapi`, `elevenlabs` ou `bland` |
| `migration.vendor_call_id` | string \| null | O ID da chamada na outra plataforma; `null` para `ours` |
| `migration.metadata` | object | Os `metadata` enviados por você ao realizar a chamada |
| `migration.vendor_cost_usd` | string \| null | O custo da chamada informado pela outra plataforma, quando informado |
| `call_id` | integer \| null | O ID da chamada no ThunderPhone; `null` para `vendor` |
| `status` | string | Para `vendor`: `completed` quando a pessoa chamada falou, `failed` quando não falou, `unknown` conforme descrito acima. Para `ours`: como em `telephony.complete` |

Para uma chamada `vendor`, o ThunderPhone não tem dados de cobrança ou extração:
`billable_minutes`, `billing_total_cents` e `extracted_data` são `null`,
`product` e `voice` estão vazios, `recording_mode` é `vendor`, e
`recording_url` é o link da outra plataforma, quando ela forneceu um.

### `migration.rollback`

Enviado quando a mudança gradual de uma migração move todas as chamadas de volta para a outra
plataforma automaticamente: 3 chamadas não conseguiram se conectar ao ThunderPhone em 15
minutos, 2 chamadas enviadas ao ThunderPhone terminaram antes de o agente atender, ou
a taxa de resultado de tarefa do ThunderPhone ficou abaixo da outra plataforma por mais do que
a diferença configurada. Sem bloqueio, uma vez por reversão. Depois disso, a participação do ThunderPhone
é de 0% e a migração fica pausada até que alguém a retome na aba Migração
do agente. A carga não contém números de telefone, transcrições nem IDs de chamadas.

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

| Campo | Tipo | Descrição |
|-------|------|-------------|
| `migration_id` | UUID | A migração |
| `vendor` | string | `retell`, `vapi`, `elevenlabs` ou `bland` |
| `reason` | string | `ours_failed_burst` (3 conexões com falha em 15 minutos), `dropped_calls` (2 chamadas terminaram antes de o agente atender, em 30 minutos) ou `rate_gap` (diferença na taxa de resultado de tarefa em pelo menos `rollback_min_calls` chamadas avaliadas de cada lado) |
| `previous_percent` | integer | Participação do ThunderPhone nas chamadas antes da reversão |
| `ours_percent` | integer | Sempre `0` |
| `step` | integer \| null | A etapa do cronograma em que estava (com base em 0) |
| `ours` / `theirs` | object \| null | Chamadas avaliadas na etapa atual e sua taxa de sucesso; `theirs` pode corresponder aos últimos 30 dias quando a etapa tem poucas chamadas. `null` quando não houve nenhuma |
| `ours_failed` | integer | Conexões com falha contabilizadas nos últimos 15 minutos |
| `dropped` | integer | Chamadas contabilizadas como encerradas nos últimos 30 minutos |
| `rolled_back_at` | timestamp | |

---

## Relacionados

<CardGroup cols={2}>
  <Card title="telephony.incoming / web.incoming" icon="phone" href="/pt/webhooks/call-incoming">
    A carga útil bloqueante de chamada recebida à qual você deve responder.
  </Card>
  <Card title="telephony.complete / web.complete" icon="phone-slash" href="/pt/webhooks/call-complete">
    Transcrição e métricas pós-chamada.
  </Card>
  <Card title="Endpoints de webhook" icon="bolt" href="/pt/webhooks/endpoints">
    Inscreva uma URL em um subconjunto destes eventos.
  </Card>
  <Card title="Ferramentas de função" icon="screwdriver-wrench" href="/pt/tools/overview">
    Como os eventos `telephony.tool` / `web.tool` são gerados.
  </Card>
</CardGroup>
