# Deduplicación de eventos con Meta y TikTok

URL: https://traqio.app/es/docs/concepts/deduplication
Last updated: 2026-10-14

Si tu app usa el SDK de Meta o de TikTok junto a Traqio, la misma conversión llega dos veces a la red. Un event_id compartido hace que la cuente una sola vez.

La **deduplicación de eventos** es la forma en que una red publicitaria reconoce que dos eventos recibidos son la misma conversión. Importa cuando tu app usa el SDK propio de la red junto a Traqio — algo habitual durante una migración: la compra llega a Meta o a TikTok una vez desde el dispositivo y otra desde el servidor de Traqio. Sin un `event_id` compartido, la red cuenta cada conversión dos veces y optimiza sobre una señal duplicada.

## Qué comparan las redes

| Red | Misma conversión cuando… | Ventana |
| --- | --- | --- |
| Meta | mismo dataset, mismo nombre de evento, mismo event id | 48 horas |
| TikTok | misma fuente de datos, mismo tipo de evento, mismo event id — gana el primero | 48 horas |

Dos consecuencias. El id solo tiene que ser único por fuente de datos y nombre de evento, así que Traqio lo acota a la app. Y el **nombre** debe coincidir además del id — por eso Traqio traduce [sus nombres de evento](https://traqio.app/es/docs/concepts/events-and-revenue#names) a los nombres estándar de las redes, los mismos que registran sus SDK.

> **Las instalaciones no necesitan nada** Meta no deduplica las instalaciones de apps — ya garantiza una instalación atribuida por dispositivo en 90 días —, así que no hay ningún event id que pasar para una instalación.

## Qué eventos se pueden deduplicar

| Evento que reenvía Traqio | Su event_id | ¿Puede calcularlo tu app? |
| --- | --- | --- |
| Una compra medida con transactionId (SDK de React Native, Expo y Capacitor) | derivado de tu app y del id de transacción de la tienda | sí — con la receta de abajo |
| Una compra recibida de RevenueCat | derivado del mismo modo, a partir del id de transacción de la tienda | sí — el mismo id |
| Cualquier otro evento del SDK | un id aleatorio que el SDK genera para ese evento | no |

Así que envía las **compras** desde ambos emisores con el id compartido, y cualquier **otro evento** desde un solo emisor — a través de Traqio o a través del SDK de la red, no ambos.

## La receta del event_id

```
event_id = "tq1_" + sha256(canonical).hex()[0:32]

canonical = "tq1|" + productId + "|" + eventName + "|" + seed                         # preferred
canonical = "tq1|" + productId + "|" + eventName + "|" + externalId + "|" + ts
                   + "|" + value + "|" + currency                                 # fallback
```

Para una compra, las entradas son:

- `productId` — el id de Traqio de tu app: el `id` que devuelve [GET /v1/products](https://traqio.app/es/docs/api#endpoints), también visible en la barra de direcciones de la consola (`/a/<productId>`).
- `eventName` — `purchase`, sea cual sea el nombre con el que tu app la midió.
- `seed` — la tienda, dos puntos y el id de transacción de la tienda: `app_store:2000000812345678`, `play_store:GPA.1234-5678-9012-34567`.

Cada entrada se recorta y se pasa a minúsculas antes de unirlas. (La forma alternativa es la que Traqio usa para los eventos que no tienen ninguna clave de negocio; tu app nunca la necesita.) Vector de referencia, para probar una implementación:

```
tq1|com.acme.app|purchase|gpa.1234-5678-9012-34567
  → tq1_4cbaf318d03260b6dc8bd21e33b56d40
```

El prefijo `tq1_` versiona la receta: una receta distinta tendría un prefijo distinto y nunca redefiniría esta, así que los ids ya calculados por las builds de la app publicadas siguen coincidiendo.

## Pasar el id al SDK de la red

### Meta

Los eventos de app reciben el id como un parámetro llamado `event_id` — en snake case, escrito a mano. No `eventID`, que es la grafía del Pixel web: en un evento de app se guarda en silencio como parámetro personalizado y nada se deduplica.

Android:
```kotlin
// facebook-android-sdk — "event_id" is a literal key: there is no constant for it
val params = Bundle().apply { putString("event_id", traqioEventId) }
AppEventsLogger.newLogger(context).logEvent("fb_mobile_purchase", 9.99, params)
```

iOS:
```swift
// facebook-ios-sdk
AppEvents.shared.logEvent(
  .purchased,
  parameters: [AppEvents.ParameterName(rawValue: "event_id"): traqioEventId]
)
```

### TikTok

Android:
```kotlin
// tiktok-business-android-sdk — the event id is the builder's second argument
TikTokBusinessSdk.trackTTEvent(
  TTBaseEvent.newBuilder("CompletePayment", traqioEventId)
    .addProperty("currency", "EUR")
    .addProperty("value", 9.99)
    .build()
)
```

iOS:
```swift
// tiktok-business-ios-sdk
let event = TikTokBaseEvent(eventName: "CompletePayment", eventId: traqioEventId)
TikTokBusiness.trackTTEvent(event)
```

En la petición, el SDK de TikTok pone tu id en `tt_event_id` y rellena `event_id` con un UUID aleatorio propio, que usa para sus reintentos de envío. Es lo esperado: no depures la deduplicación comparando payloads — compara el id que pasaste con el de Traqio.

## Lo que garantiza Traqio

- Meta y TikTok siempre reciben el mismo id para el mismo evento.
- Nunca se envía un id vacío: en su lugar se deriva uno.
- Una petición reintentada lleva el mismo id, byte a byte, así que los reintentos de Traqio no pueden contar dos veces.
- Las compras de RevenueCat se indexan por el id de transacción de la tienda — la misma clave que recibe una compra del SDK con `transactionId` —, así que la misma compra por ambas vías es también un único evento en Traqio.

## Preguntas frecuentes

**¿Necesito deduplicación si solo uso Traqio?**
No. La deduplicación importa cuando la misma conversión llega a Meta o TikTok desde dos emisores — normalmente el SDK propio de la red en tu app y el reenvío del lado del servidor de Traqio. Con Traqio solo hay un emisor, y los reintentos de Traqio reutilizan el mismo event id, así que un reintento nunca es una segunda conversión.

**¿Durante cuánto tiempo deduplican Meta y TikTok?**
48 horas. Dos eventos con la misma fuente de datos, el mismo nombre de evento y el mismo event id que llegan con menos de 48 horas de diferencia cuentan una vez. La misma compra enviada de nuevo tres días después cuenta legítimamente dos veces — no es un fallo de deduplicación.
