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).
PATCH /api/audience-criterias/:id
Atualiza um Audience Criteria existente. É uma atualização parcial: somente os campos presentes no corpo são modificados; os omitidos permanecem intactos. A operação é transacional — se a definição for substituída, as alterações são aplicadas juntas ou nenhuma é aplicada.
Auth: Obrigatória — permissão audience-criteria:update
Editar a audiência raiz do projeto exige também a
permissão project:update, para qualquer alteração (mesmo que seja só name ou description).
Sem ela, a API responde 403 — No tiene permiso para editar la audiencia raíz del proyecto.
Parâmetros de rota
| Parâmetro | Tipo | Descrição |
|---|---|---|
id | UUID | ID do audience criteria. Deve ser um UUID válido (caso contrário, 400). |
Semântica de atualização (leia primeiro)
O comportamento do PATCH não é um merge campo a campo da árvore. Resume-se a
isto:
- Só é atualizado o que é enviado. Um campo omitido não é tocado.
name— se enviado, não pode ser vazio nemnull; atualiza o nome.description— enviar uma string a altera; enviarnulla limpa (ficanull); omiti-la a deixa inalterada.
updatedByé definido para o usuário que edita;updatedAté atualizado automaticamente.
queryBlocks é uma substituição total, não um merge. Se o corpo incluir
queryBlocks, o serviço apaga todos os query blocks (e todas as composições)
existentes do critério e os recria do zero com o que foi enviado. Não é feito
diff nem são mantidos os blocos anteriores. Se você omitir queryBlocks, a
definição (blocos + composições) permanece intacta e somente name /
description são atualizados.
Enviar queryBlocks sem composedWith apaga as composições. A substituição
remove blocos e composições juntos, e as composições só são recriadas se
composedWith trouxer ao menos um elemento. Para manter as composições ao
reenviar queryBlocks, você deve também reenviar composedWith.
Corolário: composedWith sozinho é um no-op. As composições só são tocadas
quando queryBlocks também é enviado; enviar composedWith sem queryBlocks não
modifica as composições existentes.
A validação de negócio é condicional. A árvore da definição é revalidada (com
o fuso horário do tenant) somente se queryBlocks for enviado. Se não for
enviado, name / description são atualizados sem revalidar a definição.
Corpo da requisição
Nível raiz (UpdateAudienceCriteriaDto). Todos os campos são opcionais:
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
name | string | Não | Se enviado, não pode ser vazio nem null (400). |
description | string | null | Não | String para alterá-la, null para limpá-la. Omiti-la a deixa inalterada. |
queryBlocks | QueryBlockDto[] | Não | Se incluído, substitui toda a definição. Mesmo formato que em Criar. |
composedWith | CreateCompositionDto[] | Não | Só tem efeito se queryBlocks também for enviado (ver avisos). |
Assim como em Criar, se queryBlocks
for enviado, ele deve trazer pelo menos um elemento: um array vazio ([]) produz um
400. Para manter a definição atual, omita o campo.
Quando queryBlocks e/ou composedWith são enviados, eles usam exatamente os
mesmos DTOs que Criar (QueryBlockDto / CreateCompositionDto). A subárvore
está totalmente documentada abaixo.
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 diferentes 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 (hoje, 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) se resolvem 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. |
Lembre-se: composedWith só se aplica quando queryBlocks também é enviado (ver
Semântica de atualização).
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 da subárvore).
Nesse caso
messageé um array de strings e propriedades desconhecidas são rejeitadas. Sempre é executada. - 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 e para no primeiro invariante violado. Só é executada se o corpo incluirqueryBlocks.
As regras de negócio da definição são idênticas às de
Criar
(catálogo de tabelas/colunas, star (*) só com COUNT, colunas numéricas nas expressões aritméticas, cobertura de GROUP BY,
contexto de HAVING, coluna de identidade, setOperator por posição do bloco,
compatibilidade de operador por tipo, formato de value, regras do timeWindow,
etc.).
Regras específicas de composedWith (também 400, verificadas ao recriar as
composições quando queryBlocks é enviado):
| 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 |
Exemplos
Atualização parcial (somente metadados)
Renomeia o critério e limpa sua descrição, sem tocar na definição
(queryBlocks / composedWith são omitidos, então blocos e composições permanecem
intactos):
curl -X PATCH https://api.reten.ai/api/audience-criterias/a1b2c3d4-5678-4abc-9def-1234567890ab \
-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 (renombrado)",
"description": null
}'import axios from 'axios';
const id = 'a1b2c3d4-5678-4abc-9def-1234567890ab';
const response = await axios.patch(
`https://api.reten.ai/api/audience-criterias/${id}`,
{ name: 'Compradores VIP (renombrado)', description: null },
{ headers: { Authorization: 'Bearer <token>', 'x-tenant-id': '<tenant-id>', 'x-project-id': '<project-id>' } },
);
const updated = response.data;Substituição da definição
Incluir queryBlocks substitui toda a definição. Aqui composedWith também é
reenviado para manter a composição (se fosse omitido, a composição seria
apagada):
curl -X PATCH https://api.reten.ai/api/audience-criterias/a1b2c3d4-5678-4abc-9def-1234567890ab \
-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 60 días)",
"queryBlocks": [
{
"order": 0,
"from": { "table": "event_transactions", "joins": [] },
"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": 60
},
"where": {
"kind": "group",
"logicalOperator": "AND",
"children": [
{
"kind": "predicate",
"column": { "table": "event_transactions", "column": "status" },
"comparisonOperator": "EQUALS",
"value": "completed"
}
]
},
"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 id = 'a1b2c3d4-5678-4abc-9def-1234567890ab';
const body = {
name: 'Compradores VIP (últimos 60 días)',
queryBlocks: [
{
order: 0,
from: { table: 'event_transactions', joins: [] },
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: 60,
},
where: {
kind: 'group',
logicalOperator: 'AND',
children: [
{
kind: 'predicate',
column: { table: 'event_transactions', column: 'status' },
comparisonOperator: 'EQUALS',
value: 'completed',
},
],
},
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.patch(
`https://api.reten.ai/api/audience-criterias/${id}`,
body,
{ headers: { Authorization: 'Bearer <token>', 'x-tenant-id': '<tenant-id>', 'x-project-id': '<project-id>' } },
);
const updated = response.data;Resposta 200 OK
Retorna o critério já atualizado como IAudienceCriteriaDetail — a mesma
forma que GET /audience-criterias/:id
e que Criar. É o recurso base mais
a árvore completa: queryBlocks[] (com seu id e order 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. |
projectId | string (UUID) | Projeto ao qual o critério pertence. |
name | string | Nome (já atualizado se enviado). |
description | string | null | null se vazio. |
isActive | boolean | Se o critério está ativo. |
isRoot | boolean | true apenas para a audiência raiz do projeto (veja Projetos). |
ownerId | string (UUID) | Usuário criador (não muda na edição). |
updatedBy | string (UUID) | Usuário que fez esta edição. |
createdAt | string (ISO 8601) | Data de criação. |
updatedAt | string (ISO 8601) | Atualizado na edição. |
Relações aninhadas:
queryBlocks[]— cada bloco adiciona seuid(UUID) e retorna a árvore como ela ficou (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 60 días)",
"description": null,
"isActive": true,
"isRoot": false,
"ownerId": "0f0e0d0c-0b0a-4090-8070-605040302010",
"updatedBy": "1a2b3c4d-5e6f-4071-8092-a0b0c0d0e0f0",
"createdAt": "2026-07-15T14:32:07.481Z",
"updatedAt": "2026-07-15T16:05:44.902Z",
"queryBlocks": [
{
"id": "e5f6a7b8-9012-4abc-9def-567890abcdef",
"order": 0,
"setOperator": null,
"from": { "table": "event_transactions", "joins": [], "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": 60
},
"where": {
"kind": "group",
"logicalOperator": "AND",
"children": [
{
"kind": "predicate",
"column": { "table": "event_transactions", "column": "status" },
"comparisonOperator": "EQUALS",
"value": "completed"
}
]
},
"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": "f6a7b8c9-0123-4abc-9def-67890abcdef0",
"operandCriteriaId": "b2c3d4e5-6789-4abc-9def-0123456789ab",
"operandCriteriaName": "Usuarios activos",
"setOperator": "INTERSECT_DISTINCT"
}
]
}Respostas de erro
| Status | Descrição |
|---|---|
400 | DTO inválido (tipo incorreto, enum fora do intervalo, propriedade desconhecida, name vazio ou null, queryBlocks vazio) ou, quando queryBlocks é enviado, uma regra de negócio violada (ver regras de validação). Também se o id não for um UUID válido. |
401 | Authorization: Bearer ausente ou inválido. |
403 | O usuário não tem a permissão audience-criteria:update, ou o x-tenant-id não está autorizado. Também quando o critério é a audiência raiz do projeto e o usuário não tem project:update (No tiene permiso para editar la audiencia raíz del proyecto). |
404 | Não existe um audience criteria com esse id no projeto ativo. |
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).
Excluir Audiência
Arquiva (soft delete) um audience criteria; responde 204 sem corpo. Falha com 409 se for a audiência raiz do projeto, e com 400 se outro critério o referencia como operando.