---
title: "Um webhook para WhatsApp, Instagram e Messenger: o padrão Meta na prática"
description: "Receba WhatsApp, Instagram e Messenger em um único webhook no formato da Meta Cloud API, reusando um só parser. O campo provider diz o canal."
url: "https://api-wa.me/blog/webhook-whatsapp-instagram-messenger-padrao-meta"
language: "pt-BR"
og:type: "article"
published_time: "2026-08-07"
modified_time: "2026-08-07"
author: "Raphael Serafim"
keywords: "webhook whatsapp api, webhook instagram, webhook messenger, meta cloud api webhook, receber mensagens whatsapp api, parser webhook whatsapp"
reading_time: "9 min de leitura"
---

# Um webhook para WhatsApp, Instagram e Messenger: o padrão Meta na prática

> Receba WhatsApp, Instagram e Messenger em um único webhook no formato da Meta Cloud API, reusando um só parser. O campo provider diz o canal.

**Você pode receber mensagens e eventos de WhatsApp, Instagram e Messenger em um único webhook, no mesmo envelope da Meta Cloud API — reaproveitando um só parser.** A WAME entrega os três canais na estrutura oficial da Meta; o que muda de um para o outro é apenas o campo `provider`. O resultado: um endpoint, um parser, três canais.

Neste guia você configura o webhook no formato `meta`, entende o envelope campo a campo, trata os eventos com os SDKs de Node.js e PHP (ou com Express puro) e responde à mensagem recebida dentro do próprio handler.

## Por que webhooks

Sem webhook, você teria que ficar perguntando à API se chegou algo novo (polling) — desperdício de requisições e atraso. Com webhook, é o contrário: a WAME **empurra** o evento para o seu servidor no instante em que ele acontece. Mensagem recebida, status de entrega, presença ("digitando"), conexão da instância, QR code, chamadas — tudo chega em tempo real, no seu endpoint.

Para quem atende clientes, isso é a base de um chatbot, de um CRM ou de uma central omnichannel: o evento chega, seu código decide o que fazer e responde na hora.

## Passo 1 — Configurar o webhook na instância

O webhook é configurado por instância, com um `PUT /{key}/instance`. O campo-chave aqui é o `webhookFormat`:

```bash
curl -X PUT "https://us.api-wa.me/YOUR_KEY/instance" \
  -H "Content-Type: application/json" \
  -d '{"allowWebhook":true,"allowNumber":"all","webhookFormat":"meta","webhookMessage":"https://seu-servidor.com/webhook"}'
```

O que cada campo faz:

- **`allowWebhook`** — liga o envio de eventos para o seu endpoint.
- **`allowNumber`** — quais números geram eventos (`all` para todos).
- **`webhookMessage`** — a URL que vai receber os eventos.
- **`webhookFormat`** — o formato do payload. É aqui que a mágica acontece.

Sobre o `webhookFormat`, há três opções:

- **`native`** — payload no formato interno da WAME. Mais enxuto, mas específico da plataforma.
- **`meta`** — payload no **envelope oficial da Meta Cloud API**. É o que permite reaproveitar os parsers oficiais e tratar WhatsApp, Instagram e Messenger com o mesmo código.
- **`both`** — envia os dois formatos, útil em migrações ou testes.

Para o cenário deste post — um webhook, três canais — use **`meta`**. Assim seu parser já entende a estrutura que a própria Meta documenta, e o campo `provider` diferencia o canal.

## Passo 2 — O envelope

Independentemente do canal, o corpo entregue no formato `meta` tem sempre a mesma forma. Só muda o `provider` (e o `messaging_product` interno):

```json
{
  "object": "wame",
  "provider": "whatsapp",
  "instance": "YOUR_INSTANCE_ID",
  "official": true,
  "entry": [{ "id": "YOUR_INSTANCE_ID", "changes": [{ "field": "messages", "value": {
    "messaging_product": "whatsapp",
    "metadata": { "display_phone_number": "5511999990000", "phone_number_id": "YOUR_INSTANCE_ID" },
    "contacts": [{ "profile": { "name": "Fulano" }, "wa_id": "5511988887777" }],
    "messages": [{ "from": "5511988887777", "id": "wamid.XXX", "timestamp": "1700000000", "type": "text", "text": { "body": "Olá!" } }]
  }}]}]
}
```

