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.
| Tabla | Filas | Personas únicas | ID usado | Rango de fechas |
|---|---|---|---|---|
ueno_braze_users_behaviors_app_sessionstart | 1.084.288.688 | 2.047.494 | external_user_id | 2025-05-06 → 2026-07-21 |
ueno_braze_users_behaviors_app_sessionend | 987.510.114 | 2.152.132 | external_user_id | 2025-05-06 → 2026-08-07 |
ueno_braze_users_behaviors_customevent | 981.341.093 | 2.149.122 | external_user_id | 2025-05-06 → 2026-08-07 |
ueno_braze_push_notification_send | 466.039.191 | 1.966.605 | external_user_id | 2025-04-21 → 2026-07-21 |
ueno_braze_users_messages_webhook_send | 273.567.042 | 2.293.836 | external_user_id | 2025-05-06 → 2026-08-07 |
ueno_braze_users_canvas_entry | 155.199.957 | 3.253.769 | user_id | 2025-05-06 → 2026-07-20 |
ueno_braze_users_campaigns_conversion | 109.109.079 | 1.890.602 | external_user_id | 2025-05-06 → 2026-08-07 |
ueno_braze_users_messages_inappmessage_impression | 76.437.227 | 1.827.950 | external_user_id | 2025-05-06 → 2026-07-21 |
ueno_braze_users_messages_email_send | 72.832.684 | 1.945.962 | external_user_id | 2025-05-06 → 2026-07-21 |
ueno_braze_users_messages_email_delivery | 65.066.536 | 1.860.190 | external_user_id | 2025-05-06 → 2026-07-21 |
ueno_braze_users_messages_email_deferral | 57.177.221 | 961.912 | external_user_id | 2025-05-06 → 2026-07-29 |
ueno_braze_users_messages_inappmessage_click | 26.698.066 | 1.641.386 | external_user_id | 2025-05-06 → 2026-08-07 |
ueno_braze_users_canvas_conversion | 20.290.964 | 1.818.441 | external_user_id | 2025-05-06 → 2026-07-21 |
ueno_braze_users_messages_pushnotification_open | 17.971.278 | 1.493.895 | external_user_id | 2025-05-06 → 2026-08-07 |
ueno_braze_users_messages_email_open | 15.843.898 | 1.053.058 | external_user_id | 2025-05-06 → 2026-07-29 |
ueno_braze_users_messages_email_softbounce | 5.995.169 | 473.165 | external_user_id | 2025-05-06 → 2026-07-22 |
ueno_braze_users_behaviors_subscription_globalstatechange | 5.675.990 | 1.016.397 | external_user_id | 2025-05-07 → 2026-08-07 |
ueno_braze_users_canvasstep_progression | 4.243.251 | 1.413.010 | user_id | 2025-05-06 → 2026-07-21 |
ueno_braze_first_session | 3.476.069 | 235.828 | external_user_id | 2025-04-21 → 2026-08-07 |
ueno_braze_users_behaviors_uninstall | 3.223.401 | 979.171 | external_user_id | 2025-05-06 → 2026-07-21 |
ueno_braze_users_messages_pushnotification_bounce | 1.623.878 | 613.236 | external_user_id | 2025-05-06 → 2026-07-21 |
ueno_braze_users_messages_email_click | 274.209 | 128.883 | external_user_id | 2025-05-06 → 2026-07-29 |
ueno_braze_users_canvas_exit_performedevent | 246.712 | 141.513 | external_user_id | 2025-05-06 → 2026-07-20 |
ueno_braze_users_messages_email_unsubscribe | 105.472 | 34.621 | external_user_id | 2025-05-06 → 2026-08-07 |
ueno_braze_users_messages_email_markasspam | 781 | 394 | external_user_id | 2025-05-06 → 2026-07-15 |
hub_braze_cod_persona | vací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.
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.
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
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.
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.
send_id viene frecuentemente vacío en envíos disparados por canvas. No confiar en él
como llave.
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.
Push que no se pudo entregar (device inválido, token expirado, etc). Mismo patrón
de columnas que open, sin canvas_id.
In-App
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.
Impresión de un mensaje In-App. Sirve bien para campañas standalone (no-canvas) —
ahí sí trae campaign_name poblado.
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_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.
Estado de entrega del proveedor (ESP): entregado, diferido, rebote suave. Útil para salud de dominio/deliverability, no para medir campañas.
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.
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.
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.
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.
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.
El puente recomendado (ver Volumen y frescura El modelo de identidad). Alto volumen, buena cobertura.
Mismo puente, pero solo la primera sesión de cada persona — mucho menos volumen (285K filas contra 165M de sessionstart). Usar sessionstart como default.
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.
Envíos vía webhook (integraciones externas, no push/email/in-app). Poco usado en los análisis de comunicación estándar.
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.
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.
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).
| Canal | Envío con canvas_id | Apertura/click con canvas_id | Có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) |
| ✕ | ✓ (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
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.
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.
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.
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):
| Tabla | Datos hasta |
|---|---|
users_messages_email_markasspam | 2026-07-15 |
users_canvas_exit_performedevent | 2026-07-20 |
users_canvas_entry | 2026-07-20 |
users_canvasstep_progression | 2026-07-21 |
users_behaviors_uninstall | 2026-07-21 |
users_messages_pushnotification_bounce | 2026-07-21 |
users_canvas_conversion | 2026-07-21 |
users_messages_email_send | 2026-07-21 |
users_messages_email_delivery | 2026-07-21 |
users_messages_inappmessage_impression | 2026-07-21 |
push_notification_send | 2026-07-21 |
users_behaviors_app_sessionstart | 2026-07-21 |
users_messages_email_softbounce | 2026-07-22 |
users_messages_email_click | 2026-07-29 |
users_messages_email_open | 2026-07-29 |
users_messages_email_deferral | 2026-07-29 |
users_messages_email_unsubscribe | 2026-08-07 |
first_session | 2026-08-07 |
users_behaviors_subscription_globalstatechange | 2026-08-07 |
users_messages_pushnotification_open | 2026-08-07 |
users_messages_inappmessage_click | 2026-08-07 |
users_campaigns_conversion | 2026-08-07 |
users_messages_webhook_send | 2026-08-07 |
users_behaviors_customevent | 2026-08-07 |
users_behaviors_app_sessionend | 2026-08-07 |
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'.