Conecte o Meta Ads ao seu Node
O Meta te diz quanto você gastou e quantas conversões ele acha que gerou. O seu Node sabe quanto realmente entrou. Conectar a conta de anúncios coloca as duas coisas na mesma tela — dentro do seu servidor, sem entregar a sua receita para ninguém conferir a própria prova.
Tempo estimado: 15 minutos de configuração, mais algumas horas até os 90 dias de histórico terminarem de chegar.
Comece pela tag. O ROAS por anúncio só existe se o criativo carregar
utm_content={{ad.id}}. Sem esse macro, a coluna de receita atribuída volta zero — e zero parece performance ruim, não falta de tagueamento. É a Etapa 1 por um motivo: ela só vale para os cliques que acontecerem depois de você aplicá-la.
O que você passa a ter
No Console, em Insights → Meta Ads:
| Bloco | O que mostra |
|---|---|
| Linha de indicadores | Investimento, Impressões, Cliques, CTR, CPM, CPC, Conversões e CPA do período. |
| Entrega diária | A série dia a dia, alternando entre investimento, impressões, cliques e conversões. |
| ROAS da conta | A receita total que o seu Node registrou no período contra o investimento total em anúncios, com a quebra por status da compra. |
| Tabela por entidade | Investimento por Anúncio, Conjunto ou Campanha — e, quando você liga Receita atribuída, a receita e o ROAS de cada anúncio. |
O que você não ganha: uma segunda fonte de verdade sobre o que a Meta entregou. Impressões, cliques e conversões continuam sendo o número que a Meta reporta. O que muda de lado é a receita: ela vem do seu Node, das compras que ele registrou, e não da conversão que a plataforma se atribuiu.
Nada disso passa pelo Supreme. O Console lê direto do seu Node, o token da Meta fica gravado no seu servidor, e o System nunca vê investimento, receita nem evento.
Esta não é uma integração de catálogo. Não existe módulo para instalar em Integrações → Gerenciar Módulos — a leitura de anúncios faz parte do Node a partir da versão
4.0.0.
Antes de começar
| Requisito | Onde conferir |
|---|---|
Node na versão 4.0.0 ou mais recente |
Se Insights não aparece no menu lateral do Console, o seu Node ainda não está na 4.0.0. Atualize antes de seguir. |
| Uma Propriedade ativa | Console → Propriedades. Os dados de anúncio são guardados por Propriedade; sem nenhuma criada, o Console recusa a conexão. Veja Crie sua primeira Propriedade. |
| Compras chegando ao Node | Console → Eventos. Sem purchase registrado, existe investimento e não existe receita — o ROAS fica vazio, corretamente. |
| Acesso à conta de anúncios da Meta | Você precisa conseguir gerar um token que leia aquela conta. |
| O id numérico da conta de anúncios | É a parte depois de act_. Em act_1234567890, o id é 1234567890. |
Uma conta de anúncios por Propriedade. Salvar de novo na mesma Propriedade substitui a conexão anterior.
Etapa 1 — Coloque o macro utm_content nos criativos
Este é o passo que quase todo mundo pula, e é o que decide se o relatório vai servir para alguma coisa.
O Supreme liga uma venda a um anúncio pelo valor que chegou em utm_content. A Meta preenche esse valor sozinha, se você pedir, através de um macro dinâmico.
Onde colar
No Meta Ads Manager, no nível do anúncio, no campo URL parameters (fica na seção de rastreamento, junto do destino do anúncio). Cole:
utm_content={{ad.id}}
Se você já usa outros parâmetros nesse campo, junte com &:
utm_source=meta&utm_medium=cpc&utm_campaign={{campaign.name}}&utm_content={{ad.id}}
A Meta troca {{ad.id}} pelo id numérico do anúncio no momento do clique. Você não digita id nenhum, e não precisa mexer em nada quando duplicar um anúncio.
Atribuir por nome, se você preferir
O Supreme também aceita atribuir pelo nome do criativo:
utm_content={{ad.name}}
Nesse caso, na tabela do Console, troque o seletor de atribuição de ID do anúncio para Nome do anúncio.
O que isso custa: nome não é único. Dois anúncios que compartilham o mesmo nome são tratados como o mesmo criativo — as duas linhas mostram exatamente a mesma receita atribuída, o mesmo número de vendas e o mesmo ROAS. Só use este modo se a sua nomenclatura de anúncios realmente identifica uma peça específica. Na dúvida, use o id.
O que precisa sobreviver até a venda
O cruzamento usa o utm_content que ficou gravado na venda, não na primeira página visitada. Duas consequências práticas:
- Preserve a query string nos redirecionamentos. Encurtador, redirect de domínio ou página intermediária que descarta a query string apaga o
utm_contentantes da compra acontecer. - Uma venda que chega ao Node só por webhook não carrega
utm_content. Ela entra na receita total — e portanto no ROAS da conta — mas não aparece na coluna de receita atribuída daquele anúncio.
O Console avisa quando falta
Se você ligar Receita atribuída, agrupar por Anúncio e todas as linhas voltarem com zero vendas, o Console mostra o aviso Nenhuma compra cruzou com estes anúncios com o macro correto já pronto e um botão Copiar. Esse aviso quer dizer "sem tagueamento", não "sem retorno".
Etapa 2 — Gere um token da Meta com ads_read
O token vem da Meta, não do Supreme. Ele precisa de uma coisa só: conseguir ler a conta de anúncios — o que na prática significa a permissão ads_read sobre aquela conta.
Dois caminhos, com propósitos diferentes:
| Caminho | Serve para | Cuidado |
|---|---|---|
| Token de usuário gerado no Graph API Explorer da Meta | Provar em cinco minutos que a conexão funciona. | É curto. Quando ele expirar, a conexão vai para Token recusado e a sincronização para. |
| Token de usuário do sistema (System User) no Meta Business Manager, com acesso à conta de anúncios | Produção. | É o caminho certo. Não morre junto com a sua sessão pessoal. |
As telas da Meta mudam com frequência, então não vale a pena decorar caminho de menu: procure por ads_read e por "system user access token" na documentação da própria Meta. Qualquer token serve para o Supreme desde que consiga ler a conta — quem decide isso é a verificação da Etapa 3, não você.
Trate o token como senha. Ele não vai para o GTM, nem para o site, nem para uma captura de tela em um ticket de suporte.
Etapa 3 — Conecte a conta no Console
- Abra Insights → Meta Ads.
- Clique em Conectar conta de anúncios.
- Escolha a Property que vai receber esses dados.
- Em ID da conta de anúncios, informe o id numérico. Pode colar com
act_na frente — o Console remove. - Cole o Token de acesso.
- Deixe a Janela de atribuição no padrão
7d_click,1d_view, a menos que você use outra na Meta. Esse valor é o que o Node informa à Meta ao puxar os números. - Confirme que Ativa está marcado.
- Clique em Salvar.
O botão passa por Validando com a Meta… antes de gravar. O Node verifica o token contra a conta antes de armazenar qualquer coisa. Um token que não consegue ler a conta é recusado na hora, em vez de virar uma conexão que parece certa no Console e nunca sincroniza nada.
Dessa mesma verificação vêm o nome da conta, a moeda e o fuso horário que aparecem no card. Você não digita nenhum dos três — eles são lidos da Meta.
Se der certo, o Console avisa: "Conta de anúncios conectada. O Node começou a puxar os últimos 90 dias."
Se a conexão for recusada
O Console mostra a recusa acima do botão. Quando a negativa vem da Meta, a mensagem é repassada como a Meta escreveu, em inglês, com o código dela na frente — algo como [190/-] Invalid OAuth access token. Não tente traduzir: o código é o que importa.
| Situação | Causa | O que fazer |
|---|---|---|
| O campo do id reclama antes de qualquer chamada | Você colou algo que não é numérico. | Use só os dígitos, com ou sem act_ na frente. |
A Meta devolve um erro de token (190 e vizinhos) |
Token errado, expirado ou revogado. | Gere um token novo. |
| A Meta responde que a conta não existe ou não está acessível | O id está certo mas o token não enxerga essa conta, ou o id não existe. | Confirme que o token foi gerado com acesso àquela conta. |
| O Node diz que a conta não devolveu moeda e fuso | O token lê alguma coisa, mas provavelmente não tem ads_read naquela conta. |
Refaça o token incluindo ads_read. |
| A Meta responde limite de requisições | Nada errado com você. | Espere alguns minutos e salve de novo. |
| O Console pede para criar uma Propriedade primeiro | O Node não tem nenhuma Propriedade, e os dados de anúncio são guardados por Propriedade. | Crie uma em Propriedades e volte. |
O token nunca é mostrado de novo
Depois de salvo, o token não sai mais do Node. Nem por API, nem pelo Console, nem por MCP.
O que você vê no card da conexão, no campo Token, é só uma prévia mascarada — os quatro primeiros caracteres, reticências, os quatro últimos — e o estado Armazenado ou Não armazenado. Se o token tiver 12 caracteres ou menos, a prévia vira só asteriscos.
Isso é proposital, não uma funcionalidade faltando. Para trocar o token, abra Editar e cole um novo; deixar o campo vazio mantém o que já está gravado.
Etapa 4 — Deixe o histórico de 90 dias chegar
Salvar a conexão agenda um histórico de 90 dias. Ele não vem de uma vez: o Node puxa em blocos, para não estourar o tempo de execução do servidor nem o limite de requisições da Meta.
Enquanto o Console está aberto
Assim que você salva, o Console já começa a puxar. O card da conexão mostra Puxando histórico — faltam N dias, com uma barra de progresso e o intervalo que está sendo buscado. A faixa de status no topo mostra "Sincronizando — faltam N dias de histórico."
Você pode disparar mais blocos a qualquer momento com o botão Sincronizar. Cada clique encadeia vários blocos seguidos, então normalmente um clique resolve o resto do histórico.
Fechar o Console não perde progresso. Cada bloco é gravado no momento em que termina. A sincronização é idempotente: repetir um intervalo não duplica nada, apenas reescreve os mesmos dias.
Se aparecer "Outra execução está com o lock da sincronização", é só o cron ou outra aba trabalhando ao mesmo tempo. Não é erro — o trabalho continua sozinho.
Sem o Console aberto: configure um cron
Este é o passo que decide se os números continuam se atualizando sozinhos. O System dispara o
cron.phpapenas nos Nodes cuja licença carrega o nível de acesso pro. Em qualquer outro Node, nada chama o cron por você: o histórico só avança enquanto alguém tem o Console aberto, e o investimento de ontem só entra quando alguém abre a tela.
A solução é um cron nativo no seu próprio servidor, de hora em hora, apontando para:
https://SEU-NODE/cron.php?key=SUA_AGENT_KEY
O Console monta essa URL pronta para você: enquanto o histórico está sendo puxado, o card da conexão mostra o campo Cron horário com a URL completa e um botão Copiar.
No cPanel, em Cron Jobs, uma linha de hora em hora:
0 * * * * curl -s "https://SEU-NODE/cron.php?key=SUA_AGENT_KEY" > /dev/null
Esse cron não serve só para os anúncios — é o mesmo agendamento que fecha sessões, reprocessa entregas que falharam e limpa logs antigos. Vale configurar mesmo que você nunca conecte uma conta de anúncios.
Quando o histórico termina
A faixa de status mostra "Os dados de anúncios estão atualizados." e o card passa a mostrar apenas Sincronizado até e Última sincronização.
A partir daí o Node mantém os dados frescos sozinho. Quando tudo já está presente, ele só volta a chamar a Meta depois que a última sincronização passa de aproximadamente 20 horas — e, quando volta, repuxa os últimos 7 dias, não só o dia novo. Isso existe porque a Meta ajusta investimento e conversões retroativamente: um número de três dias atrás ainda pode mudar.
Como ler os números
ROAS da conta e ROAS por anúncio são coisas diferentes
O painel ROAS da conta divide toda a receita que o seu Node registrou no período pelo total investido. Ele não pergunta de onde veio cada venda. É o número que responde "esse mês fechou no azul?".
A coluna ROAS atrib. da tabela é outra pergunta: dentro daquele anúncio, quanta receita o Node conseguiu amarrar àquele anúncio, contra o que aquele anúncio gastou.
Os dois vão divergir, e isso está certo. A receita que veio de e-mail, de tráfego orgânico ou de um anúncio sem tag entra no ROAS da conta e não entra em nenhuma linha da tabela.
A Receita aprovada soma os status approved, paid, completed, complete e authorized. A tabela Receita por status da compra mostra a quebra completa, para você ver quanto ficou de fora e por quê.
Traço não é zero
Nas colunas atribuídas:
- um traço significa que o Node não cruzou aquela linha;
- um zero significa que ele cruzou e não encontrou venda.
O cruzamento só acontece por Anúncio. Agrupado por Conjunto ou Campanha, o Node não devolve atribuição — uma venda carrega o anúncio de onde veio, não o conjunto — e as colunas ficam com traço.
Fuso horário: por que a comparação pode andar um dia
Se a conta de anúncios estiver em um fuso e o Node em outro, o dia de investimento e o dia de receita não cobrem as mesmas 24 horas. O investimento é somado pelo calendário da conta de anúncios; a receita, pelo calendário do Node.
No meio de um período longo isso praticamente se anula. Nas bordas — o primeiro e o último dia — a comparação pode deslocar em até um dia.
O Console avisa quando detecta a diferença, tanto no card da conexão quanto no painel de ROAS. Não dá para corrigir: os dois lados entregam totais por dia, cada um no seu calendário, e não existe informação suficiente para reparticionar isso por hora. Leia a razão como aproximação e prefira períodos de 7 dias ou mais.
Moeda
O investimento sai na moeda da conta de anúncios; a receita, na moeda do Node. Quando as duas diferem, o Console diz que a razão mistura duas moedas e não converte. Não existe conversão de câmbio embutida.
Por que Hoje costuma vir vazio
A sincronização vai até ontem, no calendário da conta de anúncios. Números do dia corrente ainda estão se formando do lado da Meta e mudam ao longo do dia. Use Ontem, 7d ou um período fechado para leituras que você vai comparar.
Traço nos indicadores
CPM, CPC, CPA e ROAS aparecem como traço quando o denominador é zero — sem impressões não há CPM, sem conversões reportadas não há CPA. Um traço ali significa "não há o que dividir", não "zero".
Manutenção
Trocar o token
Abra Editar na conexão, cole o token novo e salve. Deixar o campo Token de acesso vazio mantém o que já está gravado — útil quando você só quer mudar a janela de atribuição ou pausar.
É isso que você faz quando o card mostra Token recusado: o token expirou ou foi revogado do lado da Meta, e o Node não tem como renovar sozinho.
Trocar a conta de anúncios
Mudar o ID da conta de anúncios de uma conexão existente zera os marcadores de sincronização e recomeça um histórico de 90 dias. O Console avisa antes. Não é o caminho para "corrigir um dígito" sem custo.
Pausar
Desmarque Ativa e salve. A conexão para de sincronizar e continua listada como Pausada, com todo o histórico intacto. É o caminho certo para uma parada temporária.
Desconectar
Clique no ícone de lixeira da conexão e confirme em Confirmar desconexão.
Desconectar mantém o histórico já sincronizado. Reconectar a mesma conta depois não recomeça do zero — é justamente para isso que o padrão é manter.
Apagar o histórico é uma escolha explícita: marque Apagar também o histórico de insights desta conta antes de confirmar, e o botão muda para Desconectar e apagar histórico. Essa remoção não tem volta.
Em nenhum dos casos o Supreme mexe em campanha, público ou configuração do lado da Meta. Desconectar aqui só interrompe a leitura.
Resolução de problemas
O card mostra Token recusado
O token expirou, foi revogado, ou perdeu o acesso à conta. Gere um novo com ads_read, abra Editar e cole. A sincronização retoma de onde parou. Se você usou um token do Graph API Explorer, isso vai acontecer de novo — troque por um token de usuário do sistema.
O card mostra Limite de requisições
A Meta está limitando as chamadas dessa conta. A sincronização parou exatamente onde estava e nada foi perdido. Espere alguns minutos e clique em Sincronizar. Se acontecer todo dia, é sinal de que a mesma conta está sendo lida por várias ferramentas ao mesmo tempo.
A tabela está vazia mas a conta está Conectada
Amplie o período. A sincronização vai até ontem, e uma conta conectada há poucos minutos ainda pode não ter nenhum dia gravado. Se continuar vazio em 30d, clique em Sincronizar e acompanhe a faixa de status.
Todos os valores de receita atribuída são zero
É tagueamento, não performance. Confira, nesta ordem:
- O criativo carrega
utm_content={{ad.id}}no campo URL parameters do anúncio? - O seletor da tabela está em ID do anúncio — ou em Nome do anúncio, se você usou
{{ad.name}}? - Os cliques que geraram essas vendas aconteceram depois de você aplicar o macro? Ele não é retroativo.
- A query string sobrevive aos redirecionamentos até a página onde a compra é registrada?
- Essas vendas chegam pelo navegador, ou só por webhook? Venda que só chega por webhook não carrega
utm_content.
Em Eventos, abra uma compra recente e confira se ela tem utm_content preenchido. É o teste mais direto: se o evento não tem, não há o que cruzar.
O histórico não avança quando ninguém está com o Console aberto
É o caso do cron. Configure o agendamento horário da Etapa 4. Para confirmar que ele está funcionando, chame a URL uma vez no navegador: a resposta é um JSON com o resultado de cada tarefa, incluindo a sincronização de anúncios.
O ROAS parece alto ou baixo demais
Antes de suspeitar do número, confira três coisas:
- Moeda. Investimento e receita estão na mesma moeda? O Console avisa quando não estão.
- Fuso. O aviso de fuso diferente está aparecendo? Amplie o período.
- Status. Abra Receita por status da compra. Uma pilha de compras em status não aprovado explica um ROAS baixo sem nenhum erro de medição.
O que cada checagem prova
- Um número no painel prova que o Node leu aquele dado da Meta e o guardou. Não prova que a Meta entregou o anúncio para a pessoa certa.
- Uma receita atribuída prova que o Node encontrou uma compra sua carregando aquele id de anúncio. É a sua medição, feita com os seus dados — não é a atribuição do Meta Ads Manager, e os dois números não precisam bater.
- Um Sincronizado até avançando prova que o cron ou o Console estão rodando. Não prova que o token continua válido para amanhã.
Para expor esses mesmos números ao seu próprio agente de IA, veja Conecte um cliente MCP ao seu Node.