Reten Docs
Audiencias

Catálogo de audiencias

Tablas, columnas y registros repetidos disponibles para construir una audiencia.

El catálogo responde qué se puede filtrar. Son dos rutas: una lista las tablas disponibles y la otra, para una tabla, todo lo que ofrece —columnas escalares y columnas RECORD REPEATED.

Sin el catálogo la definición no es construible: no hay otra forma de saber cuál es la columna de identidad de una tabla, qué columna TIMESTAMP sugiere como referencia temporal, ni que attributes es un registro repetido y no una columna comparable.

Auth: Requerida — permiso audience-criteria:view en ambas rutas


GET /api/audience-criterias/tables

Lista las tablas del catálogo sobre las que se puede construir una audiencia. El catálogo es idéntico entre tenants: esta ruta no consulta el dataset del tenant.

Ejemplo

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;

Respuesta 200 OK

Un arreglo de IAudienceTable:

CampoTipoDescripción
tableNamestringNombre de la tabla; es el valor que va en from.table y en ColumnRefDto.table.
identityColumnstringOpcional. Columna de identidad de la tabla (por ejemplo user_id). Una tabla que solo sirve para cruzar puede no tenerla.
defaultTimeReferenceColumnstringOpcional. Columna TIMESTAMP sugerida como reference de la ventana temporal. Se puede elegir otra columna TIMESTAMP.
requiresInnerJoinbooleantrue si la tabla solo admite participar como tabla principal del from o como destino de un 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
  }
]

El identityColumn es la columna que al menos un bloque de consulta tiene que proyectar en su select: una definición que no la expone se rechaza con 400. El detalle está en Columna de identidad.

Una tabla con requiresInnerJoin: true restringe el bloque entero: si participa de un bloque, todos los joins de ese bloque tienen que ser INNER. La señal está en el catálogo para que el bloque se arme bien desde el principio, en vez de descubrirlo con un 400 al validar.


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

Devuelve todo lo que el catálogo ofrece sobre una tabla. A diferencia de /tables, esta ruta reconcilia el catálogo contra el schema real del dataset del tenant antes de responder.

Parámetros de ruta

ParámetroTipoDescripción
tableNamestringNombre de la tabla, tal como lo devuelve GET /tables.

Ejemplo

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;

Respuesta 200 OK

Un arreglo de IAudienceColumn: una unión discriminada por kind con dos variantes.

Estrecha por kind antes de leer type o fields. Solo la variante scalar trae type; solo record trae fields. Leer column.type sin discriminar devuelve undefined para un registro repetido.

  • kind: "scalar" — una columna filtrable directamente:

    CampoTipoDescripción
    columnNamestringNombre de la columna. Para hojas de un STRUCT no repetido es el path con punto (pricing.final_amount).
    kind"scalar"Discriminador.
    typeCatalogFieldTypeEnumTipo del catálogo; determina qué operadores de comparación admite.
    isIdentitybooleantrue si es la columna de identidad de la tabla. Como máximo una columna por tabla la tiene.
    isDefaultTimeReferencebooleantrue si es la referencia temporal sugerida de la tabla. Es una sugerencia: se puede anclar la ventana en otra columna TIMESTAMP.
  • kind: "record" — una columna RECORD REPEATED, filtrable solo con un filtro de registro:

    CampoTipoDescripción
    columnNamestringNombre de la columna repetida.
    kind"record"Discriminador.
    fieldsIAudienceColumn[]Sub-campos filtrables, relativos al registro. Puede contener otros record.
    isIdentityfalseSiempre false: un registro repetido no puede ser la identidad de la tabla.
    isDefaultTimeReferencefalseSiempre false: un registro repetido no puede anclar la ventana temporal.

Los fields de un record usan la misma unión scalar | record, así que la regla de estrechar por kind aplica en cada nivel.

Un sub-campo de un registro nunca trae isIdentity ni isDefaultTimeReference en true, ni siquiera si se llama igual que la columna de identidad de la tabla. Los dos roles son de la tabla sobre sus columnas de primer nivel.

Ejemplo de respuesta

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
  }
]

Cómo se usa cada variante en la definición

VarianteDónde va
scalarColumnRefDto.column de una hoja predicate, del select, del groupBy, de un agregado, del on de un join o de la reference de la ventana temporal.
recordcolumn de una hoja recordPredicate; sus fields van en el field de las hojas del subWhere.

Una columna record no se puede comparar ni proyectar: usarla en el select, en el groupBy, en un agregado, en el on de un join o en una hoja predicate devuelve 400. Su único uso es el filtro de registro.

Respuestas de error

EstadoDescripción
401Falta o es inválido el Authorization: Bearer.
403El usuario no tiene el permiso audience-criteria:view, o el x-tenant-id no está autorizado.
404Solo en /tables/:tableName/columns: la tabla no está en el catálogo (La tabla no existe o no está en el catálogo de audiencias.), o el tenant no tiene dataset configurado (Dataset not configured for tenant <id>).
500Solo en /tables/:tableName/columns: el schema real del dataset no satisface el catálogo (El schema de datos no satisface el catálogo de audiencias.).

GET /api/audience-criterias/tables no consulta el dataset del tenant, así que solo devuelve 200, 401 o 403.