Criar Audience Criteria
Crie um critério de audiência a partir de sua definição completa (blocos de consulta, filtros, janela temporal, agregações e composições).
POST /api/audience-criterias
Cria um Audience Criteria a partir de sua definição completa. É o endpoint central do recurso: recebe toda a árvore da definição —blocos de consulta, projeção, filtros, janela temporal, cruzamentos, agregações e composições com outras audiências— e a persiste. A operação é transacional: o critério, seus query blocks e suas composições são criados juntos, ou nada é criado.
Auth: Obrigatória — permissão audience-criteria:create
Corpo da requisição
Nível raiz (CreateAudienceCriteriaDto):
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
name | string | Sim | Nome do critério. Não pode ser vazio. |
description | string | Não | Descrição de texto livre. Se omitida, a resposta a retorna como null. |
queryBlocks | QueryBlockDto[] | Sim | Mínimo 1 elemento. Cada bloco ≈ um statement SQL completo. |
composedWith | CreateCompositionDto[] | Não | Compõe este critério com outras audiências via operações de conjunto. |
queryBlocks[] — bloco de consulta
Cada elemento de queryBlocks (QueryBlockDto) é um statement SQL completo:
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
order | number (inteiro) | Sim | Posição do bloco; inteiro ≥ 0. |
setOperator | SetOperatorEnum | Não | Combina este bloco com o anterior. Ausente no primeiro bloco; obrigatório nos demais (ver regras). |
from | FromDto | Sim | Fonte de dados: tabela principal + joins. |
select | SelectDto | Sim | Projeção (colunas e/ou agregações). |
timeWindow | TimeWindowDto | Não | Janela temporal do bloco (união discriminada por timeOperator). |
where | WhereDto | Sim | Árvore de predicados. Obrigatório mesmo que seja um grupo vazio. |
groupBy | ColumnRefDto[] | Não | Colunas de agrupamento. |
having | HavingDto | Não | Filtro sobre agregados. |
O setOperator de um query block combina blocos dentro do mesmo critério; não
deve ser confundido com o setOperator de uma composição,
que combina critérios inteiros. São dois níveis distintos de operação de conjunto.
ColumnRefDto — referência a coluna
Usado em toda a árvore (select, filtros, group by, joins, agregados, janela temporal):
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
table | string | Sim | Tabela do catálogo. Não vazio. |
column | string | Sim | Coluna. Não vazio. Pode ser um caminho STRUCT (ex.: "pricing.final_amount"). |
Toda coluna é sempre qualificada com sua table para evitar ambiguidade.
from — fonte de dados (FromDto)
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
table | string | Sim | Tabela principal do catálogo. Não vazio. |
joins | JoinDto[] | Não | Cruzamentos com outras tabelas. Padrão []. |
unnests | ColumnRefDto[] | Não | Colunas repetidas declaradas como fonte de linhas (uma linha por elemento). Uma audiência não as aceita: omita o campo ou envie [] (o padrão); uma lista não vazia retorna 400. |
Cada JoinDto:
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
type | JoinTypeEnum | Sim | INNER | LEFT | RIGHT | FULL. |
table | string | Sim | Tabela a unir (do catálogo). Não vazio. |
on | JoinPredicateDto[] | Sim | Condições de junção. |
Cada JoinPredicateDto é um par de colunas: { left: ColumnRefDto, right: ColumnRefDto }.
select — projeção (SelectDto)
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
distinct | boolean | Sim | Aplica SELECT DISTINCT. |
items | (SelectColumnItem | SelectAggregateItem)[] | Sim | Não vazio. União discriminada pelo campo kind. |
Os items são discriminados por kind:
-
Coluna —
kind: "column":Campo Tipo Obrigatório Descrição kind"column"Sim Discriminador. columnColumnRefDtoSim Coluna projetada. aliasstring Não Deve corresponder a ^[A-Za-z_][A-Za-z0-9_]*$. -
Agregado —
kind: "aggregate":Campo Tipo Obrigatório Descrição kind"aggregate"Sim Discriminador. aggregateAggregateDtoSim Expressão de agregação. aliasstring Sim Aqui o alias é obrigatório. Mesmo regex de identificador.
AggregateDto:
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
aggregationOperator | AggregationOperatorEnum | Sim | COUNT | SUM | AVG | MIN | MAX. |
operand | object | Sim | O que é agregado. União discriminada por kind: column, star ou arithmetic (veja abaixo). |
distinct | boolean | Não | Aplica DISTINCT dentro do agregado. |
operand —o que é agregado— é discriminado por kind:
kind | Campos adicionais | Significado |
|---|---|---|
column | column: ColumnRefDto | Uma coluna do catálogo. |
star | (nenhum) | *: conta linhas. Só é válido com COUNT e sem distinct (COUNT(DISTINCT *) não é permitido). |
arithmetic | arithmeticOperator: ArithmeticOperatorEnum, left, right | Expressão binária. Cada lado é outro operando: uma column ou um arithmetic aninhado (nunca star). |
ArithmeticOperatorEnum: ADD | SUBTRACT | MULTIPLY | SAFE_DIVIDE (uma divisão que retorna
NULL quando o denominador é zero, em vez de fazer a consulta falhar). As colunas de uma expressão
aritmética precisam ser numéricas (INT64, NUMERIC, BIGNUMERIC, FLOAT64), e as expressões se
aninham até 3 níveis de arithmetic, contando o externo.
where — árvore de predicados (WhereDto)
O where é uma árvore recursiva. O nó raiz é sempre um grupo, e suas folhas são de
dois tipos:
kind | O que filtra |
|---|---|
group | Não é uma folha: agrupa filhos com AND / OR. Os grupos podem ser aninhados. |
predicate | Uma coluna escalar de uma tabela do from. |
recordPredicate | Uma coluna RECORD REPEATED: pelo menos 1 elemento satisfaz o sub-filtro. |
Grupo — kind: "group"
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
kind | "group" | Sim | Discriminador. |
logicalOperator | LogicalOperatorEnum (AND | OR) | Sim | Conectivo entre os filhos. |
children | (Group | Leaf)[] | Sim | Filhos do grupo; podem ser grupos aninhados. |
logicalOperator é sempre obrigatório em um grupo, mas só tem efeito com 2 ou
mais filhos. Com menos de 2 filhos seu valor é irrelevante (gera o mesmo SQL), mas
ainda assim deve ser enviado. Um where sem filtros é expresso como um grupo vazio:
{ "kind": "group", "logicalOperator": "AND", "children": [] }.
Folha de coluna — kind: "predicate"
Compara uma coluna escalar qualificada por sua tabela.
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
kind | "predicate" | Sim | Discriminador. |
column | ColumnRefDto | Sim | Coluna do predicado. |
comparisonOperator | ComparisonOperatorEnum | Sim | Operador de comparação. |
value | PredicateValue | Depende | Seu formato depende do operador. |
{
"kind": "predicate",
"column": { "table": "user_properties", "column": "country" },
"comparisonOperator": "IN",
"value": ["CL", "MX"]
}Folha de registro — kind: "recordPredicate"
Filtra por uma coluna RECORD REPEATED (um array de structs, como attributes).
Significa que pelo menos um elemento do array satisfaz o sub-filtro.
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
kind | "recordPredicate" | Sim | Discriminador. |
column | ColumnRefDto | Sim | Coluna RECORD REPEATED de uma tabela do from. |
subWhere | Sub-árvore relativa | Sim | Condições sobre os sub-campos do elemento. Não pode ficar vazio. |
{
"kind": "recordPredicate",
"column": { "table": "event_transactions", "column": "attributes" },
"subWhere": {
"kind": "group",
"logicalOperator": "AND",
"children": [
{ "kind": "predicate", "field": "key", "comparisonOperator": "EQUALS", "value": "canal" },
{ "kind": "predicate", "field": "value", "comparisonOperator": "EQUALS", "value": "web" }
]
}
}As condições do subWhere são avaliadas sobre um mesmo elemento do array, e não
sobre o array inteiro. O exemplo acima seleciona linhas que têm um atributo cujo key
é canal e cujo value é web — não linhas que têm um atributo com esse key e
outro, diferente, com esse value.
Quais colunas aceitam um filtro de registro é informado pelo
catálogo: as que vêm com
kind: "record".
Sub-árvore relativa
O subWhere é um grupo AND/OR cujas folhas são resolvidas contra os sub-campos que o
registro declara.
Há uma única diferença em relação à árvore de nível superior, e ela é a origem mais comum de erros:
Dentro de uma sub-árvore relativa os operandos não levam tabela: você escreve
"field": "key", e não "column": { "table": "attributes", "column": "key" }. A folha
usa a chave field (uma string), não column.
Folhas permitidas dentro de uma sub-árvore relativa:
- Folha escalar —
{ "kind": "predicate", "field": string, "comparisonOperator": …, "value"?: … }. Ofielddeve ser um sub-campo escalar do registro. - Registro aninhado —
{ "kind": "recordPredicate", "field": string, "subWhere": … }. Um registro dentro de outro registro; aninha sem limite declarado, desde que o catálogo declare cada nível. - Grupo — o mesmo formato de grupo, para combinar as folhas anteriores com
AND/OR.
Formato de value conforme comparisonOperator
| Operadores | Formato de value | Exemplo |
|---|---|---|
IS_NULL, IS_NOT_NULL | Sem value (omitido) | (omitido) |
IN, NOT_IN | Lista não vazia ScalarValue[] | ["CL", "MX"] |
BETWEEN | Par [min, max] | [10, 20] |
O resto (EQUALS, NOT_EQUALS, GREATER_THAN, LESS_THAN, GREATER_THAN_OR_EQUAL, LESS_THAN_OR_EQUAL, CONTAINS, NOT_CONTAINS, STARTS_WITH, ENDS_WITH) | Escalar único | "activo" · 42 |
ScalarValue = string | number | boolean. Além disso, cada operador deve ser
compatível com o tipo da coluna (ver regras de validação).
groupBy — colunas de agrupamento
Lista opcional de ColumnRefDto[]. Quando o bloco agrega (declara groupBy ou tem um
agregado no select), o groupBy deve corresponder exatamente às colunas não
agregadas do select (ver regras de validação).
having — filtro sobre agregados (HavingDto)
Mesma estrutura recursiva que where (grupos AND/OR aninhados e mesma regra de
value por operador), mas a folha opera sobre um agregado, não sobre uma coluna:
- Predicado (folha) —
{ kind: "predicate", aggregate: AggregateDto, comparisonOperator: ComparisonOperatorEnum, value?: PredicateValue }. - Grupo — idêntico ao de
where.
timeWindow — janela temporal (TimeWindowDto)
União discriminada por timeOperator. Restringe o bloco a um período de tempo sobre
uma coluna TIMESTAMP do catálogo (reference). É um campo irmão do where, não
um nó da árvore de filtros.
timeOperator | Campos adicionais |
|---|---|
ALL_TIME | (nenhum) — sem restrição de tempo. |
IN_THE_LAST | reference: ColumnRefDto, unit: TimeUnitEnum, value: inteiro > 0 |
IN_THE_FIRST | reference: ColumnRefDto, unit: TimeUnitEnum, value: inteiro > 0 |
SINCE | reference: ColumnRefDto, from: string (YYYY-MM-DD) |
BETWEEN | reference: ColumnRefDto, from: string (YYYY-MM-DD), to: string (YYYY-MM-DD) |
TimeUnitEnum: DAYS | WEEKS | MONTHS | YEARS.
Semântica de negócio de cada operador:
ALL_TIME— sem janela; considera todo o histórico.IN_THE_LAST— janela rolante relativa a "agora": os últimosvalueunit(ex.: últimos30 DAYS). Recalculada a cada execução.IN_THE_FIRST— janela relativa à origem do ciclo de vida do usuário (atualmente, sua data de cadastro): os primeirosvalueunitde vida de cada usuário. É ancorada por usuário, não a uma data fixa.SINCE— a partir da data civilfrom(inclusive).BETWEEN— entrefrometo, ambas as datas civis inclusivas de seu dia completo.
As datas civis YYYY-MM-DD (SINCE, BETWEEN) são resolvidas para o início do
dia no fuso horário do tenant. O detalhe de fuso horário é interno; basta enviar a
data civil.
composedWith[] — composição com outras audiências
Cada elemento (CreateCompositionDto) combina este critério com outra
audiência via uma operação de conjunto:
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
operandCriteriaId | string (UUID) | Sim | Id da outra audiência (operando). Deve existir. |
setOperator | SetOperatorEnum | Sim | UNION_DISTINCT | UNION_ALL | INTERSECT_DISTINCT. |
Regras de validação
A requisição passa por duas camadas de validação, ambas retornando
400 Bad Request:
- Validação do DTO (estrutura, tipos, enums, campos obrigatórios). Nesse caso
messageé um array de strings e propriedades desconhecidas são rejeitadas. - Validação de negócio (o critério deve gerar SQL válido e coerente com o
catálogo). Nesse caso
messageé uma string única com a mensagem da regra violada. A validação de negócio para no primeiro invariante violado.
Regras de negócio verificadas (todas retornam 400, com a mensagem exata da API):
| Regra | Mensagem |
|---|---|
| A tabela deve pertencer ao catálogo. | Table "<t>" is not in the catalog |
Cada (table, column) deve pertencer ao catálogo. | Column "<t>.<c>" is not in the catalog |
| Uma coluna repetida não pode ser usada fora de um filtro de registro. | La columna "<t>.<c>" es una columna repetida y no puede usarse en <contexto> |
| Uma folha de coluna exige uma coluna escalar. | La columna "<t>.<c>" es una columna repetida: no admite un filtro de columna |
| Um filtro de registro exige uma coluna repetida. | La columna "<t>.<c>" no es una columna repetida: no admite un filtro de registro |
| O sub-campo de um filtro de registro deve existir no registro. | El sub-campo "<f>" no existe en el registro |
| Uma folha escalar da sub-árvore não pode apontar para um sub-campo repetido. | El sub-campo "<f>" es una columna repetida: usá un filtro de registro anidado |
| Um registro aninhado exige um sub-campo repetido. | El sub-campo "<f>" no es una columna repetida |
| A sub-árvore de um filtro de registro não pode ficar vazia. | Un filtro de registro no puede quedar sin condiciones |
| Uma folha da árvore deve declarar seu operando. | Una hoja del filtro no declara una columna |
O operando star (*) só é válido com COUNT. | '*' is only valid with COUNT, not <op> |
COUNT(DISTINCT *) não é permitido. | COUNT(DISTINCT *) is not allowed |
star não pode ser lado de uma expressão aritmética. | '*' sólo vale como operando directo de COUNT, no como lado de una expresión aritmética |
| As colunas de uma expressão aritmética precisam ser numéricas. | El operando "<t>.<c>" es de tipo <type>; una expresión aritmética sólo admite operandos numéricos (INT64, NUMERIC, BIGNUMERIC, FLOAT64) |
| Uma expressão aritmética se aninha até no máximo 3 níveis. | La expresión aritmética supera la profundidad máxima de 3 niveles |
Toda coluna referenciada deve pertencer a uma tabela do from (principal ∪ joins). | Column "<t>.<c>" references a table that is not in the query block FROM |
Ao agregar, toda coluna não agregada do select deve estar no groupBy. | Column "<t>.<c>" must appear in GROUP BY when the operation aggregates |
Toda coluna do groupBy deve ser uma coluna não agregada do select. | Column "<t>.<c>" in GROUP BY must be a non-aggregated column of the SELECT |
having exige um contexto de agregação (groupBy ou um agregado no select). | HAVING requires an aggregation context (GROUP BY or an aggregate in the SELECT) |
O critério deve projetar sua coluna de identidade (ex.: user_id) como coluna. | Criteria requires at least one operation that selects its identity column (e.g. user_id) |
O primeiro bloco (order=0) não leva setOperator. | First operation (order=0) must not have a setOperator |
Todo bloco posterior (order>0) deve levar setOperator. | Operation with order=<n> must have a setOperator |
| O operador deve ser compatível com o tipo da coluna/agregado. | Operator <op> is not allowed for <type> operands |
Operador escalar com value ausente ou uma lista. | Operator <op> requires a single value |
IN/NOT_IN com value que não é lista ou está vazio. | Operator <op> requires a non-empty list of values |
BETWEEN sem exatamente dois valores. | Operator <op> requires exactly two values |
A reference do timeWindow deve estar no catálogo. | timeWindow reference "<t>.<c>" is not in the catalog |
A reference do timeWindow deve ser uma coluna TIMESTAMP. | timeWindow reference "<t>.<c>" must be a TIMESTAMP column |
A reference do timeWindow não pode ser uma coluna repetida. | La referencia temporal "<t>.<c>" es una columna repetida y no puede anclar una ventana de tiempo |
O value do timeWindow deve ser um inteiro positivo. | timeWindow value must be a positive integer |
Em timeWindow BETWEEN, from deve ser anterior ou igual a to. | timeWindow BETWEEN requires "from" to be on or before "to" |
As datas do timeWindow devem ser datas de calendário válidas. | timeWindow date "<d>" is not a valid calendar date |
Regras específicas de composedWith (também 400):
| Regra | Mensagem |
|---|---|
| Um critério não pode referenciar a si mesmo. | An audience criteria cannot reference itself |
| O operando deve existir. | Operand audience criteria <id> not found or deleted |
| Não são permitidas referências circulares entre critérios. | Circular reference detected |
Exemplo
Audiência de usuários que nos últimos 90 dias completaram transações de valor
superior a 100000, cruzando event_transactions com user_properties para
filtrar por país, e intersectada com outra audiência existente que também projeta apenas user_id.
curl -X POST https://api.reten.ai/api/audience-criterias \
-H "Authorization: Bearer <token>" \
-H "x-tenant-id: <tenant-id>" \
-H "x-project-id: <project-id>" \
-H "Content-Type: application/json" \
-d '{
"name": "Compradores VIP (últimos 90 días)",
"queryBlocks": [
{
"order": 0,
"from": {
"table": "event_transactions",
"joins": [
{
"type": "INNER",
"table": "user_properties",
"on": [
{
"left": { "table": "event_transactions", "column": "user_id" },
"right": { "table": "user_properties", "column": "user_id" }
}
]
}
]
},
"select": {
"distinct": false,
"items": [
{ "kind": "column", "column": { "table": "event_transactions", "column": "user_id" } }
]
},
"timeWindow": {
"timeOperator": "IN_THE_LAST",
"reference": { "table": "event_transactions", "column": "event_date" },
"unit": "DAYS",
"value": 90
},
"where": {
"kind": "group",
"logicalOperator": "AND",
"children": [
{
"kind": "predicate",
"column": { "table": "event_transactions", "column": "status" },
"comparisonOperator": "EQUALS",
"value": "completed"
},
{
"kind": "predicate",
"column": { "table": "user_properties", "column": "country" },
"comparisonOperator": "IN",
"value": ["CL", "MX"]
}
]
},
"groupBy": [
{ "table": "event_transactions", "column": "user_id" }
],
"having": {
"kind": "group",
"logicalOperator": "AND",
"children": [
{
"kind": "predicate",
"aggregate": {
"aggregationOperator": "SUM",
"operand": { "kind": "column", "column": { "table": "event_transactions", "column": "pricing.final_amount" } }
},
"comparisonOperator": "GREATER_THAN",
"value": 100000
}
]
}
}
],
"composedWith": [
{
"operandCriteriaId": "b2c3d4e5-6789-4abc-9def-0123456789ab",
"setOperator": "INTERSECT_DISTINCT"
}
]
}'import axios from 'axios';
const body = {
name: 'Compradores VIP (últimos 90 días)',
queryBlocks: [
{
order: 0,
from: {
table: 'event_transactions',
joins: [
{
type: 'INNER',
table: 'user_properties',
on: [
{
left: { table: 'event_transactions', column: 'user_id' },
right: { table: 'user_properties', column: 'user_id' },
},
],
},
],
},
select: {
distinct: false,
items: [
{ kind: 'column', column: { table: 'event_transactions', column: 'user_id' } },
],
},
timeWindow: {
timeOperator: 'IN_THE_LAST',
reference: { table: 'event_transactions', column: 'event_date' },
unit: 'DAYS',
value: 90,
},
where: {
kind: 'group',
logicalOperator: 'AND',
children: [
{
kind: 'predicate',
column: { table: 'event_transactions', column: 'status' },
comparisonOperator: 'EQUALS',
value: 'completed',
},
{
kind: 'predicate',
column: { table: 'user_properties', column: 'country' },
comparisonOperator: 'IN',
value: ['CL', 'MX'],
},
],
},
groupBy: [{ table: 'event_transactions', column: 'user_id' }],
having: {
kind: 'group',
logicalOperator: 'AND',
children: [
{
kind: 'predicate',
aggregate: {
aggregationOperator: 'SUM',
operand: { kind: 'column', column: { table: 'event_transactions', column: 'pricing.final_amount' } },
},
comparisonOperator: 'GREATER_THAN',
value: 100000,
},
],
},
},
],
composedWith: [
{
operandCriteriaId: 'b2c3d4e5-6789-4abc-9def-0123456789ab',
setOperator: 'INTERSECT_DISTINCT',
},
],
};
const response = await axios.post(
'https://api.reten.ai/api/audience-criterias',
body,
{ headers: { Authorization: 'Bearer <token>', 'x-tenant-id': '<tenant-id>', 'x-project-id': '<project-id>' } },
);
const created = response.data;Resposta 201 Created
Retorna o critério criado como IAudienceCriteriaDetail — a mesma forma que
GET /audience-criterias/:id. É o
recurso base mais a árvore completa: queryBlocks[] (com seu id e order já
resolvidos, ordenados por order ascendente) e compositions[] (com id e
operandCriteriaName).
Campos base (IAudienceCriteria) — todos camelCase; os instantes são serializados
em ISO 8601:
| Campo | Tipo | Descrição |
|---|---|---|
id | string (UUID) | Id do critério criado. |
projectId | string (UUID) | Projeto ao qual o critério pertence. |
name | string | |
description | string | null | null se não enviado. |
isActive | boolean | Os critérios são criados ativos (true). |
isRoot | boolean | true apenas para a audiência raiz do projeto (veja Projetos). |
ownerId | string (UUID) | Usuário criador. |
updatedBy | string (UUID) | Último editor (na criação, o criador). |
createdAt | string (ISO 8601) | |
updatedAt | string (ISO 8601) |
Relações aninhadas:
queryBlocks[]— cada bloco adiciona seuid(UUID) e retorna a árvore exatamente como foi enviada (from,select,timeWindow,where,groupBy,having). Campos opcionais ausentes são retornados comonull(setOperator,timeWindow,groupBy,having) efrom.joinscomo[]se não havia joins;from.unnestsvem sempre como[].compositions[]— cada composição:id(UUID),operandCriteriaId,operandCriteriaName(nome do operando resolvido;""se não resolver) esetOperator.
{
"id": "a1b2c3d4-5678-4abc-9def-1234567890ab",
"projectId": "3f6c2b1a-8d4e-4f7a-9b2c-5e1d0a7f6c34",
"name": "Compradores VIP (últimos 90 días)",
"description": null,
"isActive": true,
"isRoot": false,
"ownerId": "0f0e0d0c-0b0a-4090-8070-605040302010",
"updatedBy": "0f0e0d0c-0b0a-4090-8070-605040302010",
"createdAt": "2026-07-15T14:32:07.481Z",
"updatedAt": "2026-07-15T14:32:07.481Z",
"queryBlocks": [
{
"id": "c3d4e5f6-7890-4abc-9def-34567890abcd",
"order": 0,
"setOperator": null,
"from": {
"table": "event_transactions",
"joins": [
{
"type": "INNER",
"table": "user_properties",
"on": [
{
"left": { "table": "event_transactions", "column": "user_id" },
"right": { "table": "user_properties", "column": "user_id" }
}
]
}
],
"unnests": []
},
"select": {
"distinct": false,
"items": [
{ "kind": "column", "column": { "table": "event_transactions", "column": "user_id" } }
]
},
"timeWindow": {
"timeOperator": "IN_THE_LAST",
"reference": { "table": "event_transactions", "column": "event_date" },
"unit": "DAYS",
"value": 90
},
"where": {
"kind": "group",
"logicalOperator": "AND",
"children": [
{
"kind": "predicate",
"column": { "table": "event_transactions", "column": "status" },
"comparisonOperator": "EQUALS",
"value": "completed"
},
{
"kind": "predicate",
"column": { "table": "user_properties", "column": "country" },
"comparisonOperator": "IN",
"value": ["CL", "MX"]
}
]
},
"groupBy": [
{ "table": "event_transactions", "column": "user_id" }
],
"having": {
"kind": "group",
"logicalOperator": "AND",
"children": [
{
"kind": "predicate",
"aggregate": {
"aggregationOperator": "SUM",
"operand": { "kind": "column", "column": { "table": "event_transactions", "column": "pricing.final_amount" } }
},
"comparisonOperator": "GREATER_THAN",
"value": 100000
}
]
}
}
],
"compositions": [
{
"id": "d4e5f6a7-8901-4abc-9def-4567890abcde",
"operandCriteriaId": "b2c3d4e5-6789-4abc-9def-0123456789ab",
"operandCriteriaName": "Usuarios activos",
"setOperator": "INTERSECT_DISTINCT"
}
]
}Respostas de erro
| Status | Descrição |
|---|---|
400 | DTO inválido (campo faltante, tipo incorreto, enum fora do intervalo, propriedade desconhecida) ou uma regra de negócio violada (ver regras de validação). |
401 | Authorization: Bearer ausente ou inválido. |
403 | O usuário não tem a permissão audience-criteria:create, ou o x-tenant-id não está autorizado. |
Obter Audiência
Obtenha um audience criteria por id, com sua definição completa — blocos de consulta e composições aninhadas.
Atualizar Audience Criteria
Atualize parcialmente um audience criteria por id. Somente os campos enviados são modificados; incluir queryBlocks substitui completamente a definição (blocos e composições).