Guía de referencia · Data Lake ueno

Tablas de Braze en el lake: qué hay, cómo se unen, qué mirar

Mapa de las tablas de Braze Currents disponibles para analizar campañas, canvases y comunicaciones push/email/in-app. Todo lo de acá está verificado contra datos reales, no es la documentación oficial de Braze.

Orientación rápida

Cada envío o interacción con una campaña o canvas de Braze cae en el lake como un evento — una fila por persona, por acción. Quién recibió qué, cuándo, si abrió o clickeó. Volumen a nivel de persona, cruzable con el resto del data warehouse (compras, cuentas, etc). Lo que estas tablas no traen es el contenido real del mensaje — el texto del push, el HTML del email — eso vive en Braze mismo, no en el lake.

Volumen y frescura, tabla por tabla

Perfil real de las 26 tablas de Braze en ueno_staging, medido directo con count(*) y max(partition_date). Sirve como primer chequeo antes de escribir cualquier query: si la tabla que se necesita tiene pocas filas o quedó atrás en fecha, mejor saberlo acá que después de media hora armando un join.

TablaFilasPersonas únicasID usadoRango de fechas
ueno_braze_users_behaviors_app_sessionstart1.084.288.6882.047.494external_user_id2025-05-06 → 2026-07-21
ueno_braze_users_behaviors_app_sessionend987.510.1142.152.132external_user_id2025-05-06 → 2026-08-07
ueno_braze_users_behaviors_customevent981.341.0932.149.122external_user_id2025-05-06 → 2026-08-07
ueno_braze_push_notification_send466.039.1911.966.605external_user_id2025-04-21 → 2026-07-21
ueno_braze_users_messages_webhook_send273.567.0422.293.836external_user_id2025-05-06 → 2026-08-07
ueno_braze_users_canvas_entry155.199.9573.253.769user_id2025-05-06 → 2026-07-20
ueno_braze_users_campaigns_conversion109.109.0791.890.602external_user_id2025-05-06 → 2026-08-07
ueno_braze_users_messages_inappmessage_impression76.437.2271.827.950external_user_id2025-05-06 → 2026-07-21
ueno_braze_users_messages_email_send72.832.6841.945.962external_user_id2025-05-06 → 2026-07-21
ueno_braze_users_messages_email_delivery65.066.5361.860.190external_user_id2025-05-06 → 2026-07-21
ueno_braze_users_messages_email_deferral57.177.221961.912external_user_id2025-05-06 → 2026-07-29
ueno_braze_users_messages_inappmessage_click26.698.0661.641.386external_user_id2025-05-06 → 2026-08-07
ueno_braze_users_canvas_conversion20.290.9641.818.441external_user_id2025-05-06 → 2026-07-21
ueno_braze_users_messages_pushnotification_open17.971.2781.493.895external_user_id2025-05-06 → 2026-08-07
ueno_braze_users_messages_email_open15.843.8981.053.058external_user_id2025-05-06 → 2026-07-29
ueno_braze_users_messages_email_softbounce5.995.169473.165external_user_id2025-05-06 → 2026-07-22
ueno_braze_users_behaviors_subscription_globalstatechange5.675.9901.016.397external_user_id2025-05-07 → 2026-08-07
ueno_braze_users_canvasstep_progression4.243.2511.413.010user_id2025-05-06 → 2026-07-21
ueno_braze_first_session3.476.069235.828external_user_id2025-04-21 → 2026-08-07
ueno_braze_users_behaviors_uninstall3.223.401979.171external_user_id2025-05-06 → 2026-07-21
ueno_braze_users_messages_pushnotification_bounce1.623.878613.236external_user_id2025-05-06 → 2026-07-21
ueno_braze_users_messages_email_click274.209128.883external_user_id2025-05-06 → 2026-07-29
ueno_braze_users_canvas_exit_performedevent246.712141.513external_user_id2025-05-06 → 2026-07-20
ueno_braze_users_messages_email_unsubscribe105.47234.621external_user_id2025-05-06 → 2026-08-07
ueno_braze_users_messages_email_markasspam781394external_user_id2025-05-06 → 2026-07-15
hub_braze_cod_personavacía (0 filas)

El modelo de identidad

Esto es lo primero que hay que entender. Braze usa dos sistemas de ID distintos según la tabla, y no son intercambiables directo.

external_user_id — el que sirve para cruzar con el resto del lake

Es el ID que la mayoría de las tablas de envío/interacción usan. En ueno, external_user_id es directamente cod_persona — mismo valor numérico, sin necesidad de tabla puente.

