Diagnóstico técnico de ago/2026: por que a origem dos leads de anúncio estava cega e o que faltava para enxergá-la. Desfecho (out/2026): a Zeeps saiu do ar, a POSTEP assumiu o webhook do WhatsApp (takeover) e a atribuição CTWA está ao vivo — sem depender de ninguém no meio do caminho. O registro abaixo é o diagnóstico original; ele conta como se chegou até aqui.
O caminho era linear até o Ploomes. O referral (a etiqueta do anúncio) viajava colado na 1ª mensagem — mas sumia depois da Zeeps. Hoje não é mais assim: o webhook aponta para a POSTEP (ver desfecho no topo).
→ A POSTEP recebe o contato, mas o referral já morreu 3 nós antes. Resultado: contato sem origem = atribuição cega.
É o objeto que o Meta anexa na primeira mensagem de quem veio de um anúncio Click-to-WhatsApp. Destacado = os únicos campos que a POSTEP precisa.
// WhatsApp Cloud API — payload da mensagem de entrada (entry[0].changes[0].value) { "contacts": [{ "wa_id": "5562XXXXXXXX" // ← telefone do lead (a CHAVE do casamento) }], "messages": [{ "from": "5562XXXXXXXX", "timestamp": "1722801600", "type": "text", "referral": { "source_type": "ad", "source_id": "120210000000000000", // ← AD ID — QUAL anúncio "ctwa_clid": "ARAaZ...c2c==", // ← click-id único do clique "headline": "FEIRÃO do Revendedor", // ← título do anúncio "source_url": "https://fb.me/...", "media_type": "image" } }] }
→ Precisamos de 5 campos: telefone ctwa_clid source_id (ad_id) headline timestamp. Nada de conteúdo de conversa, nada de PII sensível.
Antes de pedir, tentamos por fora. A própria API do Meta barrava — e o motivo era técnico e definitivo. Na época, isso mostrava por que a Zeeps era indispensável no caminho. O que destravou foi outro: o número migrou de WABA e o webhook passou a apontar para a POSTEP (ver desfecho no topo).
Tentamos assinar o webhook da WABA com o app da POSTEP.
GET /{waba}/subscribed_apps → code 10: "requires that the Business that owns this App is a Business Solution Provider for WhatsApp"
O número tem override de webhook no nível do telefone.
GET /{phone_id}?fields=webhook_configuration → { "application": "https://maispvc-api.zeeps.com.br /whatsapp/webhook" }
→ Conclusão honesta: não dá pra contornar. O dado passa pela Zeeps por desenho do Meta. Por isso a solução é com a Zeeps, não em volta dela.
Ordenadas da mais simples pra mais trabalhosa. Qualquer uma resolve. A A é a que menos mexe em vocês.
A Zeeps faz um POST espelho do referral+telefone pra uma URL nossa, no mesmo instante que processa a mensagem.
A Zeeps expõe um GET por telefone/sessão que devolve o referral. A POSTEP consulta quando o contato aparece no CRM.
A Zeeps/Neppo escreve ctwa_clid num campo do contato no Ploomes. A POSTEP lê do espelho que já tem.
Com o fork ligado, a POSTEP casa o telefone com o contato que já espelha do Ploomes e preenche a origem. O atendimento (Zeeps→Neppo→Ploomes) continua idêntico.
→ Casamento por telefone (mesma chave que o Ploomes usa). Idempotente por ctwa_clid — reenvio não duplica. As colunas de destino já existem na base da POSTEP.
✓ Foi exatamente isto que passou a valer — só que, com a Zeeps fora do ar, o webhook do WhatsApp chega direto na Edge da POSTEP (takeover), sem precisar de um fork da Zeeps. O ramo do atendimento (Neppo → Ploomes) seguiu intacto.
Endpoint pronto do nosso lado. Basta a Zeeps disparar este POST. Payload mínimo, autenticado por segredo compartilhado.
# Requisição (Zeeps → POSTEP) — endpoint JÁ NO AR ✓ POST https://tiaeuczudlrhduveikfa.supabase.co /functions/v1/posteptrack-maispvc Content-Type: application/json X-Zeeps-Token: <segredo combinado> { "phone": "5562XXXXXXXX", "ctwa_clid": "ARAaZ...c2c==", "ad_id": "120210000000000000", "headline": "FEIRÃO do Revendedor", "occurred_at":"2026-08-04T12:00:00Z" }
# Resposta 200 { "ok":true, "matched":true } 200 { "ok":true, "matched":false } // guardado; casa quando o // contato entrar no CRM # Garantias do lado POSTEP ✓ idempotente por ctwa_clid ✓ read-only sobre o WhatsApp ✓ não escreve em Ploomes/Neppo ✓ só telefone como PII
→ Alternativa sem segredo custom: aceitamos Authorization: Bearer. Formato do payload é flexível — se for mais fácil mandar o objeto cru do Meta, a gente extrai.
Levantado direto na Graph API do Meta com token de leitura. Serve para a engenharia da Zeeps/Neppo conferir contra o ambiente de vocês.
Cada bloco é uma chamada real GET na Graph API do Meta (v21.0) e a resposta exata. Token omitido. Só leitura — nenhum POST/PATCH foi feito. A engenharia da Zeeps/Neppo pode reproduzir com o token de vocês.
PROVA 1 — o número do CTWA é Cloud API e seu webhook aponta pra Zeeps
{
"id": "627061130480155",
"display_phone_number": "+55 62 4008-0288",
"verified_name": "MAISPVC",
"platform_type": "CLOUD_API",
"account_mode": "LIVE",
"code_verification_status": "EXPIRED",
"webhook_configuration": {
"application": "https://maispvc-api.zeeps.com.br/whatsapp/webhook"
},
"throughput": { "level": "STANDARD" }
}
PROVA 2 — a POSTEP não é BSP: gerir o webhook é bloqueado pelo próprio Meta
// tentativa de ler/assinar o webhook da WABA com o app da POSTEP { "error": { "message": "You do not have permission to perform this action. This action requires that the Business that owns this App is a Business Solution Provider for WhatsApp.", "code": 10 } }
PROVA 3 — o token é de produção e enxerga o WhatsApp (não é limitação de permissão nossa)
{
"type": "SYSTEM_USER",
"expires_at": 0, // não expira
"app_id": "438596295351682",
"scopes": [ …,
"whatsapp_business_management",
"whatsapp_business_messaging",
"whatsapp_business_manage_events" ]
}
→ temos os escopos de WhatsApp — mesmo assim a PROVA 2 barra. Confirma que o gargalo é ser BSP, não permissão de token.
PROVA 4 — as WABAs do número, lado a lado: a viva (Cloud) e a legada (migração)
WABA nº plataforma webhook/apps 1306877327201750 62 4008-0288 CLOUD_API → Zeeps (subscribed_apps: erro/BSP) 372328902641103 62 4008-0288 NOT_APPLICABLE app 438596295351682 (legada, DECLINED) 1757570392080246 62 9948-3173 CLOUD_API (Cobrança — outro nº) 389253124269916 +1 555-008-6701 CLOUD_API (Test)
→ o tráfego vivo do CTWA passa pela 1306… (Cloud) → Zeeps. A 372… é resquício de migração, sem uso.
Reprodutível: GET graph.facebook.com/v21.0/<id>?fields=…&access_token=<seu_token> — 100% leitura.