Reten Docs
Audiências

Catálogo de audiências

Tabelas, colunas e registros repetidos disponíveis para construir uma audiência.

O catálogo responde o que pode ser filtrado. São duas rotas: uma lista as tabelas disponíveis e a outra, para uma tabela, tudo o que ela oferece —colunas escalares e colunas RECORD REPEATED.

Sem o catálogo a definição não é construível: não há outra forma de saber qual é a coluna de identidade de uma tabela, que coluna TIMESTAMP ela sugere como referência temporal, nem que attributes é um registro repetido e não uma coluna comparável.

Auth: Obrigatória — permissão audience-criteria:view em ambas as rotas


GET /api/audience-criterias/tables

Lista as tabelas do catálogo sobre as quais uma audiência pode ser construída. O catálogo é idêntico entre tenants: esta rota não consulta o dataset do tenant.

Exemplo

curl https://api.reten.ai/api/audience-criterias/tables \
  -H "Authorization: Bearer <token>" \
  -H "x-tenant-id: <tenant-id>" \
  -H "x-project-id: <project-id>"
import axios from 'axios';

const response = await axios.get(
  'https://api.reten.ai/api/audience-criterias/tables',
  { headers: { Authorization: 'Bearer <token>', 'x-tenant-id': '<tenant-id>', 'x-project-id': '<project-id>' } },
);
const tables = response.data;

Resposta 200 OK

Um array de IAudienceTable:

CampoTipoDescrição
tableNamestringNome da tabela; é o valor que vai em from.table e em ColumnRefDto.table.
identityColumnstringOpcional. Coluna de identidade da tabela (por exemplo user_id). Uma tabela que serve apenas para unir pode não ter uma.
defaultTimeReferenceColumnstringOpcional. Coluna TIMESTAMP sugerida como reference da janela temporal. Outra coluna TIMESTAMP pode ser escolhida.
requiresInnerJoinbooleantrue se a tabela só pode participar como tabela principal do from ou como destino de um INNER JOIN.
[
  {
    "tableName": "user_properties",
    "identityColumn": "user_id",
    "defaultTimeReferenceColumn": "sign_up_date",
    "requiresInnerJoin": false
  },
  {
    "tableName": "event_transactions",
    "identityColumn": "user_id",
    "defaultTimeReferenceColumn": "event_date",
    "requiresInnerJoin": false
  },
  {
    "tableName": "user_segment_relation",
    "identityColumn": "user_id",
    "requiresInnerJoin": true
  },
  {
    "tableName": "user_seller_relation",
    "identityColumn": "user_id",
    "requiresInnerJoin": true
  }
]

O identityColumn é a coluna que ao menos um bloco de consulta tem que projetar em seu select: uma definição que não a expõe é rejeitada com 400. O detalhe está em Coluna de identidade.

Uma tabela com requiresInnerJoin: true restringe o bloco inteiro: se ela participa de um bloco, todos os joins desse bloco têm que ser INNER. O sinal está no catálogo para que o bloco seja montado certo desde o início, em vez de descobri-lo com um 400 ao validar.


GET /api/audience-criterias/tables/:tableName/columns

Retorna tudo o que o catálogo oferece sobre uma tabela. Diferente de /tables, esta rota reconcilia o catálogo contra o schema real do dataset do tenant antes de responder.

Parâmetros de rota

ParâmetroTipoDescrição
tableNamestringNome da tabela, tal como retornado por GET /tables.

Exemplo

curl https://api.reten.ai/api/audience-criterias/tables/event_transactions/columns \
  -H "Authorization: Bearer <token>" \
  -H "x-tenant-id: <tenant-id>" \
  -H "x-project-id: <project-id>"
import axios from 'axios';

const response = await axios.get(
  'https://api.reten.ai/api/audience-criterias/tables/event_transactions/columns',
  { headers: { Authorization: 'Bearer <token>', 'x-tenant-id': '<tenant-id>', 'x-project-id': '<project-id>' } },
);
const columns = response.data;

Resposta 200 OK

Um array de IAudienceColumn: uma união discriminada por kind com duas variantes.