Os campos que importam:

- **`object`** — identifica a origem do evento (`wame`).
- **`provider`** — o canal: `whatsapp`, `instagram` ou `messenger`. É o campo que o seu código lê para saber por onde responder.
- **`instance`** — o identificador da instância que gerou o evento.
- **`official`** — se a instância é oficial (API Cloud da Meta) ou não.
- **`entry[]`** — a lista de entradas, cada uma com `changes[]`.
- **`entry[].changes[].field`** — o **tipo** de evento (`messages`, `presence`, etc.).
- **`entry[].changes[].value`** — o conteúdo do evento, no formato oficial da Meta.

Para trocar de canal, imagine o mesmo JSON com `"provider": "instagram"` — a estrutura de leitura do seu código continua idêntica. É esse o ganho de usar o padrão Meta.

## Passo 3 — Tratar os eventos

Você não precisa navegar o `entry[].changes[].value` na mão. Os SDKs oficiais têm um parser que achata o envelope em uma lista de eventos tipados, já expondo `provider`, `official`, `fromUserId` e `profile`.

### Node.js / TypeScript

Com o SDK `@raphaelvserafim/client-api-whatsapp`, use `parseWebhook`:

```ts
import express from 'express';
import { Wame, TypeMessage, parseWebhook } from '@raphaelvserafim/client-api-whatsapp';
const wa = new Wame({ server: "https://us.api-wa.me", key: "YOUR_KEY" });
const app = express();
app.use(express.json());
app.post('/webhook', async (req, res) => {
  res.sendStatus(200);
  const events = parseWebhook(req.body);
  for (const ev of events) {
    if (ev.type === 'text') {
      await wa.message.send({ type: TypeMessage.TEXT, body: { to: ev.from, text: "Recebi: " + ev.text, provider: ev.provider } });
    }
  }
});
app.listen(3000);
```

Repare em dois pontos: o `res.sendStatus(200)` vem **antes** do processamento, e o `ev.provider` é repassado no envio — assim a resposta volta pelo mesmo canal de onde a mensagem chegou.

### PHP

No SDK `raphaelvserafim/client-php-api-wa-me`, o método equivalente é `parseMeta`:

```php
use Api\Wame\Wame;
$wa = new Wame(['server' => 'https://us.api-wa.me', 'key' => 'YOUR_KEY']);
$body = json_decode(file_get_contents('php://input'), true);
$events = $wa->webhook->parseMeta($body);
foreach ($events as $e) {
  if ($e['type'] === 'text') {
    $wa->message->sendText($e['from'], 'Recebi: ' . $e['text']['body'], $e['provider']);
  }
}
```

### Sem SDK — lendo o envelope cru com Express

Se preferir não usar SDK, dá para navegar o envelope diretamente. É útil para entender a estrutura por trás do parser:

```ts
import express from 'express';
const app = express();
app.use(express.json());
app.post('/webhook', (req, res) => {
  res.sendStatus(200);
  const body = req.body;
  const provider = body.provider;
  for (const entry of body.entry || []) {
    for (const change of entry.changes || []) {
      if (change.field !== 'messages') continue;
      for (const msg of change.value.messages || []) {
        if (msg.type === 'text') {
          console.log(provider, msg.from, msg.text.body);
        }
      }
    }
  }
});
app.listen(3000);
```

O caminho é sempre o mesmo: `body.entry[].changes[]`, filtrando por `field` e lendo o `value`. Trocar de WhatsApp para Instagram ou Messenger não muda esse percurso — só o `provider`.

## Passo 4 — Tipos de `field`

O campo `field` de cada `change` diz que tipo de evento chegou. Trate cada um conforme sua necessidade:

