---
title: "Endpoints de webhook"
description: "Gerencie várias URLs de webhook com segredos por endpoint e filtros de eventos."
---

O sistema de webhooks baseado em endpoints permite registrar **vários**
destinos por organização, cada um com seu próprio segredo, seu próprio
status e sua própria assinatura de um subconjunto de tipos de evento. Este é
o modelo recomendado para todas as novas integrações.

Compare com o [webhook legado de URL única](/api-reference/organizations#legacy-single-url-webhook),
que é mantido para compatibilidade com versões anteriores, mas oferece suporte
a apenas uma URL por organização.

## Endpoints

| Método | Caminho | Função necessária | Descrição |
|--------|------|---------------|-------------|
| `GET` | `/v1/developer/webhook-endpoints` | `admin+` | Listar endpoints |
| `POST` | `/v1/developer/webhook-endpoints` | `admin+` | Criar um endpoint |
| `PATCH` | `/v1/developer/webhook-endpoints/{endpoint_id}` | `admin+` | Atualizar rótulo / URL / eventos / status |
| `DELETE` | `/v1/developer/webhook-endpoints/{endpoint_id}` | `admin+` | Excluir um endpoint |
| `POST` | `/v1/developer/webhook-endpoints/{endpoint_id}/rotate-secret` | `admin+` | Substituir o segredo de assinatura |
| `POST` | `/v1/developer/webhook-endpoints/{endpoint_id}/test` | `admin+` | Enviar uma entrega de teste assinada |
| `GET` | `/v1/developer/webhook-deliveries` | `admin+` | Inspecionar resultados recentes de entrega de endpoints e legados |

## Objeto de endpoint

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

| Campo | Tipo | Descrição |
|-------|------|-------------|
| `id` | UUID | ID do endpoint |
| `label` | string | Nome de exibição, 1–120 caracteres |
| `url` | string | URL HTTPS; `http://localhost` permitido para desenvolvimento |
| `events` | array de string | Tipos de evento inscritos (consulte [valores válidos](#valid-event-types)). Uma matriz vazia inscreve em todos os eventos, exceto nos eventos explícitos por turno (`telephony.turn` / `web.turn`) |
| `status` | string | `active`, `disabled` (pausado manualmente) ou `failing` (definido automaticamente quando uma entrega esgota sua programação de tentativas de 24 h sem um único 2xx) |
| `agent_id` | integer \| null | Agente ao qual este endpoint é limitado; `null` significa toda a organização |
| `agent_name` | string \| null | Nome do agente limitado ou `null` para um endpoint de toda a organização |
| `secret_hint` | string | Primeiros 4 e últimos 4 caracteres do segredo de assinatura com reticências (`a1b2…9f0e`) — suficientes para referenciar o segredo salvo localmente sem expor o valor completo |
| `paused_at` | timestamp \| null | Quando o ThunderPhone definiu o endpoint como `failing`. `null` enquanto ele estiver `active` ou `disabled` |
| `pause_last_error` | string | O último erro de entrega quando o endpoint foi pausado, por exemplo, `HTTP 503: Service Unavailable`. Vazio, a menos que esteja `failing` |
| `pause_undelivered_count` | integer \| null | Eventos não entregues desde a última entrega bem-sucedida do endpoint, contados quando ele foi pausado |
| `created_at`, `updated_at` | timestamp | |

<Note>
  O `secret` completo do endpoint é retornado **uma única vez** na criação e
  nunca mais. Armazene-o com segurança — se o perder,
  [faça a rotação](#rotate-the-signing-secret) para obter um novo.
</Note>

### Tipos de evento válidos

`events` é validado em relação a este conjunto exato — valores fora da lista
retornam `400`. Consulte o [catálogo de eventos](/pt/webhooks/events) para ver o
formato do payload de cada tipo.

- `telephony.incoming`, `telephony.complete`, `telephony.tool`, `telephony.turn`
- `web.incoming`, `web.complete`, `web.tool`, `web.turn`
- `sms.sent`, `sms.failed`
- `sms.received` (reservado; ainda não emitido)
- `call.graded`, `call.data_extracted`, `call.transfer_completed`
- `campaign.completed`
- `issue.reported`, `issue.escalated`
- `test-call.completed`
- `alert.triggered`

`issue.escalated` não tem contexto de agente e é entregue apenas a
endpoints de toda a organização.

`voice.ready` e `voice.failed` não podem ser selecionados explicitamente. Para
recebê-los, crie um endpoint de toda a organização com `events: []`. Uma lista
de eventos vazia recebe todos os eventos compatíveis, exceto `telephony.turn` e
`web.turn`, que devem ser selecionados explicitamente.

### Status dos endpoints

- `active` — as entregas fluem normalmente.
- `disabled` — pausado manualmente via `PATCH`. Nenhuma solicitação é enviada. Nunca
  alteramos o status de um endpoint `disabled`; reativá-lo para
  `active` é sempre decisão sua.
- `failing` — definido automaticamente quando uma entrega ao endpoint esgota
  todo o cronograma de tentativas (8 tentativas em 24 horas) sem
  receber um 2xx. Um endpoint com falha não recebe mais tráfego.
  Enviamos um e-mail aos proprietários e administradores da sua organização quando isso acontece, e
  o dashboard mostra o endpoint pausado com um botão Reativar.
  Quando o endpoint for corrigido, faça `PATCH` no status de volta para `active`;
  as entregas cujo cronograma de tentativas ainda não terminou serão retomadas de onde
  pararam.

---

## Listar endpoints

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

Retorna um array de [objetos de endpoint](#endpoint-object).
Passe `?agent_id=42` para retornar apenas endpoints vinculados a esse agente.

### Endpoints vinculados a agentes

Endpoints de toda a organização recebem todos os eventos correspondentes. Um endpoint com
`agent_id` recebe apenas eventos correspondentes de chamadas atendidas por esse agente;
eventos sem contexto de agente, como `alert.triggered`, nunca chegam até ele. Você
também pode criar e gerenciar esses endpoints na seção
**Webhooks** do construtor de agentes.

---

## Crie um endpoint

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

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

### Campos da solicitação

| Campo | Tipo | Obrigatório | Descrição |
|-------|------|----------|-------------|
| `label` | string | sim | 1–120 caracteres |
| `url` | string | sim | URL HTTPS (`http` permitido apenas para `localhost` / `127.0.0.1`) |
| `events` | array | não | Vazio/omitido assina todos os eventos, exceto `telephony.turn` / `web.turn`, que exigem uma assinatura explícita. Use os valores listados em [Tipos de evento válidos](#valid-event-types); duplicatas são removidas |
| `agent_id` | integer \| null | não | Limite a entrega a um agente nesta organização; omita ou use `null` para um endpoint de toda a organização |

Retorna `201 Created` com o [objeto Endpoint](#endpoint-object), além de
um campo adicional `secret` no nível superior contendo a chave bruta de assinatura — uma
string hexadecimal de 48 caracteres:

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

<Warning>
  `secret` é retornado **somente na criação**. As respostas `GET` subsequentes
  incluem apenas `secret_hint`. Copie o valor completo para seu gerenciador de segredos
  antes de descartar a resposta.
</Warning>

---

## Atualize um endpoint

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

| Campo | Tipo | Descrição |
|-------|------|-------------|
| `label` | string | |
| `url` | string | |
| `events` | array | |
| `status` | string | `active` ou `disabled`. Defina como `active` para reativar um endpoint que o servidor marcou como `failing` |
| `agent_id` | integer \| null | Defina um ID de agente para limitar o endpoint ou `null` para disponibilizá-lo para toda a organização |

Retorna `200 OK` com o [objeto Endpoint](#endpoint-object) atualizado.

---

## Rotacione o segredo de assinatura

Substitua o segredo de assinatura de um endpoint, por exemplo, quando ele foi perdido ou
pode ter vazado. Para um endpoint associado a um agente, você também pode usar o
dashboard: abra a seção **Webhooks** do agente e escolha
**Regenerar segredo** no endpoint. Os endpoints de toda a organização são
rotacionados pela API.

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

| Campo | Tipo | Obrigatório | Descrição |
|-------|------|----------|-------------|
| `include_copies` | booleano | não | O padrão é `true`. Também fornece o novo segredo aos outros endpoints da sua organização que têm a mesma URL e o mesmo segredo atual, como cópias deste endpoint em outros agentes, para que um único receptor continue verificando com um único segredo |

Retorna `200 OK`:

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

| Campo | Tipo | Descrição |
|-------|------|-------------|
| `endpoint` | objeto | O [objeto Endpoint](#endpoint-object) com seu novo `secret_hint` |
| `secret` | string | O novo segredo de assinatura. Retornado somente nesta resposta |
| `rotated_endpoint_ids` | array de UUID | Todos os endpoints que agora usam o novo segredo |

<Warning>
  O segredo antigo deixa de ser usado imediatamente: a próxima entrega,
  incluindo novas tentativas, é assinada com o novo segredo. Até que seu receptor tenha
  o novo segredo, as entregas falham na verificação de assinatura; se ele responder
  a elas com um status diferente de 2xx, elas serão tentadas novamente na programação
  normal de 24 h. Portanto, atualize o receptor imediatamente. Se seu receptor for implantado
  em etapas, faça com que ele aceite ambos os segredos durante a implantação — os
  auxiliares de verificação do SDK aceitam uma lista de segredos (consulte
  [Verificar assinaturas de webhook](/pt/guides/verify-webhook-signatures)).
</Warning>

---

## Envie uma entrega de teste

Envie um evento `webhook.test` sintético para um endpoint usando o pipeline normal de
entrega, incluindo serialização JSON canônica, ambos os
cabeçalhos de assinatura, registro de entrega e controle de novas tentativas.
O teste tem como destino o endpoint selecionado, independentemente do filtro `events` dele.

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

O endpoint recebe um envelope como este:

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

A API retorna `200 OK` após a primeira tentativa, mesmo que o destino
retorne um erro. Inspecione `success`, `status`, `response_code` e `error`
para verificar o resultado da entrega:

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

`webhook.test` é sintético e não pode ser adicionado à assinatura de `events`
de um endpoint. Se a primeira tentativa falhar, o ThunderPhone tenta novamente uma vez cerca de
um minuto depois e então para; a entrega passa a mostrar `status: "failed"`
em [Depurar entregas](#debug-deliveries). Uma entrega de teste nunca marca
o endpoint como `failing`.

Para configurar um gatilho com base no formato de um evento real, informe um
`event_type` opcional. A entrega continua sintética e contém `"sample": true`;
amostras relacionadas a chamadas usam `call_id: 0` e `agent_id: 0`.

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

`event_type` aceita qualquer valor em [Tipos de evento válidos](#valid-event-types).
Omiti-lo preserva o comportamento genérico de `webhook.test`.

---

## Exclua um endpoint

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

Retorna `204 No Content`. A entrega para a URL é interrompida imediatamente;
novas tentativas em andamento são abandonadas.

---

## Depurar entregas

Antes de concluir que um webhook não foi enviado, inspecione
[`GET /v1/developer/webhook-deliveries`](/api-reference/webhook-deliveries).
Ele mostra tentativas recentes de ambos os sistemas de webhook, incluindo o ID da chamada,
a origem da URL, o status HTTP, a contagem de tentativas, a categoria de falha permitida e o horário da próxima
tentativa. Ele nunca retorna o payload do evento, a transcrição, o texto de erro armazenado,
o corpo da resposta ou o caminho da URL.

Você também pode ver o mesmo histórico recente em **Agentes → selecione um agente → Webhooks →
Entregas recentes**. As linhas mostram o rótulo do endpoint e a origem da URL usada pela tentativa mais
recente. Este é um estado operacional, e não um registro de auditoria imutável: excluir um endpoint
também exclui suas linhas de entrega.

Para um `404` do n8n, primeiro confirme que o fluxo de trabalho está ativo, aceita `POST` e usa
a URL de webhook de produção, em vez da URL de teste. Um `401` ou `403` indica
autenticação ou validação de assinatura; timeouts indicam latência
ou disponibilidade do destino; erros de TLS indicam a cadeia de certificados, o nome do host ou a expiração.

---

## Relacionados

<CardGroup cols={2}>
  <Card title="Catálogo de eventos" icon="list" href="/pt/webhooks/events">
    A lista completa de valores de `events` que você pode assinar.
  </Card>
  <Card title="Visão geral de webhooks" icon="bolt" href="/pt/webhooks/overview">
    Verificação de assinatura e semântica de entrega.
  </Card>
</CardGroup>
