Validar
Valida una definición de filtro de eventos con un dry-run de BigQuery y devuelve el costo estimado, sin ejecutar el query.
POST /api/event-criterias/validate-from-body
Valida una definición de filtro de eventos: la compila a SQL y la somete a un dry-run de BigQuery, que verifica el query contra el schema real y estima su costo sin ejecutarlo.
Auth: Requerida — permiso event-criteria:view-sql
No existe POST /event-criterias/:id/validate. Las
audiencias tienen la variante por id;
este recurso solo valida desde el cuerpo. Para validar un filtro guardado, obtené su
definición con GET /:id y enviá sus
queryBlocks a esta ruta.
Cuerpo de la solicitud
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
queryBlocks | QueryBlockDto[] | Sí | Mínimo 1 elemento. La definición a validar. |
La estructura de cada bloque está en Definición.
Este endpoint recibe solo la definición: name, description y format no forman
parte del cuerpo y enviarlos produce un 400 por propiedad desconocida.
Ejemplo
curl -X POST https://api.reten.ai/api/event-criterias/validate-from-body \
-H "Authorization: Bearer <token>" \
-H "x-tenant-id: <tenant-id>" \
-H "x-project-id: <project-id>" \
-H "Content-Type: application/json" \
-d '{
"queryBlocks": [
{
"order": 0,
"from": { "table": "event_transactions", "joins": [] },
"select": {
"distinct": true,
"items": [
{ "kind": "column", "column": { "table": "event_transactions", "column": "event_id" } }
]
},
"where": {
"kind": "group",
"logicalOperator": "AND",
"children": [
{
"kind": "predicate",
"column": { "table": "event_transactions", "column": "status" },
"comparisonOperator": "EQUALS",
"value": "Facturada"
}
]
}
}
]
}'import axios from 'axios';
const body = {
queryBlocks: [
{
order: 0,
from: { table: 'event_transactions', joins: [] },
select: {
distinct: true,
items: [
{ kind: 'column', column: { table: 'event_transactions', column: 'event_id' } },
],
},
where: {
kind: 'group',
logicalOperator: 'AND',
children: [
{
kind: 'predicate',
column: { table: 'event_transactions', column: 'status' },
comparisonOperator: 'EQUALS',
value: 'Facturada',
},
],
},
},
],
};
const response = await axios.post(
'https://api.reten.ai/api/event-criterias/validate-from-body',
body,
{ headers: { Authorization: 'Bearer <token>', 'x-tenant-id': '<tenant-id>', 'x-project-id': '<project-id>' } },
);
const { valid, errors, bytesProcessed } = response.data;Respuesta
Status 201 Created. El cuerpo reporta el resultado del dry-run:
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
valid | boolean | Sí | true si el dry-run tuvo éxito; false si BigQuery rechazó el query. |
errors | string[] | No | Presente solo cuando valid: false. Trae el/los mensaje(s) de error de BigQuery. |
bytesProcessed | number | Sí | Bytes que BigQuery estima procesar. En éxito, la estimación del dry-run; en fallo, 0. |
El dry-run no ejecuta el query ni devuelve filas: solo lo valida contra BigQuery y estima su costo. Para obtener una muestra de filas reales usa Previsualizar; para ver el SQL generado, Generar SQL.
errors es un arreglo por contrato, pero en la práctica el dry-run devuelve un único
mensaje (el que reporta BigQuery). Discriminá siempre por valid antes de leer
errors.
Ejemplo — válida (valid: true)
{
"valid": true,
"bytesProcessed": 10485760
}Con valid: true, errors se omite y bytesProcessed trae la estimación de BigQuery
(en este ejemplo, ~10 MB).
Ejemplo — inválida (valid: false)
La definición pasó la validación estructural y de negocio y se compiló a SQL, pero el
dry-run de BigQuery la rechazó. Aun así el status es 201:
{
"valid": false,
"errors": [
"Unrecognized name: legacy_column at [3:8]"
],
"bytesProcessed": 0
}Validación estructural vs. dry-run
Es el punto clave del endpoint: no todos los fallos llegan a errors[]. Una solicitud
atraviesa etapas y cada una falla de forma distinta.
| Etapa | Cómo falla | Dónde se ve |
|---|---|---|
| 1. Validación del DTO (estructura, tipos, enums) | Error HTTP 400 | message (arreglo de strings); corta la solicitud. |
| 2. Validación de negocio (catálogo, agregación, tiempo) | Error HTTP 400 | message (string); corta la solicitud. |
| 3. Dry-run de BigQuery | valid: false (status 201) | Campo errors del cuerpo de respuesta. |
No asumas que "definición inválida" siempre llega como valid: false. La mayoría de los
errores de forma y de negocio son errores HTTP 400 y nunca alcanzan el dry-run.
valid: false significa específicamente que BigQuery rechazó un query que ya había
pasado toda la validación local.
Reglas de validación
Antes del dry-run, la definición pasa por las dos capas de validación. El catálogo completo de reglas y sus mensajes exactos está en Definición → Reglas de validación.
Respuestas de error
Estos son los errores HTTP (distintos de valid: false, que viaja con status 201):
| Estado | Descripción |
|---|---|
400 | DTO inválido (campo faltante, tipo incorrecto, enum fuera de rango, propiedad desconocida) o una regla de negocio incumplida. |
401 | Falta o es inválido el Authorization: Bearer. |
403 | El usuario no tiene el permiso event-criteria:view-sql, o el x-tenant-id no está autorizado. |
404 | El tenant no tiene dataset configurado (Dataset not configured for tenant <id>). |