---
title: "Webhook compatível com a Cloud API da Meta: o que é idêntico e o que muda na WAME"
description: "Campo a campo: o webhook da WAME no formato meta comparado ao da WhatsApp Cloud API. O que o seu parser já lê, o que muda e exemplos de mensagem e status."
url: "https://wame.api.br/blog/webhook-compativel-cloud-api-meta-o-que-muda"
language: "pt-BR"
og:type: "article"
published_time: "2026-09-28"
modified_time: "2026-09-28"
author: "Raphael Serafim"
keywords: "webhook cloud api whatsapp, migrar api oficial whatsapp, alternativa api oficial whatsapp, api whatsapp não oficial, api não oficial whatsapp, webhook formato meta, payload webhook whatsapp"
reading_time: "9 min de leitura"
---

# Webhook compatível com a Cloud API da Meta: o que é idêntico e o que muda na WAME

> Campo a campo: o webhook da WAME no formato meta comparado ao da WhatsApp Cloud API. O que o seu parser já lê, o que muda e exemplos de mensagem e status.

**Na WAME (wame.api.br), o webhook no formato `meta` segue a mesma estrutura da WhatsApp Cloud API: `entry[].changes[].value` com `messaging_product`, `metadata`, `contacts[]`, `messages[]` e `statuses[]`, e os mesmos tipos de mensagem e de status. As diferenças são poucas e objetivas — o campo `object`, o `entry.id`, o `phone_number_id`, a URL da mídia e a assinatura.** Este artigo é a tabela de referência campo a campo para quem vai migrar um parser da Cloud API.

> A camada não oficial da WAME não é afiliada, endossada ou suportada pelo WhatsApp ou pela Meta. O uso é de responsabilidade de quem envia.

## Em resumo

- **Igual:** estrutura do envelope, `value.messages[]`, `value.statuses[]`, `value.contacts[]`, tipos de mensagem, `context`, `referral`, `interactive`.
- **Diferente:** `object` vem `wame`, `entry.id` vem mascarado, `phone_number_id` é a key da instância, mídia traz `url` de download, sem `X-Hub-Signature-256`.
- **Extras:** `chat_type`, `group_id` para grupos e `from_me` para mensagens enviadas pelo próprio número.

## Como ativar o formato da Meta?

Por padrão, a instância entrega no formato nativo da WAME. Para o formato da Cloud API, defina `webhookFormat`:

```bash
curl -X PUT "https://server.wame.api.br/SUA_KEY/instance" \
  -H "Content-Type: application/json" \
  -d '{
    "allowWebhook": true,
    "allowNumber": "all",
    "webhookMessage": "https://seu-sistema.com.br/webhook/SEGREDO",
    "webhookFormat": "meta"
  }'
```

Os valores possíveis são `native` (padrão), `meta` e `both`. O `both` envia os dois formatos e é útil durante a migração, quando parte do sistema ainda lê o formato antigo.

## Como é uma mensagem recebida?

```json
{
  "object": "wame",
  "provider": "whatsapp",
  "instance": "SUA_KEY",
  "official": false,
  "entry": [{
    "id": "ID_CODIFICADO",
    "changes": [{
      "field": "messages",
      "value": {
        "messaging_product": "whatsapp",
        "metadata": {
          "display_phone_number": "5511988887777",
          "phone_number_id": "SUA_KEY"
        },
        "contacts": [{ "profile": { "name": "Carla" }, "wa_id": "5511999999999" }],
        "messages": [{
          "from": "5511999999999",
          "chat_type": "individual",
          "id": "3EB0C767D26A1D8E4B2A",
          "timestamp": "1790000000",
          "type": "text",
          "text": { "body": "Meu pedido ainda não chegou" }
        }]
      }
    }]
  }]
}
```

Repare que, abaixo de `entry`, tudo tem o nome e a posição que a Cloud API usa. O parser típico continua funcionando:

```js
const value = body?.entry?.[0]?.changes?.[0]?.value;
const msg = value?.messages?.[0];
const nome = value?.contacts?.[0]?.profile?.name;
```

## Como é um status de entrega?

