RRelo Docs
API & GuíasGuías

Clicks

Funcionamiento del click wrapper t.relo.mx: short links, datos capturados por click, fraude CTIT, failover de 3 niveles y deep links.

Guide

Links de Click Tracking

Usa links cortos de RELO en tus campanas de ads. Nosotros controlamos la data del click, habilitamos deteccion de fraude, y atribuimos conversiones al click exacto.

Como Funciona el Click Tracking

Cada link de tracking de RELO pasa por nuestro Click Wrapper en t.relo.mx, un Cloudflare Worker desplegado globalmente en 300+ ubicaciones de edge. Todo el proceso se completa en menos de 50ms.

// What happens when a user clicks your link:

GET https://t.relo.mx/c/AbC123

// Step 1: Look up short code in Cloudflare KV
KV.get("AbC123") -> {
  url: "https://samsungshop.onelink.me/6zKq?pid=affiliate_relo...",
  partner_id: 9,
  client_id: 3,
  campaign_id: 4
}

// Step 2: Generate unique click ID (ULID - sortable, includes timestamp)
click_id = "01HXYZ123456789ABCDEFGHIJ"

// Step 3: Capture Cloudflare headers (zero-cost, already available at edge)
ip, country, city, device_type, browser, os, referer, tcp_rtt

// Step 4: Fire click event to Go backbone (async, non-blocking)
POST ingest.relo.mx/postback/click { click_id, partner_id, ... }

// Step 5: Set first-party cookie for web-to-app attribution
Set-Cookie: _relo_cid=01HXYZ...; Domain=.relo.mx; Max-Age=2592000; SameSite=Lax; Secure

// Step 6: 302 redirect to destination with click_id appended
302 -> https://samsungshop.onelink.me/6zKq?pid=...&relo_click_id=01HXYZ...

Beneficio clave: El redirect siempre ocurre, incluso si el backbone esta caido. La captura de datos del click es fire-and-forget con una cadena de failover de 3 niveles.

Opcion 1: Desde el Portal

Ve a Portal → Assets → Links o usa la herramienta Link Generator en el dashboard de admin. Tu link se ve asi:

https://t.relo.mx/c/AbC123

Opcion 2: Via API

Crea links cortos programaticamente llamando a la API de Link Generator:

POST https://relo-api.quomx.workers.dev/api/partners/9/generate-link
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json

{
  "client_id": 3,
  "product_url": "https://www.samsung.com/mx/smartphones/galaxy-s24/",
  "product_name": "Galaxy S24 Ultra"
}

// Response:
{
  "ios_url": "https://samsungshop.onelink.me/6zKq?pid=affiliate_relo&c=mx_pd_...",
  "android_url": "https://samsungshop.onelink.me/6zKq?pid=affiliate_relo&c=mx_pd_...",
  "params": {
    "pid": "affiliate_relo",
    "c": "mx_pd_affiliate_relo_none_always-on_sub1_banner_none_conversion",
    "af_sub1": "sub1",
    "af_sub3": "mobupps",
    "deep_link_value": "samsungestore://openwebview#url=https://..."
  }
}

Datos Capturados por Click

Cada click captura los siguientes campos de los headers de edge de Cloudflare, sin costo adicional:

Campo

Fuente

Ejemplo

click_id

ULID

01HXYZ123456789ABCDEFGHIJ

timestamp

Embebido en ULID

2026-03-18T15:30:00Z

ip

CF-Connecting-IP

187.190.42.100

country

CF-IPCountry

MX

city

cf.city

Ciudad de Mexico

region

cf.region

Distrito Federal

latitude / longitude

cf.latitude / cf.longitude

19.43, -99.13

device_type

User-Agent

mobile

browser

User-Agent

Chrome 122

os

User-Agent

Android 14

referer

Referer header

https://facebook.com

tcp_rtt

cf.clientTcpRtt

45 (ms)

colo

cf.colo

MEX (edge PoP)

Deteccion de Fraude CTIT

CTIT (Click-to-Install Time) mide el tiempo entre un click y la conversion resultante. Esta es una de las senales de fraude mas efectivas en atribucion movil.

Como RELO es dueno del timestamp del click (no dependemos del MMP), podemos calcular CTIT independientemente:

// CTIT = conversion_time - our_click_time

Normal CTIT: 30 seconds - 48 hours
  User clicks ad -> browses -> installs -> opens app -> purchases

Suspicious CTIT: < 10 seconds
  Likely click injection: malware fires a click right before
  a legitimate install to "steal" the attribution

