
# Webhooks

Webhooks permitem que o <span data-t="appName">Your AI Connector</span> notifique automaticamente suas outras ferramentas de negócios sempre que algo importante acontece — um novo contato sendo criado, um agendamento sendo marcado, uma mensagem sendo recebida. Em vez de verificar manualmente por atualizações, seus sistemas conectados recebem uma notificação instantânea no momento em que algo acontece.


---

## O que são Webhooks?

Pense em um webhook como uma mensagem de texto automática entre dois aplicativos. Quando algo acontece no <span data-t="appName">Your AI Connector</span> (como um novo contato se inscrevendo), a plataforma envia instantaneamente uma notificação para outro sistema de sua escolha. Você fornece um endereço da web (chamado de "URL de webhook") para onde essas notificações devem ser enviadas — isso geralmente é fornecido pelo seu CRM, plataforma de automação ou desenvolvedor.

> **Webhooks enviam dados apenas PARA FORA do <span data-t="appName">Your AI Connector</span>.** Um webhook é uma via de mão única *do* <span data-t="appName">Your AI Connector</span> *para* suas outras ferramentas. **Não existe uma URL de webhook que envie leads, contatos ou mensagens PARA DENTRO da plataforma.** Para inserir um novo lead — a partir de um formulário de site, seu CRM ou GoHighLevel — seu sistema faz uma **chamada de API** em vez disso. Veja [Acesso à API](api-access.md) (a operação *Criar um Contato*) e [Funis](funnels.md). A única coisa que você precisa para a direção de entrada é sua **chave de API**, que fica em sua própria seção — veja [Acesso à API](api-access.md#generating-your-api-key). A página de **Webhooks** descrita aqui é exclusivamente para a direção de saída.

::: note
**Nota:** Configurar webhooks envolve alguma configuração técnica. Se você não se sentir confortável com isso, compartilhe esta página com seu desenvolvedor ou use uma plataforma de automação como Zapier, Make ou Pabbly, que fornecem URLs de webhook sem a necessidade de programação.
:::


Usos comuns incluem:

- Sincronizar novos contatos com seu CRM.
- Acionar um fluxo de trabalho no Zapier, Make ou Pabbly quando uma tag é aplicada.
- Notificar sua equipe no Slack quando um humano é alertado.
- Atualizar seu sistema de calendário quando um compromisso é agendado.
- Registrar resumos de conversas em seu banco de dados.

---

## Configurando Webhooks

1. Na barra lateral esquerda, clique em **Configurações** (ícone de engrenagem).
2. Na barra lateral de Configurações, sob o grupo **Integrações**, clique em **Webhooks**.


Em uma conta sem webhooks configurados ainda, a página aparece assim:


3. Clique em **New webhook**, no canto superior direito. Um formulário será aberto na própria página:


4. Preencha:
   - **URL do Endpoint** — o endereço da web para o qual o <span data-t="appName">Your AI Connector</span> enviará notificações de eventos. Você obtém isso do seu sistema externo (CRM, plataforma de automação ou servidor personalizado).
   - **Nome** — um rótulo que você reconhecerá mais tarde (por exemplo, "Alertas do Slack" ou "Sincronização com CRM"). Apenas para sua referência.

> **Sua URL de webhook deve ser um endereço `https://` publicamente acessível.** Endereços `http://` simples, `localhost` ou endereços de rede privada e endereços internos da plataforma são rejeitados ao salvar. Para testar a partir da sua própria máquina, use um túnel público (webhook.site ou ngrok) em vez de localhost.

5. Em **Eventos**, clique nos eventos que você deseja que este webhook receba — todos os 22 estão listados em [Os 22 Eventos de Webhook](#the-22-webhook-events).
6. *(Opcional)* Ative **Tentar novamente entregas com falha** se você quiser que o <span data-t="appName">Your AI Connector</span> continue tentando em caso de falha temporária — veja [Tentando Novamente Entregas com Falha](#retrying-failed-deliveries).
7. Clique em **Criar webhook**. Ele aparecerá na lista abaixo do formulário, e você pode clicar em **Testar** na linha dele a qualquer momento para disparar um payload de exemplo para o seu endpoint.

> **Permissão necessária.** Adicionar, editar ou testar webhooks requer a permissão de "editar" em Integrações (membros da equipe com visualização apenas veem um aviso de leitura apenas em vez do formulário).

> **Assinar um webhook** requer que ele já esteja salvo primeiro — abra a linha de um webhook existente para editá-lo, e o painel **Segredo de assinatura** aparecerá na parte inferior do formulário de edição. Um rascunho novo e não salvo ainda não possui opção de assinatura — veja [Payloads Assinados](#signed-payloads-verifying-a-webhook-really-came-from-us) abaixo.

---

## Um Webhook para Todas as Suas Contas de Cliente (Agências)

Se você gerencia uma agência, não precisa recriar o mesmo webhook em cada conta de cliente. Na conta da agência, o formulário de webhook possui uma opção de alternância extra: **Also fire for all client accounts**. Ative-a e este webhook também receberá eventos que ocorrem em todas as contas de cliente sob sua agência — um endpoint, toda a agência.

Como ele se comporta:

- **O bloco `user` informa a qual cliente um evento pertence.** Cada notificação já contém um bloco `user` identificando a conta na qual o evento ocorreu, para que sua automação possa rotear por cliente.
- **As configurações do seu webhook se aplicam a todos os lugares.** Os eventos que você selecionou, o segredo de assinatura e a configuração de nova tentativa também são usados para entregas em contas de cliente.
- **Sem entregas duplicadas.** Se uma conta de cliente tiver seu próprio webhook apontando para a mesma URL, ele será usado para os eventos daquela conta — o mesmo evento nunca chega duas vezes ao mesmo endpoint.
- **Os clientes não o veem.** O webhook não aparece na página de Webhooks da própria conta do cliente, e os clientes não podem desativá-lo — é você quem gerencia.
- **A confiabilidade é rastreada por conta de cliente.** Se o seu endpoint continuar falhando, ele será desativado automaticamente para a conta cujas entregas falharam (veja [Confiabilidade de Webhook](#webhook-reliability)), e não para toda a agência de uma vez.

A opção de alternância aparece apenas em contas de agência. A configuração via API também é suportada — veja o campo `apply_to_sub_accounts` na [API de Webhooks](../api/webhooks.md#one-subscription-for-all-client-accounts-agencies).

---

## Eventos de Gatilho Disponíveis

Você pode ativar ou desativar cada um dos 22 eventos de webhook de forma independente. Quando um evento é disparado, o <span data-t="appName">Your AI Connector</span> envia uma notificação para a sua URL de webhook com os dados relevantes. Cada evento, o que ele significa e o código `event` que ele coloca no payload estão listados juntos em [Os 22 Eventos de Webhook](#the-22-webhook-events) mais abaixo nesta página.

> **Bom saber:** **Tarefa Criada**, **Tarefa Atualizada** e **Tarefa Concluída** são totalmente selecionáveis e salvam corretamente. **Resumo Diário Criado** também é uma adição recente. Veja [Webhook de Tarefa Concluída](#task-completed-webhook) abaixo para o formato desse payload.

---

## Gatilhos de Webhook Baseados em Tags

O `subscribed_to_tags` não limita os eventos de um webhook a uma tag. Ele apenas restringe quais tags produzem uma notificação de resumo de conversa. Para receber uma solicitação quando uma tag específica for aplicada, defina uma URL de webhook nessa tag na aba **Tags** do agente (ou campanha).

O formulário de webhook em si não possui um seletor de tags, nem ao criar um novo webhook nem ao editar um, portanto, o `subscribed_to_tags` só pode ser lido ou alterado através da [API de Webhooks](../api/webhooks.md), ou solicitando ao suporte.

> **Bom saber:** editar um webhook existente que possui uma lista de `subscribed_to_tags` (renomeá-lo, alterar seus eventos, alternar tentativas) não limpa mais essa lista — como o formulário não tem um seletor de tags para enviar de volta, salvar a partir desta página agora deixa a lista existente intacta. (Isso era um bug real antes de **21 de julho de 2026**: salvar a partir do formulário de webhook costumava apagar a lista porque ele sempre enviava uma lista de tags vazia. Se um webhook perdeu sua lista de `subscribed_to_tags` antes dessa data, ele precisará ser reconfigurado através da API.)

### Gerar Resumo para Contatos Marcados

Onde um webhook possui uma lista de `subscribed_to_tags`, você pode ativar **Gerar Resumo**. Quando ativado, o <span data-t="appName">Your AI Connector</span> gera automaticamente um resumo da conversa para o contato quando uma dessas tags é aplicada e o inclui nos dados do webhook — contexto completo sem uma solicitação separada.

---

## Testando seu Webhook

1. Abra **Configurações → Integrações → Webhooks**.
2. Na linha do seu webhook, clique em **Testar**.
3. Verifique seu sistema externo para confirmar que ele recebeu os dados de teste.
4. Revise o formato dos dados para garantir que seu sistema possa analisá-los corretamente.

Para um teste completo de ponta a ponta, envie uma mensagem que dispararia um dos seus eventos configurados (uma transmissão ou uma mensagem recebida em um canal conectado) e verifique se o webhook é disparado com os dados reais.

::: tip
**Dica:** Use uma ferramenta como [webhook.site](https://webhook.site) ou [RequestBin](https://requestbin.com) durante o desenvolvimento para inspecionar os dados brutos do webhook antes de conectar seu sistema de produção.
:::


### O que conta como uma entrega bem-sucedida

Quer você clique em **Testar** ou o evento seja disparado de verdade, enviamos a mesma coisa:

- Uma solicitação **POST** (nunca GET), com o corpo como JSON e `Content-Type: application/json`.
- Os cabeçalhos listados em [Payloads Assinados](#signed-payloads-verifying-a-webhook-really-came-from-us). Os cabeçalhos de assinatura só são incluídos depois que você define um segredo de assinatura.

Consideramos a entrega bem-sucedida quando:

- Seu endpoint responde com **qualquer status 2xx** (200, 201, 204 — todos são aceitos).
- Ele responde **dentro de 30 segundos**.

Algumas coisas que surpreendem as pessoas:

- **O corpo da resposta é ignorado.** Você não precisa retornar nenhum JSON específico. Um 200 vazio é suficiente.
- **Redirecionamentos contam como falha.** Nós não os seguimos, portanto, um 301 ou 302 (incluindo um redirecionamento de barra final ou de http para https) é registrado como uma entrega falha. Salve a URL final, não uma que redirecione.
- **Strings de consulta (query strings) são totalmente suportadas.** `https://your-app.com/hook?token=abc123` é enviada exatamente como você a salvou, portanto, colocar um token na string de consulta funciona tão bem quanto colocá-lo no caminho.
- **Sua URL deve ser `https://` e publicamente acessível.** Endereços que pertencem à própria infraestrutura do <span data-t="appName">Your AI Connector</span> são rejeitados, mas seus próprios endpoints no Google Cloud Functions, Cloud Run, App Engine, Firebase Hosting ou qualquer outro lugar são aceitos.
- **Um firewall ou camada de proteção contra bots na frente do seu endpoint pode nos bloquear.** O caso mais comum é o Cloudflare: se sua zona estiver com o "Bot Fight Mode" ou um desafio gerenciado ativado, nossa solicitação recebe uma página de desafio "Just a moment..." com um 403 em vez de chegar ao seu servidor — e uma solicitação servidor-para-servidor nunca pode passar por um desafio de navegador, portanto, tanto o botão **Testar** quanto os eventos reais falham da mesma maneira. O botão Testar informará quando isso estiver acontecendo ("O Cloudflare está exibindo um desafio de bot para nossa solicitação"). Corrija isso no Cloudflare com uma regra de Segurança / WAF que ignore desafios para o caminho do seu webhook (ou para o agente de usuário `Webhook-Delivery/1.0`) e, em seguida, clique em **Testar** novamente.
- **Se o seu firewall precisar de uma lista de permissões de IP** (por exemplo, no plano gratuito do Cloudflare, onde o "Bot Fight Mode" simples não pode ser ignorado por uma regra WAF, mas uma Regra de Acesso de IP definida como "Permitir" é executada antes dele), podemos ajudar: cada entrega, seja pelo botão **Testar** ou por um evento ao vivo, é enviada de um endereço IPv4 fixo (sem intervalos, sem IPv6, sem rotação). Entre em contato com o suporte e forneceremos o endereço para adicionar à lista de permissões. Mantenha a [verificação de assinatura](#signed-payloads-verifying-a-webhook-really-came-from-us) como sua verificação de confiança real, já que ela valida cada payload independentemente de onde ele veio.
- **O resultado do Teste informa exatamente o que seu endpoint respondeu.** Um teste com falha agora mostra o motivo real (o status HTTP que seu endpoint retornou, um tempo limite ou que não conseguimos acessar o endereço) em vez de um erro genérico, e um teste em um webhook salvo é enviado assinado quando a assinatura está ativada, exatamente como um evento ao vivo.

### Usando n8n, Make ou Zapier ("Test URL" vs "Production URL")

Plataformas de automação geralmente fornecem dois endereços de webhook diferentes, e isso confunde as pessoas:

- Uma **URL de Teste** (no n8n ela contém `/webhook-test/`). Ela só recebe dados enquanto você está monitorando ativamente a tela e acabou de clicar em **Listen for test event** (ou **Test workflow**). Ela captura um único evento e para de ouvir — portanto, clicar em **Testar** no <span data-t="appName">Your AI Connector</span> várias vezes seguidas captura apenas o primeiro, e somente se a janela de escuta estiver ativa naquele exato momento. Para testar: clique em **Listen for test event** no n8n primeiro, depois volte ao <span data-t="appName">Your AI Connector</span> e clique em **Testar** uma vez.
- Uma **URL de Produção** (no n8n ela contém `/webhook/`, sem `-test`). Esta é a que deve ser colada no <span data-t="appName">Your AI Connector</span> para eventos ao vivo. Ela só funciona quando o seu fluxo de trabalho é definido como **Ativo**. Se o fluxo de trabalho não estiver ativo, o n8n rejeita a solicitação com um erro "404 / webhook not registered", mesmo que o <span data-t="appName">Your AI Connector</span> tenha enviado os dados corretamente.

Em resumo: teste com a URL de Teste enquanto estiver ouvindo, mas para que o webhook continue funcionando com contatos reais, salve a **URL de Produção** no <span data-t="appName">Your AI Connector</span> e certifique-se de que o fluxo de trabalho esteja **Active**.

---

## Formato de Dados do Webhook

Quando um webhook é disparado, o <span data-t="appName">Your AI Connector</span> envia dados estruturados (JSON) para a sua URL de webhook. Se você estiver usando uma plataforma de automação como Zapier ou Make, ela analisa esses dados para você automaticamente. Se você estiver criando uma integração personalizada:

```json
{
  "event": "contactCreated",
  "contact": { "id": "<contact-id>", "first_name": "Jane", "...": "..." },
  "campaign": { "id": "<campaign-id>", "name": "AI Receptionist", "status": "Live" },
  "agent": { "id": "<agent-id>", "name": "Front Desk" },
  "user": { "id": "<account-id>", "email": "owner@example.com" }
}
```

| Campo | Descrição |
|---|---|
| `event` | A string exata do evento que disparou a notificação (por exemplo, `contactCreated`, `booked`). Este **não** é o rótulo de exibição mostrado na lista de eventos; cada rótulo e seu código correspondente estão em [Os 22 Eventos de Webhook](#the-22-webhook-events). |
| `contact` | O contato sobre o qual o evento trata, ou `null` para eventos não vinculados a um contato (como `creditsRecharged`). |
| `campaign` | A campanha à qual o contato pertence, ou `null` se não houver uma. |
| `agent` | O agente que está lidando com a conversa, ou `null` se não houver um. |
| `user` | Informações básicas de identidade da conta que possui os dados. |

> **`campaign` ou `agent` — geralmente um, não ambos.** Se sua conta usa agentes, seus contatos ficam com um agente em vez de uma campanha, então `campaign` chega como `null` e `agent` informa qual deles lidou com isso. Contas mais antigas baseadas em campanhas veem o inverso. Leia o que estiver preenchido; não presuma que `campaign` sempre estará lá.

> **O bloco `agent` chegou em 15 de agosto de 2026.** Ele se junta ao `campaign` nos eventos vinculados a uma conversa — um chat concluído, não perturbe, uma retomada, um desarquivamento, uma pausa da IA, uma nova mensagem, um resumo de conversa e o webhook que você pode definir em uma tag — e carrega o `id` e `name` do agente responsável, ou `null` quando nenhum agente está envolvido. É puramente aditivo: todos os campos que você já recebe permanecem inalterados, portanto, um receptor que você criou antes dessa data continuará funcionando sem precisar de atualizações.

Alguns eventos adicionam seu próprio bloco de nível superior extra. Por exemplo, **Agendamento Marcado** adiciona um bloco `appointment` (veja [Webhook de Agendamento Marcado](#appointment-booked-webhook)), **Nova Mensagem** adiciona um bloco `message` completo com o texto (veja [Webhook de Nova Mensagem](#new-message-webhook)), e **Entregas** e **Leituras** adicionam um bloco `message` curto apenas com o ID e o status da mensagem (veja [Webhook de Entregas e Leituras](#deliveries-and-reads-webhook)).

> **Entregas e Leituras informam qual mensagem, mas não o que ela diz.** Eles carregam um bloco `message` contendo o `id` e o `status` da mensagem — e esse `id` é o mesmo `messageId` que o [endpoint de envio de mensagem](../api/messages.md#send-a-message) retorna, para que você possa corresponder um recibo de entrega ou leitura à mensagem exata que enviou — mas não o corpo da mensagem. **Respostas** não carrega nenhum bloco `message`. Se você precisar das palavras que foram enviadas ou recebidas, inscreva-se em **Nova Mensagem** junto com eles.

> **Duas coisas para saber antes de escrever seu receptor.** Não há campo `timestamp` e nenhum wrapper `data`. Cada bloco fica no nível superior do objeto JSON, como mostrado acima.

### Os 22 Eventos de Webhook

Os 22 eventos de webhook, com o rótulo de exibição que você marca no aplicativo e o código `event` enviado no payload. O código `event` é uma string curta que **não** corresponde ao rótulo de exibição, portanto, faça a correspondência do seu receptor pelo código, não pelo rótulo:

| Rótulo de exibição (no aplicativo) | Código `event` no payload | O que significa |
|---|---|---|
| Contato Criado | `contactCreated` | Um novo contato é adicionado à sua conta (manualmente, via importação ou via API). |
| Contato Pausado | `contact_paused` | Uma conversa com um contato é pausada (o bot para de responder). |
| Contato Retomado | `contact_resumed` | Uma conversa pausada com um contato é retomada. |
| Contato Não Perturbe | `contact_do_not_disturb_changed` | A configuração de Não Perturbe de um contato é ativada. |
| Contato Desarquivado | `contact_unarchived` | Um contato arquivado envia uma nova mensagem, trazendo-o de volta para sua caixa de entrada ativa. |
| Nova Mensagem | `new_message` | Qualquer mensagem é adicionada a uma conversa em qualquer canal — tanto mensagens que seu contato envia para você quanto mensagens que sua IA ou sua equipe enviam para ele. Este é o único evento que carrega o texto real da mensagem (veja [Webhook de Nova Mensagem](#new-message-webhook)). |
| Respostas | `replied` | Um contato responde a uma mensagem. |
| Leituras | `read` | Um contato lê uma mensagem (em canais que suportam recibos de leitura). Carrega o ID da mensagem que foi lida — veja [Webhook de Entregas e Leituras](#deliveries-and-reads-webhook). |
| Entregas | `delivered` ou `undelivered` | Uma mensagem é entregue com sucesso a um contato (`undelivered` quando a entrega falha). Carrega o ID da mensagem — veja [Webhook de Entregas e Leituras](#deliveries-and-reads-webhook). |
| Alerta Humano | `humanAlerted` | O bot de IA determina que não consegue lidar com uma conversa e a sinaliza para atenção humana. |
| Chat Concluído | `chat_concluded` | O bot de IA decide que uma conversa chegou ao fim (agendamento feito, lead desqualificado, etc.). |
| Agendamento Marcado | `booked` | Um contato marca um agendamento através do sistema de agendamento. |
| Créditos Gastos | `creditsSpent` | Créditos são deduzidos da sua conta. |
| Créditos Recarregados | `creditsRecharged` | Créditos são adicionados à sua conta via recarga automática ou compra manual. |
| Saldo de Crédito Baixo | `lowCreditBalance` em uma entrega de **Teste**, `Low Credit Balance` em uma real | Um aviso antecipado de que seu saldo de créditos caiu abaixo do seu limite de alerta (100 créditos, a menos que você defina o seu próprio). Destinado a agências, cujas subcontas gastam de um pool comum. Ele carrega `balance`, `threshold` e `account_email` em vez de um bloco de contato, é enviado no máximo uma vez a cada 24 horas enquanto o saldo permanecer baixo, e é rearmado assim que o saldo volta a ficar acima do limite. |
| Tarefa Criada | `taskCreated` | Uma tarefa é criada. |
| Tarefa Atualizada | `taskUpdated` | Uma tarefa muda sem passar para um estágio de conclusão. |
| Tarefa Concluída | `taskCompleted` | Uma tarefa passa para um estágio configurado como estágio de conclusão. |
| Resumo Diário Criado | `dailySummaryCreated` | Seu relatório de resumo diário é gerado. |
| Canal Conectado | `channelConnected` | **Ainda não enviado — selecionável, mas nada o emite hoje. Não desenvolva com base nisso.** Destinado a quando um canal de mensagens termina de se conectar. |
| Transmissão Iniciada | `broadcastStarted` | Uma transmissão começa a ser enviada (seu status muda para Enviando). Dispara uma vez por início, incluindo quando uma transmissão pausada é retomada. Carrega um bloco `broadcast` em vez de um bloco de contato: id, nome, canal, status, status anterior, a lista que ela visa (`list_id`, `list_name`, `is_smart_list`), `scheduled_at`, `total_contacts`. |
| Transmissão Concluída | `broadcastCompleted` | Uma transmissão termina (seu status muda para Enviado ou Falhou). Mesmo bloco `broadcast` mais `completed_at` e, quando disponível, `completion_summary` (`total_sent`, `permanently_failed`, `unique_replied`, `failure_rate`, `had_errors`). Use estes dois para conectar uma Lista de Transmissão Inteligente a ferramentas externas. |

Dois outros códigos nunca aparecem nessa lista porque você não se inscreve neles: `contact_tags_updated`, enviado por uma URL de webhook definida em uma tag individual, e `summary_generated`, enviado quando um resumo de chat é escrito para uma tag na lista de `subscribed_to_tags` de um webhook.

> **Canal Conectado ainda não é enviado.** Ele aparece na lista de eventos, mas nada o emite atualmente. Não desenvolva nada baseado nele.

Notificações baseadas em tags e tarefas usam seus próprios formatos separados. Veja [Contact Tags Updated](#contact-tags-updated-webhook) e [Task Completed](#task-completed-webhook).

---

## Webhook de Contato Criado

Enviado quando o evento **Contato Criado** é disparado (um novo contato é adicionado manualmente, via importação ou via API).

### Nome do evento

`contactCreated`

### Formato do payload

```json
{
  "event": "contactCreated",
  "contact": {
    "id": "<contact-id>",
    "email": "jane@example.com",
    "phone_number": "+15551234567",
    "first_name": "Jane",
    "last_name": "Smith",
    "human_alerted": false,
    "human_alert_reason": null,
    "is_bot_active": true,
    "ad_referral": null
  },
  "campaign": {
    "id": "<campaign-id>",
    "name": "AI Receptionist",
    "status": "Live"
  },
  "agent": {
    "id": "<agent-id>",
    "name": "Front Desk"
  },
  "user": {
    "id": "<account-id>",
    "email": "owner@example.com",
    "first_name": "Alex",
    "last_name": "Doe"
  }
}
```

| Campo | Descrição |
|---|---|
| `event` | Sempre `contactCreated` para este evento. |
| `contact.id` | O ID exclusivo do novo contato. |
| `contact.email` / `contact.phone_number` | O e-mail e telefone do contato, se conhecidos (qualquer um pode estar vazio, dependendo do canal). |
| `contact.first_name` / `contact.last_name` | O nome do contato, se conhecido. |
| `contact.human_alerted` / `contact.human_alert_reason` | Se o contato está sinalizado para atenção humana e o motivo. |
| `contact.is_bot_active` | Se o bot de IA está ativo atualmente neste contato. |
| `contact.ad_referral` | Atribuição de anúncio Meta Click-to-WhatsApp, ou `null` — veja [Atribuição de Anúncio Click-to-WhatsApp](click-to-whatsapp-attribution.md). |
| `campaign` | A campanha sob a qual o contato foi criado, ou `null`. |
| `agent` | O agente atribuído ao contato, ou `null`. |
| `user` | Informações básicas de identidade da conta que possui o contato. |

> **A amostra de "Teste" e um evento real parecem ligeiramente diferentes.** O botão de teste envia dados de exemplo (John Doe, uma campanha de exemplo). Um evento real de Contato Criado carrega os detalhes reais do contato, e alguns campos podem estar vazios dependendo do canal.

---

## Webhook de Nova Mensagem

Este webhook é disparado toda vez que uma mensagem é adicionada a uma conversa, em qualquer canal. Ele cobre ambas as direções: mensagens que seu contato envia para você e mensagens que sua IA, sua equipe ou uma campanha envia para ele. É o único webhook que inclui o texto da mensagem, portanto, é o que deve ser usado quando você deseja espelhar conversas em um sistema externo.

### Nome do evento

`new_message`

### Formato do payload

```json
{
  "event": "new_message",
  "contact": {
    "id": "<contact-id>",
    "email": "jane@example.com",
    "phone_number": "+15551234567",
    "first_name": "Jane",
    "last_name": "Smith",
    "human_alerted": false,
    "human_alert_reason": null,
    "is_bot_active": true,
    "ad_referral": null
  },
  "agent": {
    "id": "<agent-id>",
    "name": "Front Desk"
  },
  "user": {
    "id": "<account-id>",
    "email": "owner@example.com",
    "first_name": "Alex",
    "last_name": "Doe"
  },
  "message": {
    "id": "<message-id>",
    "body": "Hi, are you open on Saturday?",
    "direction": "inbound",
    "status": "received",
    "created_at": "2026-07-30T17:27:06.000Z",
    "channel": "whatsapp_web"
  }
}
```

| Campo | Descrição |
|---|---|
| `event` | Sempre `new_message` para este evento. Observe que esta é a string exata enviada — não é o rótulo de exibição "Nova Mensagem". |
| `contact` | O contato a cuja conversa a mensagem pertence. Mesmo formato que em [Contato Criado](#contact-created-webhook). |
| `agent` | O agente que lida com a conversa (`id` e `name`), ou `null` se nenhum agente estiver envolvido. |
| `user` | Informações básicas de identidade da conta que possui a conversa. |
| `message.id` | O ID exclusivo da mensagem. |
| `message.body` | O texto da mensagem. Vazio para uma mensagem que carrega apenas um anexo (imagem, nota de voz, documento). |
| `message.direction` | `inbound` para uma mensagem do contato, `outbound` para uma enviada pela sua IA ou pela sua equipe da caixa de entrada, e `outbound-api` para uma enviada por uma campanha, uma transmissão, um envio de modelo ou pela API. |
| `message.status` | Onde a mensagem está em seu ciclo de vida: `received` para recebida, e `queued` / `sent` / `delivered` / `read` / `failed` / `undelivered` para enviada. Este é o status no momento em que a mensagem foi criada, então uma mensagem enviada geralmente chega aqui como `queued` ou `sent` e atinge `delivered` posteriormente — use os eventos **Entregas** e **Leituras** se precisar dessas transições posteriores. Eles carregam o mesmo `message.id` que este bloco, para que você possa corresponder a transição a esta mensagem (veja [Webhook de Entregas e Leituras](#deliveries-and-reads-webhook)). |
| `message.created_at` | Quando a mensagem foi criada, em UTC (ISO 8601). |
| `message.channel` | O canal pelo qual a mensagem passou, por exemplo `whatsapp`, `whatsapp_web`, `sms`, `instagram`, `messenger`, `telegram`, `email` ou `custom`. |

> **Ainda não há um bloco `campaign` neste payload.** A Nova Mensagem envia `contact`, `agent`, `user` e `message`. O bloco `agent` foi adicionado em **15 de agosto de 2026** e informa qual agente está lidando com a conversa; se você também precisar do contexto da campanha, procure o contato através da API usando `contact.id`.

> **Registros internos de IA não disparam este webhook.** Além das mensagens reais, a plataforma mantém suas próprias linhas de registro em uma conversa (chamadas de ferramenta da IA e registros de turno internos). Eles nunca são enviados — você recebe apenas mensagens que foram genuinamente enviadas ou recebidas.

---

## Webhook de Entregas e Leituras

Estes dois eventos relatam o que aconteceu com uma mensagem depois que ela deixou <span data-t="appName">Your AI Connector</span>: **Entregas** dispara quando uma mensagem chega ao contato (ou falha ao chegar), e **Leituras** dispara quando o contato a abre, nos canais que suportam recibos de leitura.

Ambos carregam um bloco `message` com o ID da mensagem sobre a qual o evento trata, para que você possa corresponder a atualização à mensagem exata que enviou.

### Nomes de eventos

`delivered` e `undelivered` para **Entregas**, `read` para **Leituras**.

### Formato do payload

```json
{
  "event": "delivered",
  "contact": {
    "id": "<contact-id>",
    "email": "jane@example.com",
    "phone_number": "+15551234567",
    "first_name": "Jane",
    "last_name": "Smith",
    "ad_referral": null
  },
  "campaign": {
    "id": "<campaign-id>",
    "name": "AI Receptionist",
    "status": "Live"
  },
  "agent": {
    "id": "<agent-id>",
    "name": "Front Desk"
  },
  "user": {
    "id": "<account-id>",
    "email": "owner@example.com",
    "first_name": "Alex",
    "last_name": "Doe"
  },
  "message": {
    "id": "<message-id>",
    "status": "delivered"
  }
}
```

| Campo | Descrição |
|---|---|
| `event` | `delivered` ou `undelivered` para **Entregas**, `read` para **Leituras**. |
| `contact` | O contato para o qual a mensagem foi enviada. |
| `campaign` | A campanha à qual o contato pertence, ou `null`. |
| `agent` | O agente que lida com a conversa, ou `null`. |
| `user` | Informações básicas de identidade da conta que possui os dados. |
| `message.id` | O ID da mensagem sobre a qual esta atualização trata. É o mesmo valor que o [endpoint de envio de mensagem](../api/messages.md#send-a-message) retorna como `messageId`, e o mesmo `message.id` que uma notificação de [Nova Mensagem](#new-message-webhook) carrega. |
| `message.status` | O novo status, sempre a mesma string que `event` (`delivered`, `undelivered` ou `read`). |

> **Como corresponder uma atualização à mensagem que você enviou.** Armazene o `messageId` que você recebe de volta ao enviar uma mensagem através da API. Quando uma notificação de **Entregas** ou **Leituras** chegar, procure esse ID armazenado em `message.id` no payload — esse é o seu recibo de entrega ou leitura para aquela mensagem exata.

> **Não há texto de mensagem aqui.** O bloco `message` carrega apenas o ID e o status. Inscreva-se em [Nova Mensagem](#new-message-webhook) se você também precisar do corpo.

> **O bloco `message` só está presente quando sabemos qual mensagem era.** Na rara atualização que não conseguimos vincular a uma mensagem armazenada, o bloco é omitido inteiramente em vez de ser enviado vazio — portanto, verifique se `message` existe antes de ler `message.id`.

> **Uma notificação por mudança de status.** Uma única mensagem enviada normalmente produz uma notificação `delivered` e, em seguida, em canais com recibos de leitura, uma `read`. Um envio com falha produz `undelivered` em vez disso.

---

## Webhook de Agendamento Marcado

Disparado quando um contato agenda um compromisso. Ele é disparado da mesma forma, quer a IA tenha agendado durante uma conversa, você tenha agendado manualmente ou tenha vindo através da API.

### Nome do evento

`booked`

### Formato do payload

```json
{
  "event": "booked",
  "contact": {
    "id": "<contact-id>",
    "email": "jane@example.com",
    "phone_number": "+15551234567",
    "first_name": "Jane",
    "last_name": "Smith"
  },
  "campaign": {
    "id": "<campaign-id>",
    "name": "AI Receptionist",
    "status": "Live"
  },
  "user": {
    "id": "<account-id>",
    "email": "owner@example.com"
  },
  "appointment": {
    "appointment_id": "<appointment-id>",
    "start_time": "2026-07-20T15:00:00.000Z",
    "end_time": "2026-07-20T15:30:00.000Z",
    "status": "confirmed",
    "room_name": "Room 1",
    "description": "Discovery call",
    "summary": "30 min intro",
    "google_calendar_event_id": null,
    "event": {
      "id": "<service-id>",
      "event_name": "Intro Call",
      "slot_duration": 30,
      "location": "Zoom",
      "meeting_link": "https://...",
      "event_type": "online"
    }
  }
}
```

| Campo | Descrição |
|---|---|
| `event` | Sempre `booked` para este evento. |
| `contact` | A pessoa que agendou. `email` e `phone_number` podem estar vazios dependendo do canal. |
| `appointment.appointment_id` | O ID único do agendamento. |
| `appointment.start_time` / `end_time` | Início e fim do horário agendado, em UTC (ISO 8601). |
| `appointment.status` | O status atual do agendamento. |
| `appointment.room_name` | A sala onde o agendamento foi feito, se utilizada. |
| `appointment.description` / `summary` | Detalhes de texto livre capturados com o agendamento. |
| `appointment.google_calendar_event_id` | ID do Google Calendar para o evento sincronizado. Frequentemente é `null` no webhook de Agendamento Marcado, porque o evento do calendário é criado no mesmo momento em que a notificação é enviada — busque novamente o agendamento pelo seu `appointment_id` um momento depois se precisar, e espere um `null` permanente em contas sem Google Calendar conectado. |
| `appointment.event` | O serviço que foi agendado: nome, duração do horário, local, link da reunião, tipo. |

> **`google_calendar_event_id` é frequentemente `null` neste webhook, e isso é normal.** O evento do Google Calendar é criado no mesmo momento em que esta notificação é enviada, então o ID geralmente ainda não está pronto. Recupere o compromisso pelo seu `appointment_id` um momento depois, se precisar dele. Ele permanece `null` permanentemente se a conta não tiver um Google Calendar conectado, então não espere por ele para sempre.

> **O botão "Testar" não inclui o bloco `appointment`.** Use-o para confirmar se o seu endpoint responde, então faça um agendamento real para ver o payload completo.

> **Dois casos em que este webhook não é disparado:** agendamentos importados de um calendário externo e reservas que chegam através da integração com o Formitable.

---

## Webhook de Atualização de Tags de Contato

Disparado quando uma tag é **aplicada** a um contato, e essa tag possui uma URL de webhook configurada no agente ou na campanha à qual o contato pertence.

### Nome do evento

`contact_tags_updated`

### Quando é disparado

- Uma tag é aplicada a um contato que possui um agente atribuído, uma campanha atribuída ou ambos.
- Pelo menos uma das tags aplicadas possui uma URL de webhook definida na aba Tags desse agente ou campanha.

Se o contato tiver ambos e as tags da campanha possuírem URLs de webhook, elas prevalecem; caso contrário, as do agente são usadas.

Se várias tags com URLs de webhook diferentes forem aplicadas na mesma atualização, uma solicitação é enviada por URL, cada uma contendo apenas as tags que correspondem a essa URL.

**A remoção de uma tag nunca envia uma solicitação.** A maioria das pessoas aponta essas URLs para uma ação — coletar um depósito, reservar um horário, alertar um representante — portanto, uma tag sendo removida de um contato costumava reexecutar essa ação. Isso não é mais possível. Uma remoção ainda aparece em `removed_tags` quando ocorre na mesma atualização que uma aplicação que vai para a mesma URL, para que uma automação que lê ambos os arrays mantenha o panorama completo; o que ela nunca verá é uma solicitação causada apenas por uma remoção. (Alterado em **12 de agosto de 2026**. Antes dessa data, as remoções também enviavam uma solicitação.)

### Formato do payload

```json
{
  "event": "contact_tags_updated",
  "contact": {
    "id": "<contact-id>",
    "email": "jane@example.com",
    "phone_number": "+15551234567",
    "first_name": "Jane",
    "last_name": "Smith",
    "human_alerted": false,
    "is_bot_active": true,
    "ad_referral": {
      "ctwa_clid": "ARAbc123...",
      "source_id": "120210000000000",
      "source_type": "ad",
      "source_url": "https://fb.me/xxxx",
      "headline": "Get 20% off today",
      "body": "Message us now to claim your discount",
      "channel": "whatsapp"
    }
  },
  "added_tags": ["qualified-lead"],
  "removed_tags": ["new-lead"],
  "agent": {
    "id": "<agent-id>",
    "name": "Front Desk"
  },
  "user": {
    "email": "owner@example.com",
    "first_name": "Alex",
    "last_name": "Doe"
  }
}
```

| Campo | Descrição |
|---|---|
| `event` | Sempre `contact_tags_updated` para este webhook. |
| `contact.id` | O ID exclusivo do contato cujas tags foram alteradas. |
| `contact.email` / `contact.phone_number` | O e-mail/telefone do contato, se conhecido. |
| `contact.first_name` / `contact.last_name` | O nome do contato. |
| `contact.human_alerted` | Se o contato está sinalizado atualmente para atenção humana. |
| `contact.is_bot_active` | Se o bot de IA está ativo atualmente na conversa deste contato. |
| `contact.ad_referral` | Presente apenas quando o contato entrou em contato pela primeira vez através de um anúncio ou postagem Meta Click-to-WhatsApp (CTWA). `null` caso contrário. |
| `added_tags` | Matriz de nomes de tags aplicadas nesta atualização. Nunca vazia — uma aplicação é o que dispara a solicitação. |
| `removed_tags` | Matriz de nomes de tags removidas na mesma atualização, se houver. Uma remoção por si só não envia nada. |
| `agent` | O agente que está lidando com a conversa do contato (`id` e `name`), ou `null` se nenhum agente estiver envolvido. Adicionado em **15 de agosto de 2026**. |
| `user` | Informações básicas de identidade da conta proprietária do contato. |

### Testando um webhook de tag

Ao lado do campo de URL do webhook na aba Tags, há um botão **Testar**. Ele envia uma carga útil de exemplo para essa URL imediatamente, para que você possa confirmar se sua automação a recebe antes de esperar por uma conversa real.

O teste envia o mesmo formato de `contact_tags_updated` mostrado acima, usando um contato de espaço reservado, com a tag que você está testando em `added_tags` e um `removed_tags` vazio. O que sua automação vê no teste é o que ela verá em produção.

Duas coisas para saber:

- **Salve a tag primeiro.** O teste procura a tag pelo seu nome salvo, portanto, uma tag nova ou uma renomeação não salva ainda não pode ser testada. O botão permanece cinza até que o nome na tela corresponda ao salvo.
- **Um teste com falha não conta contra seu webhook.** Testes nunca contribuem para o desligamento automático após falhas repetidas descrito em [Confiabilidade de Webhook](#webhook-reliability).

Se o teste falhar, a mensagem informa o que seu endpoint respondeu (por exemplo, um `404` ou `500`), o que geralmente é suficiente para identificar uma URL incorreta ou um fluxo de trabalho que não está ativado.

---

## Webhook de Tarefa Concluída

> **Apenas para referência.** Webhooks de tarefas (como dados) estão documentados aqui para desenvolvedores; os eventos **Task Created**, **Task Updated** e **Task Completed** são selecionáveis na lista de eventos padrão no formulário de webhook como qualquer outro evento — veja [Eventos de Gatilho Disponíveis](#available-trigger-events) e [Os 22 Eventos de Webhook](#the-22-webhook-events).

Este payload é enviado quando uma tarefa transita para um estágio marcado como um estágio de conclusão. Uma tarefa movendo-se entre estágios que não são de conclusão envia o formato `taskUpdated`.

### Nome do evento

`taskCompleted`

### Quando é disparado

- Uma tarefa é atualizada.
- Seu valor `stage` mudou em comparação com o valor anterior.
- O novo estágio está configurado como um estágio de conclusão nas configurações de estágio de tarefa da conta.

### Formato do payload

```json
{
  "event": "taskCompleted",
  "contact": {
    "email": "jane@example.com",
    "phone_number": "+15551234567",
    "first_name": "Jane",
    "last_name": "Smith",
    "human_alerted": false,
    "human_alert_reason": null
  },
  "user": {
    "email": "owner@example.com",
    "first_name": "Alex",
    "last_name": "Doe"
  },
  "message": {
    "id": "<task-id>",
    "title": "Follow up with Jane",
    "description": "Confirm pricing and send proposal",
    "type": "follow_up",
    "priority": "high",
    "stage": "<stage-id>",
    "due_date": "2026-01-20T15:00:00Z",
    "source": "ai",
    "source_detail": "<source-detail>",
    "campaign_id": "<campaign-id>",
    "linked_human_alert": "<human-alert-id>",
    "tags": ["qualified-lead"],
    "notes": "Customer requested a callback"
  }
}
```

| Campo | Descrição |
|---|---|
| `event` | Sempre `taskCompleted` para este webhook. O mesmo formato de payload é enviado como `taskUpdated` quando uma tarefa muda sem entrar em um estágio de conclusão. |
| `contact` | O contato vinculado à tarefa, se houver. `null` quando não estiver vinculado. |
| `contact.human_alert_reason` | O motivo pelo qual o contato foi sinalizado para atenção humana, se aplicável. |
| `user` | Informações básicas de identidade da conta à qual a tarefa pertence. |
| `message.id` | O ID exclusivo da tarefa. |
| `message.title` / `description` | O título e a descrição da tarefa. |
| `message.type` | O tipo de tarefa (por exemplo, `follow_up`, `call`, `custom`). |
| `message.priority` | A prioridade da tarefa (`low`, `medium`, `high`). |
| `message.stage` | O ID do estágio em que a tarefa se encontra agora. |
| `message.due_date` | A data de vencimento da tarefa, se definida. |
| `message.source` | O que criou a tarefa (`ai`, `manual`, `api`). |
| `message.source_detail` | Detalhes adicionais sobre a origem. |
| `message.campaign_id` | O ID da campanha vinculada, ou `null`. |
| `message.linked_human_alert` | O ID do alerta humano vinculado, se houver. |
| `message.tags` | Etiquetas aplicadas à tarefa. |
| `message.notes` | Notas de formato livre sobre a tarefa. |

---

## Desativando (ou excluindo) um Webhook

Todo webhook tem um interruptor liga/desliga, bem na sua linha. Desligar um **desativa** o recebimento de eventos, mas mantém tudo o que você configurou — a URL, os eventos, qualquer segredo de assinatura. Ligue-o novamente e ele continuará de onde parou; nada do que aconteceu enquanto estava desligado será entregue posteriormente.

Use este recurso quando quiser interromper as entregas por um tempo: seu endpoint está sendo reconstruído, você está depurando uma integração muito ativa ou está pausando uma automação.

**Excluir** um webhook (o ícone de lixeira na sua linha) remove-o permanentemente, incluindo seu segredo de assinatura. Se você deseja apenas que as entregas parem, desligue-o — a exclusão é para quando você terminar completamente com o endpoint.

> **Isso não é o mesmo que um webhook ser desativado automaticamente.** Se desativarmos seu webhook após falhas repetidas (consulte [Confiabilidade de Webhook](#webhook-reliability)), o botão acima não o reativará. Assim que seu endpoint for corrigido, edite o webhook e salve-o com uma URL alterada (qualquer alteração de URL o reativa), ou chame o [endpoint de reativação](../api/webhooks.md) via API — ou peça ao suporte e nós o reativaremos para você.

---

## Payloads Assinados (Verificando se um Webhook Realmente Veio de Nós)

Qualquer pessoa que descubra a URL do seu webhook pode enviar uma solicitação falsa para ele. Se você executa ações automaticamente com base em webhooks — atualizando faturamento, criando registros de CRM — ativar a **assinatura** permite verificar se cada solicitação veio genuinamente de nós.

A assinatura é **opcional e desativada por padrão**, e você a ativa por webhook, na visualização de edição desse webhook (abra a linha de um webhook salvo).

### Ativando a assinatura

1. Abra o webhook (Configurações → Integrações → Webhooks → clique na linha do seu webhook).
2. Na seção **Segredo de assinatura**, clique em **Gerar**.
3. Copie o segredo (ele começa com `whsec_`) e armazene-o em seu sistema receptor. Trate-o como uma senha.

Você pode voltar e revelar, copiar, rotacionar ou desativar o segredo a qualquer momento a partir deste mesmo painel.

### O que enviamos

Assim que a assinatura estiver ativada, cada entrega para esse webhook conterá estes dois cabeçalhos HTTP extras:

| Cabeçalho | Significado |
|---|---|
| `X-Webhook-Signature` | A assinatura, no formato `v1=<hex>`. |
| `X-Webhook-Timestamp` | Quando enviamos, como um timestamp Unix em segundos. |

Estes três estão em **todas** as entregas, assinadas ou não:

| Cabeçalho | Significado |
|---|---|
| `X-Webhook-Delivery` | Um ID exclusivo para este evento. Permanece o mesmo entre tentativas, portanto, é nele que você deve basear a desduplicação. |
| `X-Webhook-Attempt` | Qual é a tentativa atual (`1` é a primeira tentativa). |
| `X-Webhook-Event` | O nome do evento, para que você possa rotear sem ler o corpo da mensagem. |

### Como verificar

A assinatura é um HMAC-SHA256 da string `<timestamp>.<raw request body>`, usando seu segredo de assinatura como chave.

**Verifique em relação ao corpo da solicitação bruta — os bytes exatos que você recebeu.** Se o seu framework analisar o JSON e serializá-lo novamente antes de verificar, os bytes podem mudar e a assinatura não corresponderá.

Exemplo em Node.js:

```js
const crypto = require("crypto");

function verify(rawBody, headers, secret) {
  const timestamp = headers["x-webhook-timestamp"];
  const signature = headers["x-webhook-signature"]; // "v1=<hex>"

  // Reject anything older than 5 minutes so a captured request can't be replayed later.
  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;

  const expected = crypto.createHmac("sha256", secret).update(`${timestamp}.${rawBody}`).digest("hex");

  return crypto.timingSafeEqual(Buffer.from(signature.replace("v1=", "")), Buffer.from(expected));
}
```

Exemplo em Python:

```python
import hashlib, hmac, time

def verify(raw_body: bytes, headers, secret: str) -> bool:
    timestamp = headers["X-Webhook-Timestamp"]
    signature = headers["X-Webhook-Signature"].replace("v1=", "")

    # Reject anything older than 5 minutes so a captured request can't be replayed later.
    if abs(time.time() - int(timestamp)) > 300:
        return False

    expected = hmac.new(secret.encode(), f"{timestamp}.".encode() + raw_body, hashlib.sha256).hexdigest()

    return hmac.compare_digest(signature, expected)
```

> **Compare assinaturas com uma função de tempo constante (timing-safe)** (`timingSafeEqual` / `compare_digest`), não `==`. Não custa nada e evita uma classe sutil de ataque.

### Rotacionando o segredo

Clique em **Rotacionar** para substituir o segredo. A troca é imediata: a próxima entrega já é assinada apenas com o novo segredo. Se o seu endpoint estiver ativo, aceite **ambos** os segredos (o antigo e o novo) por alguns minutos enquanto você implanta o novo.

Desativar a assinatura simplesmente interrompe o envio dos cabeçalhos de assinatura.

---

## Tentando novamente entregas com falha

Por padrão, uma entrega que falha não é tentada novamente — se o seu sistema estiver fora do ar naquele momento, esse evento será perdido.

Ative **Tentar novamente entregas com falha** em um webhook (no formulário de criação/edição) e continuaremos tentando:

| Tentativa | Quando |
|---|---|
| 1 | Imediatamente |
| 2 | 1 minuto depois |
| 3 | 5 minutos depois |
| 4 | 30 minutos depois |
| 5 | 2 horas depois |

Isso abrange cerca de **2 horas e 40 minutos**, portanto, um webhook pode sobreviver a uma janela de manutenção ou a uma breve interrupção do seu lado.

**O que é tentado novamente:** problemas temporários — seu servidor retornando um erro 5xx, um tempo limite (timeout) ou uma falha de conexão.

**O que não fazemos:** se o seu endpoint rejeitar a própria requisição (qualquer erro 4xx), não tentamos novamente — enviar a mesma requisição novamente apenas produziria a mesma rejeição.

**Quais eventos são reenviados:** webhooks de tag (`contact_tags_updated`), os três eventos de tarefa e o resumo diário. Os demais são enviados apenas uma vez, portanto, para eles, a chave não tem efeito. Todo evento ainda contém `X-Webhook-Delivery`, então uma única regra de desduplicação cobre todos eles.

> **Ative as tentativas de reenvio apenas se o seu endpoint for idempotente.** Reenvios significam que o mesmo evento pode chegar mais de uma vez. Use o cabeçalho `X-Webhook-Delivery` para reconhecer uma repetição: ele permanece o mesmo em todas as tentativas para um único evento, para que você possa ignorar com segurança um ID que já processou.

As tentativas de reenvio interagem com o desligamento automático após falhas repetidas (veja [Confiabilidade de Webhook](#webhook-reliability)) da maneira que você deseja: o contador de falhas contabiliza uma **entrega completa**, apenas após o uso de todas as tentativas de reenvio — não cada tentativa individual.

---

## Confiabilidade do Webhook

- O <span data-t="appName">Your AI Connector</span> envia webhooks por meio de uma conexão segura (HTTPS). Certifique-se de que o endereço da web fornecido use HTTPS.
- Se o seu sistema retornar um erro, a entrega é considerada com falha.
- Monitore o tempo de atividade do seu sistema receptor para evitar perder eventos.
- Para fluxos de trabalho críticos, ative [Tentando Novamente Entregas com Falha](#retrying-failed-deliveries) e considere também um mecanismo de fallback.

> **Webhooks são desativados automaticamente após falhas repetidas.** Se a URL do seu webhook falhar repetidamente (cerca de 5 erros seguidos, ou 3 seguidos para erros de configuração), o <span data-t="appName">Your AI Connector</span> para automaticamente de enviar eventos para essa URL. Para reativá-lo assim que seu endpoint estiver saudável: edite o webhook e salve-o com uma URL alterada (qualquer alteração de URL o reativa), ou use o [endpoint de reativação](../api/webhooks.md) via API — salvar novamente com a mesma URL não é suficiente. O suporte também pode reativá-lo para você.

---

## Solução de problemas

| Problema | Solução |
|---|---|
| Webhook não disparando | Primeiro, verifique se o webhook não está **desativado** em sua linha. Em seguida, confirme se os eventos corretos estão selecionados e se sua URL é acessível pela internet. |
| Evento de teste funciona, mas eventos reais não | Certifique-se de que o tipo de evento específico esteja habilitado. Se você esperava uma solicitação quando uma tag é aplicada, observe que `subscribed_to_tags` não limita os eventos de um webhook a uma tag — ele apenas restringe quais tags produzem uma notificação de resumo de conversa. Para obter uma solicitação quando uma tag específica é aplicada, defina uma URL de webhook nessa tag na aba **Tags** do agente (ou campanha) — veja [Webhook de Tags de Contato Atualizadas](#contact-tags-updated-webhook). |
| Nada chega no n8n / Make / Zapier | Você provavelmente está usando a **URL de Teste** da plataforma, que apenas escuta um único evento logo após clicar em "Ouvir evento de teste". Para eventos em tempo real, salve a **URL de Produção** e altere o fluxo de trabalho para **Ativo**. |
| Recebendo eventos duplicados | Verifique se há vários webhooks apontando para a mesma URL. Se **Tentar novamente entregas com falha** estiver ativado, uma repetição é esperada sempre que seu endpoint aceitou um evento, mas falhou em responder a tempo — faça a desduplicação em `X-Webhook-Delivery`. |
| Verificação de assinatura sempre falha | Quase sempre porque o corpo foi re-serializado antes da verificação. Verifique em relação ao corpo da solicitação **bruto**, assine `<timestamp>.<body>` e confirme se você está usando o segredo atual caso tenha feito uma rotação recentemente. |
| Tentativas de reenvio não ocorrendo | As tentativas de reenvio estão desativadas, a menos que sejam habilitadas nesse webhook específico. Nós não tentamos novamente respostas 4xx. |
| O bloco `campaign` é sempre `null` | Esperado se sua conta usa agentes: os contatos ficam com um agente em vez de uma campanha. Leia o bloco `agent` em vez disso — veja [Formato de Dados de Webhook](#webhook-data-format). |
| Dados estão vazios ou malformados | Verifique se seu sistema receptor aceita JSON. Verifique os logs do seu servidor em busca de erros de análise. |
| URL do Webhook retorna erros | Teste sua URL com uma ferramenta como Postman ou [webhook.site](https://webhook.site). |
| Webhook parou de disparar totalmente após uma interrupção | Falhas repetidas desabilitam automaticamente um webhook. Salvar novamente não o reabilita — corrija seu endpoint e, em seguida, entre em contato com o suporte. |
| Salvar ou Testar gera um erro de permissão | Você precisa da permissão de "editar" Integrações. Peça ao proprietário da conta para concedê-la. |
| A lista `subscribed_to_tags` de um webhook retornou vazia | `subscribed_to_tags` não limita os eventos de um webhook a uma tag — ele apenas restringe quais tags produzem uma notificação de resumo de conversa. Editar a partir do formulário de webhook não limpa mais essa lista (corrigido em 21 de julho de 2026). Se um webhook perdeu sua lista antes dessa data, defina `subscribed_to_tags` novamente via [API de Webhooks](../api/webhooks.md) — veja [Gatilhos de Webhook Baseados em Tag](#tag-based-webhook-triggers). |

---

## Próximos passos

- [Integração com GoHighLevel](ghl-integration.md) — use webhooks para integrar o <span data-t="appName">Your AI Connector</span> com o GHL.
- [Acesso à API](api-access.md) — combine webhooks com a API para automações poderosas.
- [Usando Tags para Rotular Contatos](../get-started/creating-tags.md) — configure tags que disparam seus webhooks.