external_user_id (Braze)=cod_persona (ueno) Match directo. Confirmado 100% en poblaciones de campaña reales.

Para bajar a documento o email, cruzar contra ueno_common.dim_persona (nro_documento, correo_electronico, ~3,1M personas). Evitar ueno_bankitti_ba_personas_nrt — cubre solo ~400K personas y da match rate bajo (~12%) comparado con dim_persona o ba_personas_v2_nrt.

user_id interno — solo en las tablas nativas de Canvas

Dos tablas identifican a la persona únicamente con el ID interno de Braze (hex tipo 69f9396f48f14b62e6d2314a), sin external_user_id en la fila: canvas_entry y canvasstep_progression. Ahí hay que puentear sí o sí. canvas_conversion y canvas_exit_performedevent, en cambio, sí traen external_user_id directo en la columna — no verificado el porcentaje de filas con el campo poblado, pero la columna existe y se puede intentar sin el puente primero.

canvas_entry.user_id app_sessionstart external_user_id= cod_persona

ueno_braze_users_behaviors_app_sessionstart es la tabla que resuelve esto: trae user_id (interno) y external_user_id en la misma fila. Es prácticamente el único puente confiable — hub_braze_cod_persona, que promete resolver esto directo, está vacía hoy. first_session también sirve pero cubre menos volumen.

-- puente interno -> externo, quedarse con el mas reciente por persona
WITH bridge AS (
  SELECT user_id iid, external_user_id uid,
         row_number() OVER (PARTITION BY user_id ORDER BY formatted_time DESC) rn
  FROM ueno_staging.ueno_braze_users_behaviors_app_sessionstart
)
SELECT iid, uid FROM bridge WHERE rn = 1
Match verificado

98,8% de cobertura probado contra la población real de un canvas (5.634 de 5.702 usuarios resueltos). Suficiente para trabajar con confianza.

Push

El canal con mejor trazabilidad de todos: es el único donde el envío lleva canvas_id propio.

ueno_braze_push_notification_send
canvas_idcampaign_id

Un envío de push a una persona. Es la única tabla de send/interacción que trae canvas_id, canvas_step_id y canvas_step_name directo — no hace falta ningún cruce para saber de qué canvas viene.

Columnas clave: external_user_id, campaign_id/campaign_name, canvas_id/canvas_name/canvas_step_id/canvas_step_name, message_variation_id, send_id, dispatch_id, device_id, formatted_time
Volumen real: 466.039.191 filas · 1.966.605 personas distintas (external_user_id) · datos del 2025-04-21 al 2026-07-21
send_id viene frecuentemente vacío en envíos disparados por canvas. No confiar en él como llave.
ueno_braze_users_messages_pushnotification_open
sin canvas_id

Apertura de push. No trae ningún identificador de canvas — para saber de qué canvas es una apertura hay que puentear por el envío.

Columnas clave: external_user_id, dispatch_id, campaign_id/campaign_name, message_variation_id, formatted_time
Volumen real: 17.971.278 filas · 1.493.895 personas distintas (external_user_id) · datos del 2025-05-06 al 2026-08-07
Trampa real, no teórica: ver Trampas conocidas → dispatch_id no siempre es 1:1 por persona. Usarlo sin verificar infló tasas de apertura a 96-100% en dos canvases reales de este lake.
ueno_braze_users_messages_pushnotification_bounce
sin canvas_id

Push que no se pudo entregar (device inválido, token expirado, etc). Mismo patrón de columnas que open, sin canvas_id.

In-App

El canal con el hueco más grande

Ni la impresión ni el click de mensajes In-App disparados por Canvas traen canvas_id ni campaign_id poblado. Es un hueco sistémico de la ingesta — confirmado con el 67% de impresiones In-App de una ventana real de ueno bank sin ningún identificador de campaña. No hay forma hoy de aislar la exposición In-App de un canvas específico en Currents.

ueno_braze_users_messages_inappmessage_impression
sin canvas_idcampaign_id vacío en canvas

Impresión de un mensaje In-App. Sirve bien para campañas standalone (no-canvas) — ahí sí trae campaign_name poblado.

Columnas clave: external_user_id, campaign_id/campaign_name, message_variation_id, formatted_time
Volumen real: 76.437.227 filas · 1.827.950 personas distintas (external_user_id) · datos del 2025-05-06 al 2026-07-21
Volumen real: 1.623.878 filas · 613.236 personas distintas (external_user_id) · datos del 2025-05-06 al 2026-07-21
ueno_braze_users_messages_inappmessage_click
sin canvas_id

