📡 Server-side tracking

Pixel + CAPI: como evitar duplicar evento

Rodar Pixel + Conversion API juntos é a recomendação oficial da Meta em 2026. Mas se você não usa event_id compartilhado, vai contar tudo duplicado. Este guia explica como configurar deduplicação corretamente em 8 minutos.

📌 Resposta direta

Gere um único event_id por evento (UUID v4 ou hash do order_id) e envie esse mesmo ID tanto pelo Pixel (parâmetro eventID) quanto pela Conversion API (campo event_id). Meta dedupe automaticamente em janela de 7 dias. Se os IDs forem diferentes, conta como 2 conversões — ROAS inflado em 2×.

O problema da dupla contagem

Em 2026, a Meta recomenda rodar Pixel + CAPI juntos. O motivo: cada caminho cobre o que o outro perde. Pixel pega eventos rápidos no navegador, CAPI garante que conversões críticas sempre chegam (mesmo com iOS ATT, AdBlock, etc.).

Mas tem um problema óbvio: se ambos enviam o mesmo evento (ex.: Purchase), a Meta pode contar 2 vezes. Resultado prático:

  • Gerenciador de Anúncios mostra 200 conversões quando na verdade foram 100;
  • ROAS reportado em 8× quando na realidade é 4×;
  • IA de otimização da Meta se confunde — pensa que está acertando o público, na verdade está super-otimizando pra padrão errado;
  • CFO vê o relatório, vê o CRM, percebe a diferença e desconfia de toda a operação de ads.

Como o dedupe funciona no Meta

Meta dedupe automaticamente eventos que satisfaçam três condições simultâneas:

  1. Mesmo event_name — ex.: ambos como "Purchase";
  2. Mesmo event_id — string idêntica entre pixel e CAPI;
  3. Recebidos em até 7 dias um do outro — janela de deduplicação.

Quando as 3 condições casam, Meta mantém apenas o primeiro evento que chegou e descarta o segundo. Resultado: 1 conversão contada, não 2.

Gerando event_id corretamente

O event_id precisa ser:

  • Único por evento (não reutilizar entre Purchases diferentes);
  • Estável entre pixel e CAPI (gerar UMA vez, propagar pros dois);
  • Determinístico se possível (mesmo input = mesmo ID, facilita debugging).

Três abordagens comuns:

Opção 1: UUID v4 (mais comum)

// JavaScript
const eventId = crypto.randomUUID();
// → 'e4eaaaf2-d142-11ec-9d64-0242ac120002'

Prós: zero colisão garantida. Contras: aleatório, não vincula ao pedido.

Opção 2: Hash do order_id (recomendado pra e-com)

// Pseudocódigo
const eventId = 'purchase_' + sha256(orderId + timestamp).slice(0, 16);
// → 'purchase_a3f2b9c8d4e5f6a1'

Prós: rastreável (você consegue achar no log pelo order_id). Contras: precisa garantir que o timestamp é o mesmo no pixel e na CAPI.

Opção 3: order_id direto (simples)

const eventId = String(order.id);  // '#10042'

Prós: facílimo. Contras: se um order tem múltiplos eventos (Purchase, AddPaymentInfo), você precisa sufixar pra diferenciar (10042_purchase, 10042_payment).

Implementação no pixel client-side

// 1. Gerar event_id no servidor (renderiza no HTML)
// 2. Passar pro pixel via parâmetro eventID

fbq('track', 'Purchase', {
  value: 99.90,
  currency: 'BRL',
  content_ids: ['SKU-001'],
  content_type: 'product'
}, {
  eventID: ''  // ← este é o ID compartilhado
});

Atenção: o parâmetro eventID (camelCase) vai no terceiro argumento do fbq('track', ...), não no segundo. Erro comum.

Implementação no CAPI server-side

