Pré-visualizar
Executa um filtro de eventos contra o BigQuery e retorna uma amostra limitada de linhas mais o total correspondente.
Pré-visualizar
Executa um filtro de eventos contra o BigQuery e retorna uma amostra das linhas reais que ele seleciona, mais o total. São duas rotas com a mesma resposta: uma executa uma definição enviada no corpo e a outra um filtro já salvo.
| Rota | Origem da definição | Código de sucesso |
|---|---|---|
POST /api/event-criterias/preview-from-body | O corpo | 201 |
POST /api/event-criterias/:id/preview | O filtro salvo | 201 |
Auth: Obrigatória — permissão event-criteria:view-sql em ambas as rotas
Diferente de Validar, que faz um
dry-run, pré-visualizar executa a consulta: consome cota do BigQuery e seu custo
aparece em bytesProcessed.
POST /api/event-criterias/preview-from-body
Corpo da requisição
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
queryBlocks | QueryBlockDto[] | Sim | Mínimo 1 elemento. A definição a executar. |
limit | number | Não | Tamanho da amostra. Inteiro entre 1 e 500. Padrão 100. |
A estrutura de cada bloco está em Definição.
Este endpoint recebe apenas a definição e o limit: name, description e format
não fazem parte do corpo e enviá-los produz um 400 por propriedade desconhecida.
Exemplo
curl -X POST https://api.reten.ai/api/event-criterias/preview-from-body \
-H "Authorization: Bearer <token>" \
-H "x-tenant-id: <tenant-id>" \
-H "x-project-id: <project-id>" \
-H "Content-Type: application/json" \
-d '{
"limit": 50,
"queryBlocks": [
{
"order": 0,
"from": { "table": "event_transactions", "joins": [] },
"select": {
"distinct": true,
"items": [
{ "kind": "column", "column": { "table": "event_transactions", "column": "event_id" } },
{ "kind": "column", "column": { "table": "event_transactions", "column": "event_date" } }
]
},
"timeWindow": {
"timeOperator": "IN_THE_LAST",
"reference": { "table": "event_transactions", "column": "event_date" },
"unit": "DAYS",
"value": 30
},
"where": {
"kind": "group",
"logicalOperator": "AND",
"children": [
{
"kind": "predicate",
"column": { "table": "event_transactions", "column": "status" },
"comparisonOperator": "EQUALS",
"value": "Facturada"
}
]
}
}
]
}'import axios from 'axios';
const body = {
limit: 50,
queryBlocks: [
{
order: 0,
from: { table: 'event_transactions', joins: [] },
select: {
distinct: true,
items: [
{ kind: 'column', column: { table: 'event_transactions', column: 'event_id' } },
{ kind: 'column', column: { table: 'event_transactions', column: 'event_date' } },
],
},
timeWindow: {
timeOperator: 'IN_THE_LAST',
reference: { table: 'event_transactions', column: 'event_date' },
unit: 'DAYS',
value: 30,
},
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/preview-from-body',
body,
{ headers: { Authorization: 'Bearer <token>', 'x-tenant-id': '<tenant-id>', 'x-project-id': '<project-id>' } },
);
const { rows, totalCount, bytesProcessed } = response.data;POST /api/event-criterias/:id/preview
Executa um filtro já salvo. A definição é lida do filtro e validada antes de executá-la.
Parâmetros de rota
| Parâmetro | Tipo | Descrição |
|---|---|---|
id | UUID | ID do filtro de eventos. |
Corpo da requisição
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
limit | number | Não | Tamanho da amostra. Inteiro entre 1 e 500. Padrão 100. |
O corpo não leva a definição: o filtro salvo é a definição. Enviar queryBlocks
produz um 400 por propriedade desconhecida.
Exemplo
curl -X POST https://api.reten.ai/api/event-criterias/6d2a9c41-7e35-48b0-b1c9-0f8e7d6c5b4a/preview \
-H "Authorization: Bearer <token>" \
-H "x-tenant-id: <tenant-id>" \
-H "x-project-id: <project-id>" \
-H "Content-Type: application/json" \
-d '{ "limit": 50 }'import axios from 'axios';
const id = '6d2a9c41-7e35-48b0-b1c9-0f8e7d6c5b4a';
const response = await axios.post(
`https://api.reten.ai/api/event-criterias/${id}/preview`,
{ limit: 50 },
{ headers: { Authorization: 'Bearer <token>', 'x-tenant-id': '<tenant-id>', 'x-project-id': '<project-id>' } },
);
const { rows, totalCount, bytesProcessed } = response.data;limit — tamanho da amostra
limit limita apenas quantas linhas a resposta traz em rows (a amostra), não o
universo que o filtro seleciona.
- Intervalo: inteiro 1..500 (menor que 1 ou maior que 500 ⇒
400). - Padrão:
100quando omitido.
Pré-visualizar executa duas consultas sobre a mesma definição: um
SELECT … LIMIT <limit> para a amostra e um SELECT COUNT(*) para o total. Por isso
você pode ver rows.length = 50 com totalCount = 4821: rows é um vislumbre,
totalCount é a quantidade real de linhas que o filtro seleciona.
Resposta
Status 201 Created em ambas as rotas.
| Campo | Tipo | Descrição |
|---|---|---|
rows | Record<string, unknown>[] | Amostra de linhas reais, limitada por limit. As colunas dependem do select da definição (e de seus aliases); por isso rows não tem uma forma fixa. |
totalCount | number | Total de linhas que o filtro seleciona, não limitado por limit. |
bytesProcessed | number | Bytes processados pelo BigQuery na execução. Soma os bytes de ambas as consultas (amostra + contagem). |
Exemplo
Resposta 201 ao exemplo acima (limit: 50). O filtro seleciona 4821 eventos;
rows mostra os primeiros 50 (aqui reduzidos a 3 por brevidade), cada um com as
colunas projetadas:
{
"rows": [
{ "event_id": "evt_9f3a1c", "event_date": { "value": "2026-07-14T18:02:11.000Z" } },
{ "event_id": "evt_2b7e04", "event_date": { "value": "2026-07-14T17:45:03.000Z" } },
{ "event_id": "evt_c081ff", "event_date": { "value": "2026-07-13T09:21:58.000Z" } }
],
"totalCount": 4821,
"bytesProcessed": 5242880
}As chaves de cada objeto em rows (event_id, event_date) vêm do select da
definição: outra definição produz outras colunas.
Uma coluna TIMESTAMP não chega como string: chega envolvida em
{ "value": "<ISO 8601>" }. A data ISO está em row.event_date.value, não em
row.event_date. Os demais tipos do catálogo chegam como escalares JSON.
Regras de validação
Antes de executar, a definição passa pelas duas camadas de validação. A validação de
negócio roda em ambas as rotas: preview-from-body valida a definição do corpo, e
:id/preview valida o filtro salvo antes de executá-lo.
O catálogo completo de regras e suas mensagens exatas está em Definição → Regras de validação.
Se a definição passar pelas duas camadas mas a execução no BigQuery falhar —por
exceder o limite de bytes faturáveis (10 GB), esgotar o timeout de 30 s, ou qualquer
outro erro do motor— a resposta também é 400, com um message no formato
Query execution failed: <detail>.
Respostas de erro
| Status | Descrição |
|---|---|
400 | DTO inválido (limit fora de 1..500, tipo incorreto, enum fora do intervalo, propriedade desconhecida), uma regra de negócio violada, ou uma falha de execução no BigQuery (Query execution failed: …). Em :id/preview, também se o id não for um UUID válido. |
401 | O Authorization: Bearer está ausente ou é inválido. |
403 | O usuário não tem a permissão event-criteria:view-sql, ou o x-tenant-id não está autorizado. |
404 | Em :id/preview, não existe um filtro de eventos com esse id no tenant (Event criteria not found). Em ambas as rotas, se o tenant não tiver dataset configurado. |