Registrar eventos del embudo
Informa de los pasos que alcanza un cliente referido después del clic, como una solicitud, una aprobación o una cuenta con fondos, con una llamada firmada de servidor a servidor por cada paso. Cada paso puede pagarle al afiliado un importe fijo y cuenta para los límites de volumen.
Un evento del embudo es un paso con nombre que alcanza un cliente referido después del clic: una solicitud iniciada, una solicitud aprobada, una cuenta con fondos. Defines los pasos en la campaña y tu backend informa de cada uno con un postback firmado. Rekomi registra quién refirió al cliente, le paga al afiliado si el paso lleva un pago y muestra el embudo completo por afiliado.
Los eventos conviven con las ventas y los leads. Nunca cambian tus recuentos de ventas, leads o clics, y funcionan tengas o no una pasarela de pago conectada.
Plan necesario: Starter o superior. Las cuentas en periodo de prueba siempre se aceptan.
Define tus eventos
Abre la campaña, ve a Comisión y añade tus pasos en Eventos del embudo. Cada evento tiene:
- un nombre (por ejemplo,
Application approved), - una clave, que se crea a partir del nombre (
application_approved). La clave es lo que envía tu postback y nunca cambia. Un nombre sin letras latinas ni dígitos recibe una clave comoevent_3, que se muestra junto al nombre, - un pago por evento opcional, un importe fijo en tu moneda principal. Déjalo vacío si solo quieres registrar el paso.
El orden de la lista es el orden de las columnas en el informe del embudo. Una campaña puede registrar hasta 20 eventos.
Endpoint
POST /api/tracking/eventProducción: https://api.rekomi.com/api/tracking/event (también disponible como /api/v1/tracking/event).
La autenticación es la misma que en el postback de ventas S2S: tu clave de API en Authorization: Bearer rk_live_*, más una cabecera X-Rekomi-Signature con un HMAC-SHA256 de {unix-seconds}.{raw-body} calculado con el secreto de firma de la clave. Reutiliza la misma función de firma. La marca de tiempo debe estar a menos de 300 segundos de la hora actual, y la clave necesita acceso de escritura.
Cuerpo de la petición
{
"event": "application_approved",
"externalEventId": "app_58213_approved",
"affiliateSlug": "jane-recommends",
"customerId": "cust_58213",
"customerEmail": "user@example.com",
"amountCents": 2500000,
"currency": "USD",
"subId": "newsletter"
}event(obligatorio): la clave de uno de los eventos de la campaña.externalEventId(obligatorio): tu id único para esta ocurrencia, de hasta 128 caracteres. Es único en toda tu cuenta, así que un reintento con el mismo id es seguro y siempre devuelve el primer registro, envíe lo que envíe el reintento.affiliateSlug(opcional): el afiliado que refirió al cliente. Envíalo en el primer paso. En los pasos siguientes puedes omitirlo y enviar solo el cliente (consulta Enviar el afiliado una sola vez).customerId(opcional): tu propio id del cliente. Es lo que une los pasos de un mismo cliente.customerEmail(opcional): el correo del cliente, que se usa igual cuando no tienes un id de cliente.programId(opcional): el id de la campaña. Si lo envías junto conaffiliateSlug, tiene que ser la campaña de ese afiliado. Si lo envías sin slug, limita la búsqueda del cliente a esa campaña. Cuando un afiliado promociona más de una de tus campañas, envía el slug del enlace de la campaña a la que te refieres.amountCents(opcional): un valor para el paso, en unidades menores decurrency, por ejemplo un importe con el que se dotó la cuenta. Se guarda para tus informes y no cambia el pago.currency(opcional): código ISO 4217 paraamountCentsy paracommissionCentscuando lo envías. Por defecto, tu moneda principal.commissionCents(opcional): lo que esta ocurrencia le paga al afiliado, cuando es tu backend quien decide el importe. Sustituye el pago configurado del evento solo para esta ocurrencia. Envía0para registrar el paso sin pagar.subId(opcional): la etiqueta de canal que llevaba la visita del cliente.occurredAt(opcional): cuándo ocurrió el paso (ISO 8601), si informas de él con retraso. Un valor sin zona horaria se interpreta como UTC. No puede estar en el futuro ni tener más de cinco años.
Envía en cada llamada affiliateSlug o un cliente (customerId o customerEmail).
Enviar el afiliado una sola vez
La mayoría de los backends conocen al afiliado que refirió al cliente cuando este llega por primera vez, y solo después tienen su propio id de cliente. Por eso Rekomi identifica al afiliado en este orden:
affiliateSlug, cuando lo envías.- El evento anterior más reciente con el mismo
customerId. - El evento anterior más reciente con el mismo
customerEmail. - Un lead registrado con ese correo en los últimos 90 días.
Así, una integración típica envía el slug con el primer paso y un customerId estable con todos los pasos:
{ "event": "lead", "externalEventId": "c58213_lead", "affiliateSlug": "jane-recommends", "customerId": "cust_58213" }{ "event": "funded", "externalEventId": "c58213_funded", "customerId": "cust_58213" }Respuesta
Un evento registrado por primera vez:
{ "ok": true, "eventId": "0b6f...", "conversionId": "c0nv...", "commissionCents": 5000, "overCap": false }conversionIdviene informado cuando el paso le pagó al afiliado. A partir de ahí, el dinero es una comisión normal: aparece en la página Conversiones como bono, espera a que termine la retención por reembolso y se paga con todo lo demás.overCapestruecuando el afiliado ya había alcanzado un límite de volumen configurado para retener. El paso se registra igualmente. Si lleva un pago,conversionIdapunta a una comisión retenida (estadoInvalidated,commissionCentsa0en esta respuesta) que se paga cuando la validas en la página Conversiones.
Un evento que ya estaba registrado:
{ "ok": true, "deduped": true, "eventId": "0b6f..." }Hay dos casos que cuentan como ya registrados: el mismo externalEventId, y el mismo evento para el mismo cliente. Un cliente se aprueba una sola vez, así que un segundo application_approved para el mismo customerId devuelve el primero.
Errores
409 external_event_id_reused significa que el externalEventId ya se usó para otro evento: usa un id por paso, por ejemplo el id del cliente más la clave del evento. Un 401 con el cuerpo vacío significa que se rechazó la clave, la firma o la marca de tiempo. 402 plan_tier_required significa que la cuenta está por debajo de Starter y no está en periodo de prueba. 413 significa que el cuerpo supera los 8,192 bytes, 429 significa que envías más rápido de lo que permite el límite de peticiones y 500 persist_failed significa que el evento no se pudo guardar, así que reinténtalo con el mismo externalEventId. Todo lo demás es un 400 con un código error:
error | Causa |
|---|---|
invalid_body | El cuerpo no es JSON válido |
event_required, invalid_event | Falta event o no es una clave válida |
unknown_event | La campaña no tiene ningún evento activo con esa clave |
external_event_id_required, external_event_id_too_long | Falta, o tiene más de 128 caracteres |
customer_id_too_long, customer_email_too_long | Tiene más de 255 y 320 caracteres, respectivamente |
affiliate_slug_or_customer_required | No se envió ni un slug ni un cliente |
affiliate_not_found | El slug no coincide con ningún afiliado de tu cuenta |
affiliate_not_resolved | No se envió slug y ningún evento o lead anterior coincide con el cliente |
affiliate_not_active | El afiliado no está aprobado |
program_mismatch | programId no es la campaña del afiliado |
no_active_program | La campaña del afiliado está inactiva o suspendida |
amount_out_of_range, invalid_commission | Un importe negativo, o uno de más de 1,000,000,000,000 unidades menores |
unsupported_currency | currency no es un código ISO 4217 admitido |
occurred_at_in_future, occurred_at_too_old | occurredAt está fuera del rango aceptado |
Ejemplo
import crypto from "node:crypto";
const BEARER = process.env.REKOMI_API_KEY!; // rk_live_...
const SIGNING = process.env.REKOMI_SIGNING_SECRET!; // rks_...
async function trackEvent(input: {
event: string;
externalEventId: string;
affiliateSlug?: string;
customerId?: string;
customerEmail?: string;
}) {
const body = JSON.stringify(input); // serialize once: these exact bytes are signed and sent
const t = Math.floor(Date.now() / 1000);
const sig = crypto.createHmac("sha256", SIGNING).update(`${t}.${body}`).digest("hex");
const res = await fetch("https://api.rekomi.com/api/tracking/event", {
method: "POST",
headers: {
Authorization: `Bearer ${BEARER}`,
"X-Rekomi-Signature": `t=${t},sig=${sig}`,
"Content-Type": "application/json",
},
body,
});
if (!res.ok) throw new Error(`Rekomi event failed: ${res.status} ${await res.text()}`);
return res.json();
}Consultar los eventos
- Panel: la pestaña Rendimiento de la campaña muestra la tabla Embudo, con una fila por afiliado y una columna por evento, y una exportación a CSV.
- API:
GET /api/v1/programs/{programId}/funneldevuelve el mismo informe (filtrossince,untilyaffiliateId;format=csvpara la tabla).GET /api/v1/funnel-eventslista las ocurrencias registradas (programId,affiliateId,event,since,until,take,skip), yGET /api/v1/funnel-events/export.csvlas exporta. - Webhooks: cada evento registrado dispara
event.recorded. Un paso que paga también dispara elconversion.createdde siempre.
Conviene saber
- El importe de un evento que paga es el mismo para todos los afiliados. Para pagar importes distintos a distintos afiliados, envía
commissionCentsen el postback. - Si quitas un evento que ya tiene ocurrencias registradas, se archiva: deja de aceptar postbacks y su historial se queda en el informe. Al quitar un evento también se quitan los límites de volumen definidos sobre él.
- El pago de un evento es en dinero. En una campaña que recompensa con crédito, los eventos se pueden registrar, pero no pueden llevar un pago.
- Los eventos no se reembolsan a través de
/api/tracking/refund. Para recuperar la comisión de un paso pagado, deniega o ajusta su bono en la página Conversiones.
Seguimiento de leads y altas
Registra un alta gratuita identificada (un correo vinculado a la referencia) antes del pago, para que una venta posterior se siga acreditando al afiliado aunque la cookie del clic ya no exista. Automático en Stripe, Paddle, Chargebee, Recurly y Creem; opcional en el resto.
Checkouts sin código y fuera de Stripe
Instala el script de seguimiento de Rekomi para atribuir los clics en una plataforma sin código, y registra las conversiones con un procesador nativo, la API S2S o códigos de cupón.