Skip to main content
Quando alguém toca num anúncio Click-to-WhatsApp (CTWA) ou num post orgânico e escreve para o seu número da API oficial, a Meta anexa a origem daquele clique à primeira mensagem recebida. A Pilot Status guarda isso, e estes dois endpoints leem de volta: um mensagem por mensagem, outro agregado por anúncio.

Endpoints

GET https://pilotstatus.com.br/v1/referrals GET https://pilotstatus.com.br/v1/referrals/summary
Os dois exigem uma API key escopada a número (ps_*) no header x-api-key. Keys de tenant recebem 403.
Na prática só números da API oficial (Meta) têm origem de anúncio — o bloco de origem é um campo do webhook da Cloud API do WhatsApp, então número conectado por QR code nunca tem.

Nome de campanha, e quando ele vem nulo

A resposta traz os nomes legíveis do anúncio — adName, adsetName, campaignName e os ids correspondentes — ao lado do sourceId cru.
Os cinco campos de nome voltam null enquanto o anunciante não compartilhar a conta de anúncios com a gente, e null é estado suportado, não erro.Ler o nome de um anúncio exige a permissão ads_read na conta de anúncios do próprio anunciante. A forma de conceder isso é o compartilhamento de parceiro da Meta: o anunciante adiciona o portfólio empresarial da Pilot Status como parceiro na conta de anúncios, com “ver desempenho”. Até que ele faça isso, a conversa continua contada e o sourceId continua vindo — só os nomes é que são nulos.Nada que você envie na requisição muda isso. Consultar nunca dispara chamada à Marketing API: a resolução roda de forma assíncrona, fora do caminho da requisição, então um null que você vê agora pode ser um nome segundos depois, sem você fazer nada — veja O primeiro clique em um anúncio novo chega antes dos nomes.
O namesResolvedAt é o que torna os três estados distinguíveis, e cada um pede uma resposta diferente:
O sourceId continua sendo a identidade mesmo com os nomes presentes. Uma campanha pode ser renomeada na Meta a qualquer momento, então quem usa campaignName como chave perde o próprio histórico na primeira vez que o anunciante editar.

O primeiro clique em um anúncio novo chega antes dos nomes

A linha do referral é gravada antes de o seu webhook disparar, então sourceId, sourceUrl, headline e body já podem ser lidos no instante em que o evento chega até você. Os nomes não: eles são resolvidos por um worker separado, que chama a Marketing API da Meta uma vez por anúncio, e essa chamada termina depois que o webhook já saiu. Medido em produção em 53 anúncios: os nomes ficam prontos 0,7s depois da linha da mensagem na mediana, 3,0s no p95 e 5,5s no pior caso. A variação é a latência da própria Meta. Ou seja, uma integração que chama o GET /v1/referrals no instante em que o webhook chega está correndo contra esse worker — e no primeiro clique de um criativo novo ela costuma ganhar a corrida, recebendo o referral com os cinco campos de nome null e namesResolvedAt: null. Isso acontece uma vez por anúncio, só. Todo clique seguinte no mesmo anúncio lê os nomes já em cache e volta preenchido na hora. É exatamente por isso que a mesma integração vê os nomes “às vezes”: as falhas são criativos novos, os acertos são anúncios que já tinham sido clicados.
Receita. Trate namesResolvedAt: null como pergunte de novo, nunca como não existem nomes: repita a mesma consulta ~5s depois e mais uma vez ~60s depois. Assim que namesResolvedAt tiver uma data, a resposta é definitiva — nomes preenchidos são os nomes, nomes nulos significam que falta o compartilhamento de parceiro, e repetir não vai mudar.

Só a primeira mensagem carrega a origem

A Meta envia a origem na primeira mensagem da conversa e nunca repete. Então uma linha em GET /v1/referrals equivale a uma conversa que nasceu daquele anúncio, e conversations no resumo é o número que o seu anúncio realmente produziu.

GET /v1/referrals

Parâmetros de query

string
Restringe a um único id de anúncio/post.
string
ad ou post. Qualquer outro valor devolve 400 INVALID_SOURCE_TYPE.
string
Data-hora ISO 8601. Mensagens a partir de (inclusive) este instante.
string
Data-hora ISO 8601. Mensagens até (inclusive) este instante.
integer
padrão:"1"
Página (≥ 1).
integer
padrão:"30"
Itens por página (1–100).

O objeto referral

Exemplo

GET /v1/referrals/summary

Agrupa os mesmos dados por anúncio, ordenado por número de conversas desc.

Parâmetros de query

string
Data-hora ISO 8601.
string
Data-hora ISO 8601.

Regra de contagem

conversations conta conversas distintas; messages conta mensagens. Duas mensagens na mesma conversa são 1 conversa e 2 mensagens — então conversations é a contagem de leads e messages é o volume. lastSourceUrl e lastHeadline vêm da mensagem mais recente daquele anúncio: a copy pode ser editada, e a última versão que a Meta mandou é a útil.

O teto é informado, não escondido

A lista para em 200 anúncios. Quando houver mais, truncated vem true e um notice avisa — estreite a janela com startDate/endDate em vez de paginar.

Exemplo

Efeito do modo de privacidade (PII)

A identidade do anúncio e a copy do anúncio são tratadas de forma diferente de propósito: um id de anúncio identifica um criativo, nunca uma pessoa, enquanto ctwaClid é um identificador por clique ligado ao indivíduo, e título/texto são conteúdo. É essa divisão que mantém a atribuição de anúncio funcionando num número RELAY_ONLY em vez de devolver nada.

Erros