Deduplicação além do event_id: as três duplicatas que sobram
O event_id resolve navegador contra servidor. Sobram três fontes de duplicata que ele não alcança — e a maior delas reescreveu quase metade dos eventos de uma semana numa conta que medimos.

Todo guia de API de Conversões dedica um parágrafo ao event_id, e com razão: sem ele, manter o pixel do navegador e ligar o envio pelo servidor faz o Meta contar cada compra duas vezes.
O que quase nenhum guia diz é que o event_id resolve um caso só — o mesmo evento chegando por dois canais. Existem outros três, e eles não têm nada a ver com o navegador.
Duplicata 1: o webhook e a sincronização de histórico
A venda chega em tempo real pelo webhook do checkout. Uma hora depois, a sincronização que mantém o relatório em dia varre a mesma janela e encontra a mesma venda. Se essa sincronização também emite eventos, a compra vira conversão de novo — e de novo, a cada hora.
Numa conta que medimos, isso produziu 17.108 eventos de pessoa numa semana para 8.952 eventos reais distintos. Quase metade do volume era reescrita byte a byte do que já tinha sido emitido. Nenhuma tela mostrava isso: a sincronização reportava sucesso, porque ela de fato tinha rodado.
A regra que resolve: o webhook emite conversão, a sincronização alimenta o relatório. Quando a sincronização encontra algo que o webhook não trouxe, aí sim ela emite — uma vez, e marcando que já emitiu.
Duplicata 2: dois eventos da mesma venda
Várias plataformas emitem um evento quando a compra é aprovada e outro quando ela é concluída, dias depois, ao fim do prazo de garantia. São dois nomes diferentes para a mesma transação.
Filtrar os dois como conversão duplica o faturamento. Filtrar só o segundo atrasa o aprendizado da campanha em uma semana inteira. Filtrar só o primeiro é quase sempre o certo — e é uma decisão, não um detalhe técnico.
Duplicata 3: a reentrega
Toda fila confiável reentrega uma mensagem quando não recebe confirmação. Isso é uma qualidade, não um defeito: é o que impede que o evento se perca quando algo falha no meio.
O efeito colateral é que a mesma linha pode ser processada duas vezes. Se a escrita não for idempotente — se ela inserir em vez de atualizar por uma chave estável —, cada reentrega vira uma duplicata.
A armadilha do carimbo de tempo na chave
Esta é a mais sutil e a que mais custa a achar. É comum que a chave de deduplicação inclua o instante do evento. Faz sentido no papel: dois eventos idênticos em momentos diferentes são dois eventos.
O problema aparece quando o instante é o momento do processamento, e não o momento em que a coisa aconteceu. Aí cada reprocessamento gera um carimbo novo, a chave muda, e a deduplicação nunca colapsa nada — o mecanismo existe, roda, reporta sucesso e não deduplica.
chave = pedido + tipo + agora() <- nunca colapsa
chave = pedido + tipo <- colapsa sempre
chave = pedido + tipo + data_do_pedido <- colapsa, e preserva historicoA regra geral
A chave de deduplicação tem de ser a identidade de negócio do evento: o número do pedido, o identificador da transação, o par pessoa e produto. Nunca um valor gerado no momento do envio, e nunca um carimbo que muda a cada execução.
Vale lembrar também que a proteção do Meta tem prazo: ele considera dois envios com mesmo nome e mesmo event_id como um só dentro de sete dias. Reenviar uma venda antiga depois desse prazo é uma conversão nova aos olhos dele, com event_id igual e tudo.
No CrazyLeads a chave de deduplicação sai da identidade de negócio da fonte, a sincronização emite apenas o que é novidade, e a escrita é idempotente por essa chave — reentrega de fila não vira linha nova.