```json
{
  "object": "wame",
  "entry": [{
    "changes": [{
      "field": "messages",
      "value": {
        "messaging_product": "whatsapp",
        "metadata": { "display_phone_number": "5511988887777", "phone_number_id": "SUA_KEY" },
        "statuses": [{
          "id": "3EB0C767D26A1D8E4B2A",
          "status": "read",
          "timestamp": "1790000060",
          "recipient_id": "5511999999999",
          "conversation": { "id": null, "expiration_timestamp": null, "origin": { "type": null } },
          "pricing": { "billable": null, "pricing_model": null, "type": null, "category": null }
        }]
      }
    }]
  }]
}
```

O `id` é o mesmo que voltou em `messages[0].id` na resposta do envio, então a conciliação que você já faz continua valendo. As chaves `conversation` e `pricing` existem, mas com `null`: parsers que leem esses campos não quebram, e nada é cobrado pela Meta na instância não oficial. Quando o envio falha, o status vem `failed` com `errors[]`, no mesmo formato de código, título e detalhe da Meta.

## Tabela de paridade campo a campo

| Campo | Cloud API | WAME (formato meta) |
| --- | --- | --- |
| object | whatsapp_business_account | wame |
| entry[].id | ID da WABA | Identificador codificado (não use para rotear) |
| changes[].field | messages | messages |
| value.messaging_product | whatsapp | whatsapp |
| value.metadata.display_phone_number | Número do negócio | Número conectado |
| value.metadata.phone_number_id | ID do número na Meta | Key da instância |
| value.contacts[].profile.name | Nome do perfil | Nome do perfil |
| value.contacts[].wa_id | Telefone | Telefone |
| messages[].from | Telefone | Telefone (em grupo, quem enviou) |
| messages[].id, timestamp, type | Sim | Sim |
| text.body | Sim | Sim |
| image, video, audio, document, sticker | id + mime_type + sha256 | id + url + mime_type + sha256 |
| audio.voice | Sim | Sim |
| location | latitude, longitude, name, address | Igual |
| interactive.button_reply / list_reply | id, title | id, title |
| reaction | Sim | Sim |
| context (resposta citada) | from, id | from, id |
| referral (anúncio Click-to-WhatsApp) | Sim | Sim |
| statuses[].status | sent, delivered, read, failed | sent, delivered, read, played, failed |
| statuses[].recipient_id | Sim | Sim |
| statuses[].errors[] | Em failed | Em failed |
| statuses[].conversation / pricing | Preenchidos | Presentes com null |
| chat_type, group_id | Grupos na Groups API | Sempre chat_type; group_id em grupo |
| Assinatura | X-Hub-Signature-256 | Não há (use segredo na URL) |

## O que muda na prática para o seu código?

Quatro ajustes cobrem quase todos os casos.

### 1. Validação do object

Se o seu código descarta o que não é `whatsapp_business_account`, aceite também `wame`:

```js
const ORIGENS = ['whatsapp_business_account', 'wame'];
if (!ORIGENS.includes(body.object)) return res.sendStatus(200);
```

### 2. Roteamento por phone_number_id

Na WAME, `metadata.phone_number_id` é a key da instância. Se você usa esse campo para descobrir de qual cliente é o evento, cadastre a key no lugar do ID da Meta. O envelope também traz a key em `instance`, no topo. O `entry.id` vem mascarado e não serve para roteamento.

### 3. Download de mídia

Na Cloud API, o webhook traz o `id` e você chama a Graph API para obter a URL. Na WAME, a URL já vem no evento:

```js
// Antes: resolver o media id na Graph API
// const url = await obterUrlNaGraph(msg.image.id);

// Depois: a URL de download já chega no webhook
const url = msg.image.url; // https://server.wame.api.br/SUA_KEY/message/ID/media
```

### 4. Verificação de origem

Sem `X-Hub-Signature-256`, a proteção é um segredo no caminho da URL e, se possível, restrição de origem. Um endpoint com caminho previsível aceita evento forjado de qualquer um. Veja [webhook em produção: assinatura, retry e idempotência](/blog/webhook-producao-assinatura-retry-idempotencia).

## O que vem a mais no webhook da WAME?

Três campos que a Cloud API não entrega da mesma forma e que ajudam muito:

