Para gestores de tráfego

API de Conversões (CAPI) para WhatsApp: como mandar a venda de volta para a Meta, na prática

O que é a CAPI para mensagens, quais eventos e campos a Meta aceita, os erros 2804066, 2804069 e 2804071 e como testar sem contaminar a otimização.

Rastrear conversão no WhatsApp é diferente de rastrear no site por um motivo simples: não existe pixel dentro de uma conversa. O único caminho para a Meta saber que uma conversa virou venda é o seu servidor contar para ela. Esse caminho é a API de Conversões (CAPI), e para mensagens ela tem um vocabulário, campos e validações próprios.

Este guia é técnico e prático. Cobre o que a CAPI de mensagens é, as três origens de evento, a anatomia de um evento válido, o vocabulário aceito, os erros em cadeia que a Meta devolve (com os subcódigos reais), de onde vem o ctwa_clid, como testar sem contaminar a otimização e como tratar deduplicação e reenvio.

O que é a API de Conversões (e por que o pixel não resolve no WhatsApp)

A API de Conversões é uma interface servidor-a-servidor: o seu sistema envia eventos (lead, compra, agendamento) diretamente para um conjunto de dados da Meta, sem depender do navegador. No site, ela complementa o pixel. No WhatsApp, ela é o único canal, porque a conversa não roda num navegador que a Meta consiga observar.

A Meta trata eventos de mensagem como uma categoria própria, com action_source igual a business_messaging. É nessa categoria que a otimização de campanhas de clique para o WhatsApp acontece. A documentação oficial está em Conversions API for Business Messaging, e vale a leitura, mas ela não conta o que dá errado. Este guia conta.

As três origens que interessam a quem vende pelo WhatsApp

action_sourceQuando usarAtribui à campanha?Exige
business_messagingConversa que começou num clique de anúncio de WhatsApp (ou Instagram/Messenger)Sim, pelo ctwa_clidNome de evento do vocabulário de mensagens, identidade do número, ctwa_clid
websiteLead que clicou num link rastreável e foi para o WhatsApp a partir de uma página suaSim, pelo fbclid/fbc e correspondência de dadosevent_source_url, dados do usuário hasheados
chatConversa orgânica (indicação, número salvo, link sem rastreio)NãoDados do usuário hasheados (telefone)

A escolha da origem é por conversa, não por conta. O mesmo número recebe conversas de anúncio (business_messaging), de link do site (website) e orgânicas (chat). Um sistema correto resolve a origem de cada evento a partir do que sabe daquela conversa: houve clique de anúncio com identificador? Houve link rastreável? Nada? A regra é: link rastreável → website; conversa de anúncio com identidade do número → business_messaging; o resto → chat.

Anatomia de um evento de mensagem válido

Um Purchase enviado para business_messaging, com número conectado pelo WhatsApp Business App (sem WABA, então com page_id):

POST https://graph.facebook.com/v21.0/{DATASET_ID}/events
{
  "data": [{
    "event_name": "Purchase",
    "event_time": 1757865600,
    "event_id": "lead-8f2c1a-won",
    "action_source": "business_messaging",
    "messaging_channel": "whatsapp",
    "user_data": {
      "page_id": "123456789012345",
      "ctwa_clid": "ARAo7…(identificador do clique)…",
      "ph": ["<sha256 do telefone em E.164, sem + e sem espaços>"]
    },
    "custom_data": {
      "currency": "BRL",
      "value": 1960.00
    }
  }],
  "access_token": "<token com permissão no dataset>"
}

Campo por campo:

  • event_name: do vocabulário de mensagens (abaixo). Purchase é aceito; Lead não.
  • event_time: timestamp Unix em segundos do momento da venda. Eventos muito antigos são recusados; envie perto do fato.
  • event_id: identificador estável do evento no seu sistema. Permite reenviar sem duplicar.
  • action_source: business_messaging.
  • messaging_channel: whatsapp (ou instagram, messenger).
  • user_data.page_id ou user_data.whatsapp_business_account_id: a identidade do número. WABA quando o número está na API oficial; ID da Página do Facebook que roda os anúncios quando o número é do WhatsApp Business App.
  • user_data.ctwa_clid: o identificador do clique. Sem ele, nada é atribuído.
  • user_data.ph: telefone hasheado com SHA-256, normalizado (só dígitos, com DDI). Melhora a correspondência.
  • custom_data.value e currency: obrigatórios para Purchase se você quer otimização por valor e ROAS no relatório.

Vocabulário de eventos aceito em business_messaging

Os dois que importam para a maioria das operações:

  • LeadSubmitted: lead qualificado. É o equivalente do Lead de site. Lead é rejeitado nesta origem.
  • Purchase: venda, com valor.

Outros eventos padrão (como Schedule, AddToCart, InitiateCheckout, ViewContent) são aceitos conforme o caso de uso. Se a sua integração já usa Lead para site, mantenha um mapeamento na camada de envio: Lead vira LeadSubmitted quando a origem é business_messaging. Guarde o nome efetivamente enviado no seu banco, para o relatório bater com o Gerenciador de Eventos.

Os erros em cadeia e como resolver

A Meta valida em sequência. Cada correção revela o próximo erro. Os subcódigos vêm no campo error_subcode e a explicação em error_user_msg da resposta. Guarde a resposta inteira: é o seu diagnóstico.

SubcódigoO que a Meta dizCausa realCorreção
2804066O nome do evento não é válido para esta origemLead em business_messagingMapear para LeadSubmitted
2804069Não há page_id (ou WABA)Número por QR sem identidade cadastradaEnviar user_data.page_id com o ID da Página que roda os anúncios
2804071Não há ctwa_clidConversa não nasceu de clique, ou o identificador não foi capturadoCapturar no webhook; rebaixar conversa orgânica para chat
190Token inválido ou expiradoToken de usuário vencido, ou permissões removidasRenovar token; preferir token de usuário do sistema