- **`messages`** — mensagens recebidas **e** status de entrega (enviado, entregue, lido, falha). É o mais usado.
- **`presence`** — presença do contato ("digitando", online).
- **`connection`** — mudanças de estado da conexão da instância.
- **`qrcode`** — novo QR code disponível (para instâncias não oficiais).
- **`call`** — eventos de chamada.
- **`groups`** — eventos de grupo (entrada, saída, alterações).
- **`health`** — saúde da instância.

Sobre os **status de entrega**: eles chegam dentro de `field: "messages"`, no array `statuses` do `value` (em vez de `messages`). É assim que você acompanha se a mensagem que você enviou foi entregue e lida — essencial para métricas e reenvio.

## Passo 5 — Responder à mensagem no próprio handler

Como visto nos exemplos, responder é só chamar o `send` com o `provider` do evento. O ponto importante é **repassar `ev.provider`**: sem isso, o envio pode ir pelo canal errado. Como o parser já entrega esse campo, basta encaminhá-lo.

Esse padrão fecha o ciclo: chegou uma mensagem no Instagram, seu código responde no Instagram; chegou no WhatsApp, responde no WhatsApp — tudo no mesmo handler, sem `if` por canal para montar a chamada de envio.

## Passo 6 — Boas práticas

- **Responda 200 rápido.** Envie o `200` antes de processar a lógica. Se o seu endpoint demora, a WAME pode considerar falha e reentregar o evento, gerando duplicidade. Processe de forma assíncrona (fila, worker) quando a lógica for pesada.
- **Seja idempotente.** Use o `id` da mensagem (`wamid.XXX`) para ignorar reentregas do mesmo evento.
- **Monitore a entrega.** Consulte as estatísticas do webhook para ver se está tudo chegando:

```bash
curl "https://us.api-wa.me/YOUR_KEY/instance/webhook/statistics"
```

- **Trate os três estados.** No handler, considere sempre o caminho de erro (payload inesperado), o vazio (evento sem `messages`) e o feliz — não só o último.

## Conclusão

Um único endpoint, um único parser e o campo `provider` para diferenciar o canal: é assim que a WAME transforma WhatsApp, Instagram e Messenger em uma superfície só, usando o envelope oficial da Meta. Você escreve o parser uma vez e ele serve para os três.

Comece configurando a instância com `webhookFormat: "meta"` e aponte seu endpoint. Para aprofundar, veja a [documentação de webhooks](/docs/webhooks), o [SDK de TypeScript](/docs/sdk/ts) e o [SDK de PHP](/docs/sdk/php). E se quiser entender como um só conjunto de endpoints atende os três canais, leia [Instagram e Messenger na mesma API do WhatsApp](/blog/api-instagram-messenger-mesma-api-whatsapp).

## Perguntas frequentes

### Como recebo mensagens dos três canais em um só webhook?

Configure a instância com webhookFormat "meta". A WAME entrega os eventos de WhatsApp, Instagram e Messenger no mesmo envelope da Meta Cloud API, mudando apenas o campo provider. Assim você usa um único endpoint e um único parser para os três canais.

### O que é o campo provider no envelope?

É o campo que identifica de qual canal veio o evento: "whatsapp", "instagram" ou "messenger". Como o restante da estrutura é idêntica, seu código lê provider para saber por onde responder, sem precisar de webhooks separados.

### Qual a diferença entre webhookFormat native, meta e both?

native entrega o payload no formato interno da WAME; meta entrega no envelope oficial da Meta Cloud API, reaproveitando os parsers oficiais; both envia os dois formatos. Use meta para padronizar WhatsApp, Instagram e Messenger com o mesmo parser.

### Preciso responder algo ao webhook?

Sim, responda HTTP 200 o mais rápido possível para confirmar o recebimento. Processe a lógica de negócio depois, de forma assíncrona, para evitar timeouts e reentregas. Nos SDKs isso é feito enviando o 200 antes de processar os eventos.

### Como sei se meu webhook está recebendo os eventos?

Consulte GET /{key}/instance/webhook/statistics para ver estatísticas de entrega, incluindo sucessos e falhas. Isso ajuda a diagnosticar endpoints fora do ar, respostas lentas ou URLs mal configuradas.