Click sobre un mensaje In-App. Mismas columnas que impression más button_id. Mismo hueco de canvas.

Para medir el impacto de un paso In-App dentro de un canvas, la única vía hoy es medir el canvas completo (entrada + control, ver sección Canvas) en vez de aislar el canal.

Email

Asimetría rara: open sí tiene canvas_id, send y click no

email_open trae canvas_id/canvas_name/canvas_step_name directo. email_send y email_click, no. Es la única combinación exposición/interacción de las tres donde el segundo evento sabe más que el primero. Si el objetivo es solo contar aperturas por canvas, se puede leer directo de email_open sin puente; para exposición (cuántos se enviaron) no hay atajo.

ueno_braze_users_messages_email_send
sin canvas_id
Columnas clave: external_user_id, email_address, campaign_id/campaign_name, message_variation_id, dispatch_id, formatted_time
ueno_braze_users_messages_email_open
canvas_id
Columnas clave: external_user_id, campaign_id/campaign_name, canvas_id/canvas_name/canvas_step_name/canvas_variation_name, browser, device_os, formatted_time
ueno_braze_users_messages_email_click
sin canvas_id
Columnas clave: external_user_id, campaign_id/campaign_name, url, link_id, link_alias, formatted_time
ueno_braze_users_messages_email_delivery / deferral / softbounce
sin canvas_id

Estado de entrega del proveedor (ESP): entregado, diferido, rebote suave. Útil para salud de dominio/deliverability, no para medir campañas.

ueno_braze_users_messages_email_unsubscribe / markasspam
canvas_id

Bajas y marcados como spam. También traen canvas_id — señal de calidad de campaña más que de performance.

Tablas nativas de Canvas

Miden el canvas como objeto — quién entró, en qué variante, si Braze registró alguna conversión configurada. Usan el ID interno, no external_user_id.

ueno_braze_users_canvas_entry
canvas_id

La tabla más útil de este grupo. Un registro por persona que entra al canvas, con la variante asignada y si cayó en el grupo control (in_control_group — llega como string 'true'/'false', no boolean nativo, hay que castear). Es la base para medir lift real test-vs-control.

Columnas clave: user_id (interno), canvas_id, canvas_variation_name, in_control_group, formatted_time
Volumen real: 155.199.957 filas · 3.253.769 personas distintas (user_id) · datos del 2025-05-06 al 2026-07-20
Volumen real: 274.209 filas · 128.883 personas distintas (external_user_id) · datos del 2025-05-06 al 2026-07-29
Volumen real: 15.843.898 filas · 1.053.058 personas distintas (external_user_id) · datos del 2025-05-06 al 2026-07-29
Volumen real: 72.832.684 filas · 1.945.962 personas distintas (external_user_id) · datos del 2025-05-06 al 2026-07-21
Volumen real: 26.698.066 filas · 1.641.386 personas distintas (external_user_id) · datos del 2025-05-06 al 2026-08-07
Con esta tabla + el puente de identidad se puede armar una comparación real de "recibió el canvas" vs "no recibió nada" — más confiable que estimar atribución.
ueno_braze_users_canvasstep_progression
cobertura inconsistente

En teoría, qué paso del canvas alcanzó cada persona. Tiene volumen real a nivel global (ver abajo), pero la cobertura es por canvas, no uniforme: para uno de los canvases probados en este lake dio cero filas mientras otros canvases sí tenían datos. No asumir que un canvas puntual va a estar poblado acá — validar con un count(*) WHERE canvas_id = '...' antes de diseñar una consulta que dependa de esta tabla.

ueno_braze_users_canvas_conversion / users_campaigns_conversion
depende de config en Braze

Solo tienen datos si el canvas/campaña tiene un evento de conversión configurado en Braze. En la práctica, muchas campañas de ueno no lo tienen configurado, o lo tienen mal (ver Trampas conocidas). No asumir que esta tabla va a traer algo sin verificarlo primero con un count(*) filtrado por ese canvas.

ueno_braze_users_canvas_exit_performedevent
canvas_id

Registra cuándo una persona sale del canvas por haber cumplido el evento de salida configurado (distinto de conversión). Menos usado, mismo patrón de ID interno.

Comportamiento — y el puente de identidad

Estas tablas no son de campañas, son de actividad del usuario en la app. Su valor acá es que varias traen user_id interno y external_user_id juntos.

ueno_braze_users_behaviors_app_sessionstart
trae los 2 IDs

El puente recomendado (ver Volumen y frescura El modelo de identidad). Alto volumen, buena cobertura.

ueno_braze_first_session
trae los 2 IDs

