> ## Documentation Index
> Fetch the complete documentation index at: https://docs.brainchat.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

> Receba mensagens, eventos de instância e mudanças em contatos em tempo real via webhook.

# Webhooks

Configure webhooks para receber eventos em tempo real. Cada webhook cadastrado em `/u/webhooks` responde por um único tipo de evento (ou variantes agregadas).

## Configuração

<Steps>
  <Step title="Acesse Webhooks">
    No painel, vá em **/u/webhooks** e clique em **Adicionar webhook**.
  </Step>

  <Step title="Escolha o tipo de evento">
    Selecione qual evento deve ser enviado — ver tabela abaixo.
  </Step>

  <Step title="Informe a URL de destino">
    URL HTTPS pública que receberá os eventos via `POST`.
  </Step>
</Steps>

## Segurança

<Warning>
  Implemente estas proteções no seu servidor:

  * **Validação HMAC**: valide o header `X-Signature` com o `client_token` da instância.
  * **Validação de timestamp**: rejeite requisições com `X-Timestamp` antigo (> 5 minutos).
  * **Idempotência**: use `X-Idempotency-Key` para deduplicar entregas.
  * **HTTPS**: URLs `http://` e IPs privados são bloqueados.
</Warning>

## Eventos Disponíveis

| `event_type`       | Descrição                                                            |
| ------------------ | -------------------------------------------------------------------- |
| `message_received` | Nova mensagem recebida do cliente                                    |
| `message_sent`     | Mensagem enviada pela instância                                      |
| `both`             | Mensagens recebidas + enviadas                                       |
| `contact_created`  | Novo contato criado (WhatsApp, API, importação, formulário, widget…) |
| `contact_updated`  | Contato existente teve campos relevantes alterados                   |
| `contact_any`      | Contatos criados + atualizados                                       |

### Quando `contact_updated` dispara

Apenas quando um dos seguintes campos muda: `name`, `email`, `company`, `job_title`, `notes`, `custom_labels`, `utm_source`, `utm_medium`, `utm_campaign`, `is_favorite`, `is_archived`, `is_blocked`.

Mudanças em `last_message_at`, `photo_url`, `unread_count` e outros campos operacionais **não** disparam webhook.

## Payload de mensagem

```json theme={null}
{
  "event": "message_received",
  "instance_id": "internal_<uuid>",
  "message": {
    "id": "…",
    "phone": "5511999999999",
    "message_type": "text",
    "content_text": "Olá, preciso de ajuda",
    "timestamp": "2024-01-15T10:30:00Z",
    "from_me": false,
    "sender_name": "João Silva",
    "chat_name": null
  },
  "timestamp": "2024-01-15T10:30:00Z"
}
```

## Payload de contato

Mesma estrutura da API `/contacts-api/create`, acrescida de metadados do evento:

```json theme={null}
{
  "event": "contact_created",
  "instanceId": "SUA_INSTANCIA",
  "instanceName": "Stegia Comercial",
  "contactId": "uuid-do-contato",
  "phone": "5511999999999",
  "name": "João Silva",
  "email": "joao@email.com",
  "company": "ACME Corp",
  "jobTitle": "Diretor",
  "notes": "Lead vindo do formulário Trabalhe Conosco",
  "tags": ["vip", "lead-quente"],
  "utmSource": "google",
  "utmMedium": "cpc",
  "utmCampaign": "black-friday",
  "customLabels": {
    "contratante": "1346452978",
    "vincular_vaga": "1409608130",
    "segmento": "premium"
  },
  "origin": "form",
  "isFavorite": false,
  "isArchived": false,
  "isBlocked": false,
  "changedKeys": null,
  "createdAt": "2026-07-09T10:30:00Z",
  "updatedAt": "2026-07-09T10:30:00Z",
  "timestamp": "2026-07-09T10:30:00Z"
}
```

Em `contact_updated`, `changedKeys` traz um array com os campos que mudaram, ex.: `["email", "custom_labels"]`.

<Tip>
  `customLabels` é sempre um **objeto JSON** (`{"chave": "valor"}`), igual ao aceito no endpoint `/contacts-api/create`. Consuma direto em Zapier/Make/n8n via `payload.customLabels.contratante`.
</Tip>

## Headers enviados

| Header                | Descrição                                                    |
| --------------------- | ------------------------------------------------------------ |
| `X-Client-Token`      | Token da instância (mesmo usado na API)                      |
| `X-Signature`         | HMAC-SHA256 do body assinado com o `client_token`            |
| `X-Signature-Version` | Sempre `v1`                                                  |
| `X-Timestamp`         | Timestamp em ms (evita replay)                               |
| `X-Idempotency-Key`   | Chave única do evento                                        |
| `X-Event-Type`        | Nome do evento (`contact_created`, `message_received`, etc.) |

## Retry Policy

Se seu servidor retornar erro (status ≥ 500) ou timeout (> 30s), o sistema tenta reenviar até **3 vezes** com backoff exponencial (1s → 2s → 4s). Respostas `4xx` **não** são reenviadas.

<Tip>
  Retorne `200` o mais rápido possível. Processe a lógica de negócio de forma assíncrona para evitar timeouts.
</Tip>