O ponto que engana todo mundo está no 2804071. Depois de corrigir os dois primeiros, os eventos passam a sair como business_messaging e voltam a ser recusados para todas as conversas orgânicas. A regra real da Meta: business_messaging exige identidade do número e clique, juntos. Conversa orgânica nunca é aceita nessa origem, e o correto é enviá-la como chat. Se você olhar os eventos de um cliente novo e ver 100% como chat, não é bug: ele ainda não rodou anúncio de clique para o WhatsApp, e toda conversa é orgânica.

De onde vem o ctwa_clid

O ctwa_clid é gerado pela Meta no clique e entregue com a primeira mensagem da conversa que nasceu daquele anúncio.

  • API oficial (Cloud API): no webhook de mensagem, dentro de messages[].referral, junto com source_id (ID do anúncio), source_type, headline e body do anúncio.
  • WhatsApp Business App conectado por QR (via Evolution API ou similar): nos metadados da mensagem (contextInfo.externalAdReply), com o ctwaClid e o ID do anúncio. É um caminho de melhor esforço, mas funciona na prática e permite atribuir sem migrar o número para a API oficial.

Guarde o ctwa_clid na conversa (não na mensagem) no primeiro contato. Ele é a chave de tudo o que vem depois: atribuição, ROAS por campanha e o envio de eventos. Mais sobre os mecanismos de atribuição em qual anúncio gerou a venda no WhatsApp.

Testando sem contaminar a otimização

  1. No Gerenciador de Eventos, aba "Testar eventos", pegue o test_event_code.
  2. Envie os eventos com o campo test_event_code no corpo. Eles aparecem na aba de teste em segundos, com os erros de validação.
  3. Corrija até ver "recebido" com correspondência do ctwa_clid.
  4. Remova o test_event_code. Evento com código de teste não conta para otimização nem para relatório. Uma integração "funcionando" com o código de teste esquecido é uma integração que não faz nada.
  5. Confirme na aba de visão geral, origem "mensagens de negócios", que os eventos reais estão chegando.

Deduplicação, reenvio e fila

Três cuidados de engenharia que separam uma integração confiável de uma que "às vezes funciona":

  • event_id estável. Derive do ID do lead e do tipo de evento (lead-<id>-won). Reenviar o mesmo evento não cria duplicata.
  • Fila com retentativa. O envio para a Meta não pode acontecer dentro do fluxo que salva a venda. Salve primeiro, enfileire depois. Se a Meta estiver fora, o evento espera; se o seu Redis cair, o evento não pode se perder. Uma varredura periódica que reprocessa o que ficou pendente resolve os casos de borda.
  • Fila de rejeitados com reenvio manual. Guarde a resposta da Meta em cada tentativa e exponha um botão "reenviar" que normaliza o payload antes (por exemplo, rebaixando para chat um evento que perdeu a atribuição). Depois que você corrige o page_id da integração, os rejeitados antigos por 2804069 podem ser reenviados e aceitos.

Fazer na mão ou usar uma ferramenta

Fazer na mão é viável para quem tem desenvolvedor e um cliente só. O trabalho real não está no envio (uma requisição HTTP), está em: capturar o ctwa_clid nos dois tipos de conexão, resolver a origem por conversa, manter o mapeamento de nomes, tratar token expirado, enfileirar com retentativa, guardar a resposta da Meta, expor reenvio, e ligar tudo isso a um funil onde alguém marca "vendido" com valor. Multiplique por cliente.

Uma ferramenta que já faz isso custa menos do que uma semana de desenvolvimento, e o gestor de tráfego passa a olhar para o que importa: qual evento enviar, com que critério, e o que a campanha faz com ele.

Perguntas frequentes

O que é a API de Conversões para WhatsApp?

É a forma de o seu servidor enviar para a Meta eventos que aconteceram dentro de uma conversa (lead qualificado, venda, agendamento), com action_source business_messaging. Como não existe pixel numa conversa, é o único caminho para a Meta atribuir e otimizar campanhas de clique para o WhatsApp.

Por que meus eventos de WhatsApp são rejeitados pela Meta?

Quase sempre por um de três motivos, em ordem: nome de evento inválido (Lead em vez de LeadSubmitted, subcódigo 2804066), falta de identidade do número (page_id ou WABA, 2804069) ou falta de ctwa_clid (2804071). A resposta da Meta traz o subcódigo; guarde-a.

O que é ctwa_clid?

É o identificador do clique num anúncio de clique para o WhatsApp. A Meta o entrega junto com a primeira mensagem da conversa (no referral da API oficial ou nos metadados da mensagem no WhatsApp Business App). Sem ele, o evento não é atribuído a nenhuma campanha.

Posso enviar eventos de conversas orgânicas?

Pode, com action_source chat, para registro e correspondência de dados. Mas eles não são atribuídos a campanhas nem servem para otimizar, porque não têm clique. Enviar orgânicas como business_messaging gera rejeição 2804071.

Preciso da API oficial do WhatsApp (WABA) para usar a CAPI?

Não. Com o número no WhatsApp Business App conectado por QR, a Meta aceita o ID da Página do Facebook que roda os anúncios no campo page_id. O ctwa_clid também chega por esse caminho.

Yuri Gomes

Gestor de tráfego e fundador do RASTRO. Opera campanhas de Meta Ads para negócios que vendem pelo WhatsApp e construiu o RASTRO para resolver o problema que via todo dia: o anúncio gera conversa, a venda fecha no WhatsApp e a Meta nunca fica sabendo.