Mismo puente, pero solo la primera sesión de cada persona — mucho menos volumen (285K filas contra 165M de sessionstart). Usar sessionstart como default.

ueno_braze_users_behaviors_app_sessionend / customevent / uninstall / subscription_globalstatechange
traen los 2 IDs

Mismo patrón de doble ID. Útiles si el análisis necesita eventos de producto (custom events) o señales de desinstalación/opt-out cruzadas con exposición a campañas.

ueno_braze_users_messages_webhook_send
sin canvas_id

Envíos vía webhook (integraciones externas, no push/email/in-app). Poco usado en los análisis de comunicación estándar.

hub_braze_cod_persona
vacía

Por nombre debería ser el puente directo user_id ↔ cod_persona. Está vacía (0 filas) al momento de esta guía. No usar — usar app_sessionstart en su lugar.

Fuera de ueno_staging: rollup experimental de Canvas

Vive en otra base, con otro enfoque: en vez de un evento por persona, es un pre-agregado por canvas y día que ya junta push, email e in-app en la misma fila.

ae_sandbox.fact_braze_eventos
en pruebas

Trazabilidad diaria de Canvas Analytics nativo de Braze. Grano: fecha × canvas × variante × segmento — no persona. Trae ya sumadas las métricas de los tres canales en la misma fila: push_envios/aperturas/clicks, email_envios/aperturas/clicks/unsubscribes, inapp_impresiones/clicks, más entradas, conversiones y revenue nativos de Braze.

Columnas clave: fecha, canvas_id, nombre_canvas, id_variante/nombre_variante, id_segmento/nombre_segmento, entradas, conversiones, revenue, push_*, email_*, inapp_*, control_inscritos
Volumen real: 412 filas · 5 canvases · 43 días con datos · del 2026-06-18 al 2026-07-30
Justo la asimetría documentada arriba (in-app y buena parte de email sin canvas_id en Currents) acá no existe — viene resuelta de fábrica porque es el propio rollup de Braze, no un cruce armado a mano. El costo: solo 5 canvases cargados hoy, y es agregado — no sirve para bajar a nivel de persona ni para cruzar con compras. Para eso, seguir usando las tablas de ueno_staging.

Matriz canvas × canal

Resumen de qué se puede medir hoy sin trabajo extra, por canal, cuando el mensaje viene de un Canvas (no de una campaña simple).

CanalEnvío con canvas_id Apertura/click con canvas_idCómo medirlo igual
Push Directo por canvas_id en el envío; apertura vía external_user_id + ventana de tiempo (no dispatch_id ciego, ver trampas)
Email (solo open) Aperturas directo de email_open; para exposición, usar el envío del canvas completo (canvas_entry) como proxy
In-App No se puede aislar el canal. Medir el canvas completo con canvas_entry

Por eso, para reportar performance de un canvas multicanal (Push + In-App + Email en un mismo flujo), lo más robusto es no intentar descomponer por canal y usar canvas_entry como unidad de exposición, comparando variante de test contra in_control_group = true.

Patrones de consulta

1 · Funnel de una campaña simple (no canvas), por canal

Envío → apertura, usando dispatch_id como puente. Válido cuando se confirma que dispatch_id es 1:1 por persona (ver trampa abajo).

WITH snd AS (
  SELECT DISTINCT external_user_id uid, dispatch_id
  FROM ueno_staging.ueno_braze_push_notification_send
  WHERE partition_date BETWEEN '2026-06-01' AND '2026-06-30'
    AND campaign_name = '<nombre exacto de campaña>'
),
opn AS (
  SELECT DISTINCT o.external_user_id uid
  FROM ueno_staging.ueno_braze_users_messages_pushnotification_open o
  JOIN snd d ON d.dispatch_id = o.dispatch_id
)
SELECT count(DISTINCT snd.uid) enviados, count(DISTINCT opn.uid) abiertos
FROM snd LEFT JOIN opn ON opn.uid = snd.uid

2 · Verificar si dispatch_id es seguro de usar

Correr esto SIEMPRE antes del patrón 1. Si dispatch_id << usuarios, no es 1:1 — está agrupando personas en lotes y el join de apertura va a inflar falsos positivos.

SELECT count(*) filas, count(DISTINCT dispatch_id) dispatch_unicos,
       count(DISTINCT external_user_id) usuarios
FROM ueno_staging.ueno_braze_push_notification_send
WHERE canvas_id = '<id>' -- o campaign_name = '...'

3 · Exposición de un canvas con grupo control (recomendado para canvas)

Usa canvas_entry + puente de identidad. Da un universo con test/control real, sin depender de qué canal individual llegó.

