Pixel + CAPI: cómo evitar duplicar evento
Correr Pixel + Conversion API juntos es la recomendación oficial de Meta en 2026. Pero si no usas event_id compartido, vas a contar todo duplicado. Esta guía explica cómo configurar la deduplicación correctamente en 8 minutos.
Genera un único event_id por evento (UUID v4 o hash del order_id) y envía ese mismo ID tanto por el Pixel (parámetro eventID) como por la Conversion API (campo event_id). Meta deduplica automáticamente en una ventana de 7 días. Si los IDs son diferentes, cuenta como 2 conversiones — ROAS inflado en 2×.
El problema del doble conteo
En 2026, Meta recomienda correr Pixel + CAPI juntos. El motivo: cada camino cubre lo que el otro pierde. Pixel toma eventos rápidos en el navegador, CAPI garantiza que las conversiones críticas siempre llegan (incluso con iOS ATT, AdBlock, etc.).
Pero hay un problema obvio: si ambos envían el mismo evento (ej.: Purchase), Meta puede contar 2 veces. Resultado práctico:
- El Administrador de Anuncios muestra 200 conversiones cuando en realidad fueron 100;
- ROAS reportado en 8× cuando en realidad es 4×;
- La IA de optimización de Meta se confunde — piensa que está acertando al público, en realidad está sobre-optimizando para el patrón equivocado;
- El CFO ve el reporte, ve el CRM, percibe la diferencia y desconfía de toda la operación de ads.
Cómo funciona el dedupe en Meta
Meta deduplica automáticamente eventos que satisfagan tres condiciones simultáneas:
- Mismo
event_name— ej.: ambos como "Purchase"; - Mismo
event_id— string idéntica entre pixel y CAPI; - Recibidos en hasta 7 días uno del otro — ventana de deduplicación.
Cuando las 3 condiciones coinciden, Meta mantiene solo el primer evento que llegó y descarta el segundo. Resultado: 1 conversión contada, no 2.
Generando event_id correctamente
El event_id necesita ser:
- Único por evento (no reutilizar entre Purchases diferentes);
- Estable entre pixel y CAPI (generar UNA vez, propagar por ambos);
- Determinístico si es posible (mismo input = mismo ID, facilita debugging).
Tres abordajes comunes:
Opción 1: UUID v4 (más común)
// JavaScript
const eventId = crypto.randomUUID();
// → 'e4eaaaf2-d142-11ec-9d64-0242ac120002'
Pros: cero colisión garantizada. Contras: aleatorio, no vincula al pedido.
Opción 2: Hash del order_id (recomendado para e-com)
// Pseudocódigo
const eventId = 'purchase_' + sha256(orderId + timestamp).slice(0, 16);
// → 'purchase_a3f2b9c8d4e5f6a1'
Pros: trazable (puedes encontrarlo en el log por el order_id). Contras: necesitas garantizar que el timestamp sea el mismo en el pixel y en la CAPI.
Opción 3: order_id directo (simple)
const eventId = String(order.id); // '#10042'
Pros: facilísimo. Contras: si un order tiene múltiples eventos (Purchase, AddPaymentInfo), necesitas sufijarlo para diferenciar (10042_purchase, 10042_payment).
Implementación en el pixel client-side
// 1. Generar event_id en el servidor (renderizar en el HTML)
// 2. Pasarlo al pixel vía parámetro eventID
fbq('track', 'Purchase', {
value: 99.90,
currency: 'USD',
content_ids: ['SKU-001'],
content_type: 'product'
}, {
eventID: '' // ← este es el ID compartido
});
Atención: el parámetro eventID (camelCase) va en el tercer argumento del fbq('track', ...), no en el segundo. Error común.
Implementación en el CAPI server-side
// PHP / Node / Python — payload para Meta CAPI
const payload = {
data: [{
event_name: 'Purchase',
event_time: Math.floor(Date.now() / 1000),
event_id: 'purchase_a3f2b9c8d4e5f6a1', // ← mismo ID del pixel
action_source: 'website',
user_data: {
em: [sha256('[email protected]')],
ph: [sha256('+5491199998888')],
fbp: req.cookies._fbp,
fbc: req.cookies._fbc
},
custom_data: {
value: 99.90,
currency: 'USD'
}
}],
test_event_code: 'TEST12345' // remover en producción
};
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 })
});
La ventana de deduplicación de 7 días
Meta mantiene el event_id en caché por 7 días. Si el pixel envía hoy y la CAPI envía dentro de 8 días con mismo ID, cuenta como 2 eventos.
En casos especiales (ej.: webhook del gateway de pago que puede tardar hasta 10min en confirmar la venta), todo bien. Pero jamás envíes el pixel ahora y la CAPI 3 días después — vas a duplicar.
¿Funciona en TikTok y Google también?
TikTok Events API
Misma lógica. Usa event_id en el payload del TikTok Events API igual al event_id del TikTok Pixel:
ttq.track('CompletePayment', {
value: 99.90,
currency: 'USD',
event_id: 'purchase_a3f2b9c8d4e5f6a1' // ← compartido con Events API
});
Google Ads Enhanced Conversions
Google deduplica automáticamente vía match key (email hasheado + phone hasheado). No requiere event_id explícito — pero necesitas garantizar que el pixel client-side y el server-side envíen exactamente el mismo email hasheado.
Cómo validar que el dedupe está funcionando
- Abre el Events Manager de Meta → Diagnostics;
- Busca el aviso "Server and browser events received without event_id" — si aparece, tienes eventos no-deduplicados;
- Mira la métrica "Deduplication rate" por evento — debe estar entre 0.85 y 1.0. Por debajo de 0.5 = no está deduplicando bien;
- Compara el conteo del Administrador vs CRM — debe cerrar en al menos 85% (era 50-60% antes del CAPI).
FAQ
¿Qué pasa si pixel y CAPI tienen event_id diferente?
Meta cuenta como dos eventos separados. Tu Administrador de Anuncios reporta 2× la cantidad real de conversiones, inflando el ROAS hacia arriba. Esto confunde a la IA de Meta (optimiza por un número equivocado) y distorsiona los reportes al CFO/cliente.
¿Cómo generar el event_id correctamente?
Usa un identificador único y estable por evento — generalmente UUID v4 o hash SHA-256 de timestamp + datos del pedido. El mismo event_id debe pasarse por el pixel (parámetro eventID) Y por la CAPI (campo event_id). No generes dos IDs separados.
¿Cuál es la ventana de deduplicación de Meta?
Meta deduplica eventos con mismo event_id, event_name y fbp/fbc dentro de 7 días. Si el pixel envía hoy y la CAPI envía dentro de 8 días, cuenta como dos eventos.
¿TikTok y Google también usan event_id?
Sí. TikTok dedupe vía event_id idéntico en pixel + Events API. Google Ads enhanced conversions dedupe automáticamente vía match key (email/phone hasheado). La lógica es la misma — generar una vez, propagar por los dos caminos.
¿Puedo usar el ID del pedido como event_id?
Puedes, siempre que sea único. Order ID es buena fuente porque ya existe en tu base. Cuidado: si el cliente reembolsa y rehace el pedido, mantén el ID original (Meta lo entenderá como dos eventos diferentes solo si es otro ID).
Trakvo deduplica automáticamente
Configura pixel + CAPI en Trakvo y el sistema genera event_id compartido, sincroniza entre ambos caminos y monitorea la deduplication rate en tiempo real.
Hablar con el equipo