Suspicious CTIT: > 7 days
  Stale click being matched to organic install

// Fraud scoring in the Go backbone:
CTIT < 10s   -> fraud_score += 80  (click injection)
CTIT < 2s    -> fraud_score += 120 (definite click spam)
CTIT > 7d    -> fraud_score += 40  (stale attribution)

Por que somos duenos del click: Si dependieramos del timestamp de click de AppsFlyer, los fraudsters podrian manipular el tiempo reportado. Al capturar nuestro propio timestamp en el edge de Cloudflare, el calculo de CTIT es a prueba de manipulacion.

Flujo de Atribucion Click-a-Conversion

1

El Click Wrapper genera un ULID click_id, lo guarda en la cookie del usuario, y registra el click en ClickHouse con todos los metadatos (IP, geo, dispositivo, partner_id).

2

Usuario es redirigido al destino

El redirect 302 envia al usuario a la URL de OneLink/Branch con relo_click_id adjunto. El MMP (AppsFlyer/Branch) toma el click_id para atribucion.

3

Usuario abre la app / llega al sitio web

Para instalaciones de app, AppsFlyer/Branch matchea al usuario via device ID o matching probabilistico. Para web, la cookie _relo_cid enlaza la sesion del navegador con el click original.

4

Se dispara el evento de conversion

El evento de compra llega via postback S2S (de AppsFlyer) o via el pixel web. El backbone en Go matchea el click_id en DragonflyDB, calcula CTIT, corre el scorer de fraude, y escribe la venta atribuida en ClickHouse + Supabase.

Cadena de Failover de 3 Niveles

El click wrapper nunca bloquea el redirect del usuario. La captura del evento de click usa un patron fire-and-forget con 3 niveles de fallback:

// Tier 1: Primary - Go service on Hetzner (3s timeout)
POST https://ingest.relo.mx/postback/click
  -> Success? Done.
  -> Timeout/Error? Fall through to Tier 2.

// Tier 2: Standby - Warm standby VPS (5s timeout)
POST https://standby.relo.mx/postback/click
  -> Success? Done. Events replayed to primary later.
  -> Timeout/Error? Fall through to Tier 3.

// Tier 3: KV Buffer - Cloudflare KV (always succeeds)
KV.put("click:{click_id}", eventJSON, { expirationTtl: 86400 })
  -> Go service polls KV every 30s and replays buffered events.

// In all cases: the 302 redirect fires immediately.
// User experience is never affected by backend failures.

Los links de tracking de RELO se integran tanto con AppsFlyer OneLink como con Branch.io deep links. La URL generada incluye parametros para:

Parametro

Proposito

Ejemplo

pid

Fuente de medios

affiliate_relo

c

Nombre de campana con CID

mx_pd_affiliate_relo_none_always-on_sub1_...

af_sub1

CID del partner

sub1

af_sub3

Nombre del partner

mobupps

af_ad

ID de tracking del asset

SAM-MX-A1B2C3

deep_link_value

Deep link de la app

samsungestore://openwebview#url=...

relo_click_id

Nuestro click ID para CTIT

01HXYZ...

Ejemplo Completo: De Punta a Punta

// 1. Partner PartnerA creates a link for Galaxy S24 via the portal
//    Link generated: https://t.relo.mx/c/GxS24m

// 2. PartnerA uses this link in a Facebook ad campaign

// 3. User in Mexico City clicks the ad at 3:15 PM
GET https://t.relo.mx/c/GxS24m
  -> click_id: 01J5KR3N7YMQP8X2VFTG4WDHAB
  -> ip: 187.190.42.100, country: MX, city: Ciudad de Mexico
  -> device: iPhone 15 Pro, browser: Safari 17, os: iOS 17
  -> partner_id: 9 (PartnerA), client_id: 3 (Marca)

// 4. User redirected to Marca Shop app via OneLink
302 -> https://samsungshop.onelink.me/6zKq?pid=affiliate_relo
       &c=mx_pd_affiliate_relo_none_always-on_sub1_banner_none_conversion
       &relo_click_id=01J5KR3N7YMQP8X2VFTG4WDHAB

// 5. User purchases Galaxy S24 Ultra at 3:22 PM (7 minutes later)
// AppsFlyer fires S2S postback to ingest.relo.mx
// CTIT = 7 min -> normal range -> fraud_score = 0

// 6. Sale attributed to PartnerA, appears in dashboard within 10 min

On this page