Estreite por kind antes de ler type ou fields. Apenas a variante scalar traz type; apenas record traz fields. Ler column.type sem discriminar retorna undefined para um registro repetido.

  • kind: "scalar" — uma coluna que pode ser filtrada diretamente:

    CampoTipoDescrição
    columnNamestringNome da coluna. Para folhas de um STRUCT não repetido é o path com ponto (pricing.final_amount).
    kind"scalar"Discriminador.
    typeCatalogFieldTypeEnumTipo do catálogo; determina quais operadores de comparação ela admite.
    isIdentitybooleantrue se é a coluna de identidade da tabela. No máximo uma coluna por tabela a tem.
    isDefaultTimeReferencebooleantrue se é a referência temporal sugerida da tabela. É uma sugestão: a janela pode ser ancorada em outra coluna TIMESTAMP.
  • kind: "record" — uma coluna RECORD REPEATED, filtrável apenas com um filtro de registro:

    CampoTipoDescrição
    columnNamestringNome da coluna repetida.
    kind"record"Discriminador.
    fieldsIAudienceColumn[]Sub-campos filtráveis, relativos ao registro. Pode conter outros record.
    isIdentityfalseSempre false: um registro repetido não pode ser a identidade da tabela.
    isDefaultTimeReferencefalseSempre false: um registro repetido não pode ancorar a janela temporal.

Os fields de um record usam a mesma união scalar | record, então a regra de estreitar por kind se aplica em cada nível.

Um sub-campo de um registro nunca traz isIdentity nem isDefaultTimeReference em true, nem mesmo se tiver o mesmo nome da coluna de identidade da tabela. Os dois papéis são da tabela sobre suas colunas de primeiro nível.

Exemplo de resposta

GET /api/audience-criterias/tables/event_transactions/columns:

[
  {
    "columnName": "user_id",
    "kind": "scalar",
    "type": "STRING",
    "isIdentity": true,
    "isDefaultTimeReference": false
  },
  {
    "columnName": "event_date",
    "kind": "scalar",
    "type": "TIMESTAMP",
    "isIdentity": false,
    "isDefaultTimeReference": true
  },
  {
    "columnName": "event_id",
    "kind": "scalar",
    "type": "STRING",
    "isIdentity": false,
    "isDefaultTimeReference": false
  },
  {
    "columnName": "status",
    "kind": "scalar",
    "type": "STRING",
    "isIdentity": false,
    "isDefaultTimeReference": false
  },
  {
    "columnName": "coupon_code",
    "kind": "scalar",
    "type": "STRING",
    "isIdentity": false,
    "isDefaultTimeReference": false
  },
  {
    "columnName": "pricing.final_amount",
    "kind": "scalar",
    "type": "FLOAT64",
    "isIdentity": false,
    "isDefaultTimeReference": false
  },
  {
    "columnName": "attributes",
    "kind": "record",
    "fields": [
      {
        "columnName": "key",
        "kind": "scalar",
        "type": "STRING",
        "isIdentity": false,
        "isDefaultTimeReference": false
      },
      {
        "columnName": "value",
        "kind": "scalar",
        "type": "STRING",
        "isIdentity": false,
        "isDefaultTimeReference": false
      }
    ],
    "isIdentity": false,
    "isDefaultTimeReference": false
  }
]

Como cada variante é usada na definição

VarianteOnde vai
scalarColumnRefDto.column de uma folha predicate, do select, do groupBy, de um agregado, do on de um join ou da reference da janela temporal.
recordcolumn de uma folha recordPredicate; seus fields vão no field das folhas do subWhere.

Uma coluna record não pode ser comparada nem projetada: usá-la no select, no groupBy, em um agregado, no on de um join ou em uma folha predicate retorna 400. Seu único uso é o filtro de registro.

Respostas de erro

StatusDescrição
401Ausente ou inválido o Authorization: Bearer.
403O usuário não tem a permissão audience-criteria:view, ou o x-tenant-id não está autorizado.
404Apenas em /tables/:tableName/columns: a tabela não está no catálogo (La tabla no existe o no está en el catálogo de audiencias.), ou o tenant não tem dataset configurado (Dataset not configured for tenant <id>).
500Apenas em /tables/:tableName/columns: o schema real do dataset não satisfaz o catálogo (El schema de datos no satisface el catálogo de audiencias.).

GET /api/audience-criterias/tables não consulta o dataset do tenant, então só retorna 200, 401 ou 403.