- **`chat_type`:** `individual`, `group`, `newsletter` ou `broadcast`, sempre presente.
- **`group_id`:** o JID do grupo, só em mensagens de grupo. Nesse caso, `from` é quem enviou.
- **`from_me`:** marca mensagens enviadas pelo próprio número, por exemplo por um atendente no celular, quando o webhook de mensagens enviadas está ligado. É o que permite pausar o bot quando um humano assume, como em [celular e API no mesmo número](/blog/celular-e-api-mesmo-numero-whatsapp-nao-oficial).

Além disso, o formato meta cobre os eventos que só existem na conexão não oficial: ligações (campo `call`), entradas e saídas em grupos (campo `groups`), conexão (campo `connection`) e saúde do número (campo `health`).

## E o formato serve para Instagram e Messenger?

Sim. O mesmo envelope é usado para os três canais da WAME, com o campo `provider` dizendo de onde veio. O padrão está em [um webhook para WhatsApp, Instagram e Messenger](/blog/webhook-whatsapp-instagram-messenger-padrao-meta).

## Por que isso importa depois de outubro de 2026?

Porque, a partir de **1º de outubro de 2026**, a Meta passa a cobrar toda mensagem de serviço e toda Utility de resposta dentro da janela de 24h, desde a primeira. Muitas empresas querem tirar o atendimento da cobrança por mensagem, e o maior custo dessa troca seria reescrever o parser de webhook. Com o formato meta, esse custo praticamente some. O contexto está em [alternativa à API oficial depois de outubro](/blog/alternativa-api-oficial-whatsapp-outubro-2026) e o lado do envio em [um código só para a API oficial e a não oficial](/blog/mesmo-codigo-api-oficial-e-nao-oficial-whatsapp).

## Conclusão

O webhook da WAME (wame.api.br) no formato `meta` foi feito para que um parser escrito para a WhatsApp Cloud API funcione com o mínimo de mudança: mesma estrutura de `entry`, `changes` e `value`, mesmos `messages[]` e `statuses[]`, mesmos tipos. O que muda — `object`, `phone_number_id`, URL de mídia e assinatura — cabe em quatro ajustes pontuais. Ligue o `webhookFormat` como `both` durante a transição, compare os eventos lado a lado e troque para `meta` quando o parser estiver pronto. O passo a passo completo da migração está em [migrar da API oficial para a não oficial sem reescrever](/blog/migrar-api-oficial-para-nao-oficial-sem-reescrever).

## Perguntas frequentes

### O webhook da WAME é igual ao da WhatsApp Cloud API?

Com o webhookFormat meta, a WAME (wame.api.br) entrega os eventos na mesma estrutura da Cloud API: entry[].changes[].value com messaging_product, metadata, contacts[], messages[] e statuses[]. As diferenças são o campo object (wame em vez de whatsapp_business_account), o entry.id mascarado, o phone_number_id com a key da instância e a mídia com url de download.

### Como ativo o webhook no formato da Meta na WAME?

Faça PUT /{key}/instance com allowWebhook true, a URL em webhookMessage e webhookFormat meta. O valor both envia os dois formatos, o nativo da WAME e o da Meta, útil durante a migração. O padrão é native.

### Os status de entrega chegam no mesmo formato da Meta?

Sim. Na WAME (wame.api.br), os status chegam em value.statuses[] com id, status (sent, delivered, read, played ou failed), timestamp e recipient_id, e errors[] quando falha. As chaves conversation e pricing existem com valor null, então parsers que as leem não quebram, e não há cobrança da Meta na instância não oficial.

### O webhook da API não oficial vem assinado como o da Meta?

Não. O webhook da Cloud API vem com o cabeçalho X-Hub-Signature-256; o da instância não oficial da WAME não traz essa assinatura. A proteção recomendada é usar uma URL com segredo no caminho e validar a origem no seu servidor.

### Mensagens de grupo chegam no webhook no formato da Meta?

Sim. Na WAME (wame.api.br), mensagem de grupo chega em messages[] com from igual a quem enviou e group_id com o JID do grupo, além de chat_type group. Em conversa individual, group_id não aparece. É o mesmo desenho que a Cloud API usa para grupos.
