Referencia
Consultas SQL
Consulta tus datos de envío con el generador de Queryable o con SQL directo de ClickHouse, conoce las tablas disponibles y los límites, y parte de consultas de ejemplo.
La pestaña Queryable de Email APIAnalytics te permite plantear tus propias preguntas sobre tus datos de envío, con un generador visual o con SQL de ClickHouse de solo lectura. Está disponible en Pay as you goProBusinessCustom. Los resultados se muestran en un gráfico y una tabla, y puedes guardar consultas para tu equipo.
Generador
El generador escribe la consulta por ti y usa el periodo y los filtros Sending domain y API key de la página.
| Control | Opciones |
|---|---|
| Measure | sends, bounces, complaints, loads, clicks, unique loads, unique clicks, unique emails, failed, rejected, suppressed, avg delivery time, bounce rate, complaint rate |
| Time grain | hour, day, week |
| Group by | none, status, domain, credential (clave de API), campaign, tag, country |
| Chart type | Timeseries, Pie, Stat, Table |
No todas las combinaciones son válidas. Group by country funciona con las cargas y los clics, que tienen país; status, domain, credential, campaign y tag funcionan con las métricas de emails (envíos, rebotes, fallidos, rechazados, bloqueados, emails únicos y las dos tasas). Las quejas y el tiempo medio de entrega no se agrupan. Los grupos muestran ID como dom_… y key_…; usa SQL directo para añadir los nombres con un join. Agrupar por tag suele devolver un único grupo (none).
Selecciona Run para ver el resultado.
SQL directo
Activa Raw SQL para escribir SQL de ClickHouse en el editor y selecciona Run.
- Las consultas deben empezar por
SELECToWITHy solo pueden leer las tablas que se indican más abajo. Las escrituras, las funciones de tabla comourl()os3()y las tablassystemestán bloqueadas. - Cada tabla se limita automáticamente a tu espacio de trabajo. No necesitas una condición
workspace_oid. - El periodo y los filtros de la página no se aplican al SQL directo. Añade tu propia condición de tiempo, como
created_at >= now() - INTERVAL 30 DAY, o las consultas recorrerán todos los datos conservados. - Cada
FROMy cadaJOINdebe nombrar una tabla directamente. Las subconsultas entre paréntesis están permitidas, pero no pongas un alias después del nombre de una tabla (FROM emails_raw e) ni selecciones de una consultaWITHcon nombre. En su lugar, cualifica las columnas con el nombre de la tabla, por ejemplosending_domains_dim.name. - Las consultas devuelven como máximo 5000 filas y se detienen a los 10 segundos. Una consulta puede tener hasta 20.000 caracteres.
Para mostrar el resultado en un gráfico, devuelve una columna de tiempo llamada t, una columna numérica llamada v y, opcionalmente, una columna group_key para obtener una serie por valor. Cualquier otra forma se muestra como tabla. La tabla de la página muestra las 100 primeras filas.
Consultas guardadas
Escribe un nombre en Save as… y selecciona Save query para guardar la configuración actual del generador o el SQL. Las consultas guardadas aparecen como botones encima de los resultados para todos los miembros del espacio de trabajo. Selecciona una para cargarla o selecciona su × para eliminarla.
Tablas
Las tablas _raw se conservan hasta 365 días. Las tablas _daily contienen totales diarios y siguen la retención de analítica de tu plan.
emails_raw
Una fila por cada versión de cada email. Cada cambio de estado añade una versión nueva, así que un email aparece varias veces. Agrupa por oid y usa argMax(column, _peerdb_version) para leer el último valor, como en los ejemplos de más abajo.
| Columna | Descripción |
|---|---|
oid |
ID del email (em_…). |
type |
outgoing para el correo enviado, inbound para el correo recibido. |
status |
El estado del email, por ejemplo delivered o bounced. |
rcpt_to, mail_from, subject, message_id |
Sobre y asunto. |
sending_domain_oid, credential_oid |
ID del dominio de envío (dom_…) e ID de la clave de API (key_…). |
campaign_oid, automation_oid |
Tienen valor en los envíos de campañas y automatizaciones. |
tag |
Normalmente vacío. |
spam_score, inspected |
Puntuación de Rspamd y si el email se puntuó. |
size |
Tamaño del mensaje en bytes. |
loaded, clicked |
Hora de la primera apertura y del primer clic, o NULL. |
created_at, updated_at |
Marcas de tiempo en UTC. |
_peerdb_version |
Número de versión; cuanto más alto, más reciente. |
deliveries_raw
Una fila por cada registro de entrega: cada intento y registros como los de emails retenidos o bloqueados.
| Columna | Descripción |
|---|---|
oid, email_oid |
ID de la entrega y el email al que pertenece. |
status |
Por ejemplo delivered, attempted, bounced, held, suppressed. |
output |
La respuesta del servidor receptor, por ejemplo 250 2.0.0 OK. |
details |
La descripción del resultado que da Emailit. |
time |
Cuánto tardó el intento, el valor en el que se basa Time to inbox. |
sent_with_ssl |
Si la conexión usó TLS. |
timestamp, created_at |
Cuándo se produjo el intento. |
loads_raw y clicks_raw
Una fila por cada apertura o clic.
| Columna | Descripción |
|---|---|
oid, email_oid |
ID de la carga o del clic y el email al que pertenece. |
link_oid |
Solo en clicks_raw: el ID del enlace en el que se hizo clic (link_…). Las URL de los enlaces no se guardan en las tablas de analítica. |
ip_address, country, city, user_agent |
De dónde procede la apertura o el clic. |
timestamp, created_at |
Cuándo se produjo. |
events_raw
Una fila por cada evento: oid (evt_…), type, data (el payload como cadena JSON; léelo con funciones como JSONExtractString(data, 'object', 'id')) y created_at.
Tablas diarias
| Tabla | Columnas |
|---|---|
events_daily |
day, type, cnt, unique_emails |
deliveries_daily |
day, status, cnt, avg_time |
loads_daily |
day, cnt, unique_emails, countries |
clicks_daily |
day, cnt, unique_emails, unique_links |
Suma cnt con sum(cnt). Las demás columnas son estados de agregación de ClickHouse: léelas con uniqMerge(unique_emails), uniqMerge(unique_links), avgMerge(avg_time) y topKMerge(10)(countries).
Tablas de dimensiones
| Tabla | Columnas |
|---|---|
sending_domains_dim |
oid, name, created_at |
campaigns_dim |
oid, name, status, created_at |
workspaces_dim |
oid, name, plan_id, created_at |
Únelas con un join para mostrar nombres en lugar de ID.
Consultas de ejemplo
Tasa de rebote por dominio de envío y día
SELECT
toDate(latest.first_seen) AS t,
sending_domains_dim.name AS group_key,
countIf(latest.status = 'bounced') / count() AS v
FROM (
SELECT
oid,
min(created_at) AS first_seen,
argMax(status, _peerdb_version) AS status,
argMax(sending_domain_oid, _peerdb_version) AS sending_domain_oid
FROM emails_raw
WHERE type = 'outgoing'
AND created_at >= now() - INTERVAL 30 DAY
GROUP BY oid
) AS latest
LEFT JOIN sending_domains_dim ON sending_domains_dim.oid = latest.sending_domain_oid
GROUP BY t, group_key
ORDER BY t, group_keyElige el gráfico Timeseries para obtener una línea por dominio.
Enlaces con más clics
SELECT
link_oid,
count() AS clicks,
uniqExact(email_oid) AS emails_clicked
FROM clicks_raw
WHERE timestamp >= now() - INTERVAL 7 DAY
GROUP BY link_oid
ORDER BY clicks DESC
LIMIT 20Las tablas de analítica guardan el ID del enlace, no la URL. Para ver la URL de un enlace, abre un email que tenga el clic y consulta su pestaña Clicks, o recoge link.url de los webhooks email.clicked.
Percentiles del tiempo de entrega
SELECT
toDate(timestamp) AS t,
count() AS deliveries,
quantile(0.5)(toFloat64(time)) AS p50,
quantile(0.95)(toFloat64(time)) AS p95,
quantile(0.99)(toFloat64(time)) AS p99
FROM deliveries_raw
WHERE status = 'delivered'
AND time IS NOT NULL
AND timestamp >= now() - INTERVAL 14 DAY
GROUP BY t
ORDER BY tEnvíos y aperturas por campaña
SELECT
campaigns_dim.name AS campaign,
count() AS sent,
countIf(latest.loaded IS NOT NULL) AS opened,
countIf(latest.clicked IS NOT NULL) AS clicked
FROM (
SELECT
oid,
argMax(campaign_oid, _peerdb_version) AS campaign_oid,
argMax(loaded, _peerdb_version) AS loaded,
argMax(clicked, _peerdb_version) AS clicked
FROM emails_raw
WHERE type = 'outgoing'
AND created_at >= now() - INTERVAL 90 DAY
GROUP BY oid
) AS latest
INNER JOIN campaigns_dim ON campaigns_dim.oid = latest.campaign_oid
GROUP BY campaign
ORDER BY sent DESCErrores
| Mensaje | Causa |
|---|---|
| Only SELECT queries are allowed | La consulta no empieza por SELECT ni por WITH. |
| Table “…” is not allowed | Un FROM o un JOIN nombra algo que no es una tabla permitida, como una consulta WITH con nombre. |
| Query must read an allowlisted analytics table | La consulta no tiene un FROM de una tabla permitida. |
| External tables and table functions are not allowed | La consulta usa una función de tabla como url(). |
| Queries cannot target another workspace | Una condición workspace_oid = '…' nombra otro espacio de trabajo. |
Los errores de sintaxis de ClickHouse, por ejemplo por un alias después del nombre de una tabla, se muestran tal como los devuelve ClickHouse.