WITH bridge AS (
  SELECT user_id iid, external_user_id uid,
         row_number() OVER (PARTITION BY user_id ORDER BY formatted_time DESC) rn
  FROM ueno_staging.ueno_braze_users_behaviors_app_sessionstart
),
bridge1 AS (SELECT iid, uid FROM bridge WHERE rn = 1),
entrada AS (
  SELECT user_id iid,
         min(date_parse(substr(formatted_time,1,19),'%Y-%m-%d %H:%i:%s')) entry_ts,
         max(CASE WHEN lower(CAST(in_control_group AS varchar))='true'
             THEN 1 ELSE 0 END) es_control
  FROM ueno_staging.ueno_braze_users_canvas_entry
  WHERE canvas_id = '<id>'
  GROUP BY 1
)
SELECT e.es_control, count(DISTINCT b.uid) personas
FROM entrada e JOIN bridge1 b ON b.iid = e.iid
GROUP BY 1

4 · De external_user_id a documento/email

SELECT p.nro_documento, p.correo_electronico
FROM ueno_common.dim_persona p
WHERE p.cod_persona = CAST('<external_user_id>' AS bigint)

Trampas conocidas

dispatch_id no siempre es 1 persona = 1 dispatch_id

Para envíos masivos, Braze a veces agrupa cientos de personas bajo el mismo dispatch_id. Si se usa como llave de join para medir apertura sin verificar antes (patrón 2), el resultado infla la tasa de apertura — se vio en la práctica una tasa de 96-100% en dos canvases reales, cuando lo esperable para push es 2-10%. Corrección más robusta cuando hay dudas: unir por external_user_id + ventana de tiempo (ej. open dentro de las 72h posteriores al send de esa persona), en vez de dispatch_id.

conversion_behaviors casi nunca mide lo que parece

El campo de conversión nativo de Braze suele estar configurado como Starts Session (abrir la app), no como una compra o acción de negocio real. Antes de usar canvas_conversion/campaigns_conversion o el número de "conversiones" que muestra Braze, confirmar con el equipo de CRM qué evento de conversión tiene configurado cada campaña. Muchas campañas ni siquiera lo tienen configurado.

In-App: cero linaje de canvas en Currents

No hay hoy ninguna columna, directa o indirecta, que permita aislar una impresión o click de In-App a un canvas específico. Si el reporte necesita ese dato, hay que pedirle el screenshot al equipo de CRM — no está en el lake.

La frescura NO es la misma en todas las tablas — esto rompió un reporte real

No existe un único "corte del lake". Cada tabla de Currents se actualiza por su cuenta, y en la práctica quedan varios días de diferencia entre una y otra. Un reporte que arma la exposición con canvas_entry (atrasada) va a mostrar cero público para un canvas que push_send o campaigns_conversion (al día) sí ven. Pasó exactamente eso con canvases de tarjeta de crédito que arrancaron a principios de agosto: parecían sin datos, pero el hueco era solo de canvas_entry.

Antes de concluir "no tiene público todavía", revisar max(partition_date) de la tabla puntual que se está usando — no asumir que otra tabla del mismo grupo tiene la misma frescura. Última fecha con datos por tabla (a la fecha de esta guía):

TablaDatos hasta
users_messages_email_markasspam2026-07-15
users_canvas_exit_performedevent2026-07-20
users_canvas_entry2026-07-20
users_canvasstep_progression2026-07-21
users_behaviors_uninstall2026-07-21
users_messages_pushnotification_bounce2026-07-21
users_canvas_conversion2026-07-21
users_messages_email_send2026-07-21
users_messages_email_delivery2026-07-21
users_messages_inappmessage_impression2026-07-21
push_notification_send2026-07-21
users_behaviors_app_sessionstart2026-07-21
users_messages_email_softbounce2026-07-22
users_messages_email_click2026-07-29
users_messages_email_open2026-07-29
users_messages_email_deferral2026-07-29
users_messages_email_unsubscribe2026-08-07
first_session2026-08-07
users_behaviors_subscription_globalstatechange2026-08-07
users_messages_pushnotification_open2026-08-07
users_messages_inappmessage_click2026-08-07
users_campaigns_conversion2026-08-07
users_messages_webhook_send2026-08-07
users_behaviors_customevent2026-08-07
users_behaviors_app_sessionend2026-08-07
in_control_group es texto, no boolean

Llega como string 'true'/'false' en canvas_entry. Un CASE WHEN in_control_group THEN... directo tira error de tipo en Athena — castear con lower(CAST(in_control_group AS varchar))='true'.