// PHP / Node / Python — payload pra Meta CAPI
const payload = {
  data: [{
    event_name: 'Purchase',
    event_time: Math.floor(Date.now() / 1000),
    event_id: 'purchase_a3f2b9c8d4e5f6a1',  // ← mesmo ID do pixel
    action_source: 'website',
    user_data: {
      em: [sha256('[email protected]')],
      ph: [sha256('+5511999998888')],
      fbp: req.cookies._fbp,
      fbc: req.cookies._fbc
    },
    custom_data: {
      value: 99.90,
      currency: 'BRL'
    }
  }],
  test_event_code: 'TEST12345'  // remover em produção
};

await fetch(`https://graph.facebook.com/v19.0/${pixelId}/events`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ ...payload, access_token: META_ACCESS_TOKEN })
});

A janela de deduplicação de 7 dias

Meta mantém o event_id em cache por 7 dias. Se pixel envia hoje e CAPI envia daqui a 8 dias com mesmo ID, conta como 2 eventos.

💡 Best practice: dispare CAPI imediatamente após o pixel disparar — idealmente dentro de segundos, no máximo minutos. Nunca atrase mais que algumas horas.

Em casos especiais (ex.: webhook do gateway de pagamento que pode demorar até 10min pra confirmar venda), tudo certo. Mas jamais envie o pixel agora e o CAPI 3 dias depois — vai duplicar.

Funciona em TikTok e Google também?

TikTok Events API

Mesma lógica. Use event_id no payload do TikTok Events API igual ao event_id do TikTok Pixel:

ttq.track('CompletePayment', {
  value: 99.90,
  currency: 'BRL',
  event_id: 'purchase_a3f2b9c8d4e5f6a1'  // ← compartilhado com Events API
});

Google Ads Enhanced Conversions

Google dedupe automaticamente via match key (email hasheado + phone hasheado). Não precisa de event_id explícito — mas precisa garantir que o pixel client-side e o server-side enviam exatamente o mesmo email hasheado.

Como validar que o dedupe está funcionando

  1. Abra o Events Manager da Meta → Diagnostics;
  2. Procure o aviso "Server and browser events received without event_id" — se aparecer, você tem eventos não-deduplicados;
  3. Veja a métrica "Deduplication rate" por evento — deve estar entre 0.85 e 1.0. Abaixo de 0.5 = não está deduplicando direito;
  4. Compare contagem do Gerenciador vs CRM — deve fechar em pelo menos 85% (era 50-60% antes do CAPI).

FAQ

O que acontece se pixel e CAPI tiverem event_id diferente?

O Meta conta como dois eventos separados. Seu Gerenciador de Anúncios reporta 2× a quantidade real de conversões, inflando ROAS pra cima. Isso confunde a IA da Meta (ela otimiza por um número errado) e distorce relatórios pro CFO/cliente.

Como gerar o event_id corretamente?

Use um identificador único e estável por evento — geralmente UUID v4 ou hash SHA-256 de timestamp + dados do pedido. O mesmo event_id deve ser passado pelo pixel (parâmetro eventID) E pela CAPI (campo event_id). Não gere dois IDs separados.

Qual a janela de deduplicação do Meta?

Meta deduplica eventos com mesmo event_id, event_name e fbp/fbc dentro de 7 dias. Se o pixel envia hoje e a CAPI envia daqui 8 dias, conta como dois eventos.

TikTok e Google também usam event_id?

Sim. TikTok dedupe via event_id idêntico em pixel + Events API. Google Ads enhanced conversions dedupe automaticamente via match key (email/phone hasheado). A lógica é a mesma — gerar uma vez, propagar pros dois caminhos.

Posso usar o ID do pedido como event_id?

Pode, desde que único. Order ID é boa fonte porque já existe no seu banco. Cuidado: se o cliente reembolsa e refaz o pedido, mantenha o ID original (Meta vai entender como dois eventos diferentes só se for outro ID).

Trakvo deduplica automaticamente

Configure pixel + CAPI no Trakvo e o sistema gera event_id compartilhado, sincroniza entre os dois caminhos e monitora a deduplication rate em tempo real.

Falar com o time
Assistente Trakvo
Respondo na hora