Reten Docs

Create Event Filter

Create an event filter from its complete definition (query blocks, filters, time window, and aggregations).

POST /api/event-criterias

Creates an event filter from its complete definition. The operation is transactional: the filter and its query blocks are created together, or nothing is created.

Auth: Required — event-criteria:create permission

Request Body

Root level (CreateEventCriteriaDto):

FieldTypeRequiredDescription
namestringYesFilter name. Cannot be empty.
descriptionstringNoFree-text description. If omitted, the response returns it as null.
queryBlocksQueryBlockDto[]YesMinimum 1 element. Each block ≈ a complete SQL statement.

The structure of each block —order, setOperator, from, select, timeWindow, where, groupBy, having— is in Definition.

There is no composedWith: an event filter is not composed with other filters. Sending it produces a 400 for an unknown property.

Examples

Column filter

Events whose status is Facturada.

curl -X POST https://api.reten.ai/api/event-criterias \
  -H "Authorization: Bearer <token>" \
  -H "x-tenant-id: <tenant-id>" \
  -H "x-project-id: <project-id>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Venta oficial — solo facturada",
    "description": "Definición canónica de evento válido",
    "queryBlocks": [
      {
        "order": 0,
        "from": { "table": "event_transactions", "joins": [] },
        "select": {
          "distinct": true,
          "items": [
            { "kind": "column", "column": { "table": "event_transactions", "column": "event_id" } }
          ]
        },
        "where": {
          "kind": "group",
          "logicalOperator": "AND",
          "children": [
            {
              "kind": "predicate",
              "column": { "table": "event_transactions", "column": "status" },
              "comparisonOperator": "EQUALS",
              "value": "Facturada"
            }
          ]
        }
      }
    ]
  }'
import axios from 'axios';

const body = {
  name: 'Venta oficial — solo facturada',
  description: 'Definición canónica de evento válido',
  queryBlocks: [
    {
      order: 0,
      from: { table: 'event_transactions', joins: [] },
      select: {
        distinct: true,
        items: [
          { kind: 'column', column: { table: 'event_transactions', column: 'event_id' } },
        ],
      },
      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',
  body,
  { headers: { Authorization: 'Bearer <token>', 'x-tenant-id': '<tenant-id>', 'x-project-id': '<project-id>' } },
);
const created = response.data;

Record filter

Events that have an attribute whose key is documento_tipo and whose value is factura — both conditions on the same element of attributes.

{
  "name": "Documentos tipo factura",
  "queryBlocks": [
    {
      "order": 0,
      "from": { "table": "event_transactions", "joins": [] },
      "select": {
        "distinct": true,
        "items": [
          { "kind": "column", "column": { "table": "event_transactions", "column": "event_id" } }
        ]
      },
      "where": {
        "kind": "group",
        "logicalOperator": "AND",
        "children": [
          {
            "kind": "recordPredicate",
            "column": { "table": "event_transactions", "column": "attributes" },
            "subWhere": {
              "kind": "group",
              "logicalOperator": "AND",
              "children": [
                { "kind": "predicate", "field": "key", "comparisonOperator": "EQUALS", "value": "documento_tipo" },
                { "kind": "predicate", "field": "value", "comparisonOperator": "EQUALS", "value": "factura" }
              ]
            }
          }
        ]
      }
    }
  ]
}

Invoiced events with at least one line whose product is in the Food Service or HORECA category. The path to product_properties is resolved by the catalog: the request only names the semi-join.

{
  "name": "Proyecto Food Service",
  "queryBlocks": [
    {
      "order": 0,
      "from": { "table": "event_transactions", "joins": [] },
      "select": {
        "distinct": true,
        "items": [
          { "kind": "column", "column": { "table": "event_transactions", "column": "event_id" } }
        ]
      },
      "where": {
        "kind": "group",
        "logicalOperator": "AND",
        "children": [
          {
            "kind": "predicate",
            "column": { "table": "event_transactions", "column": "status" },
            "comparisonOperator": "EQUALS",
            "value": "Facturada"
          },
          {
            "kind": "semiJoinPredicate",
            "table": "event_transactions",
            "semiJoin": "products",
            "subWhere": {
              "kind": "group",
              "logicalOperator": "AND",
              "children": [
                {
                  "kind": "predicate",
                  "field": "categorization.category_name",
                  "comparisonOperator": "IN",
                  "value": ["Food Service", "HORECA"]
                }
              ]
            }
          }
        ]
      }
    }
  ]
}

Response 201 Created

Returns the created filter as IEventCriteriaDetail — the same shape as GET /event-criterias/:id: the base resource plus queryBlocks[], with their id already resolved and ordered by order ascending.

FieldTypeDescription
idstring (UUID)Id of the created filter.
projectIdstring (UUID)Project the filter belongs to.
namestring
descriptionstring | nullnull if not sent.
isActivebooleanAlways true: no endpoint modifies it.
ownerIdstring (UUID)Creating user.
updatedBystring (UUID)Last editor (on creation, the creator).
createdAtstring (ISO 8601)
updatedAtstring (ISO 8601)
queryBlocksarrayThe persisted blocks, with their id.
{
  "id": "9f3a1c22-4b7e-4c31-9a8d-2f5e6b7c8d90",
  "projectId": "3f6c2b1a-8d4e-4f7a-9b2c-5e1d0a7f6c34",
  "name": "Venta oficial — solo facturada",
  "description": "Definición canónica de evento válido",
  "isActive": true,
  "ownerId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "updatedBy": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "createdAt": "2026-07-10T09:12:44.005Z",
  "updatedAt": "2026-07-10T09:12:44.005Z",
  "queryBlocks": [
    {
      "id": "e5f6a708-91b2-4c33-8d44-5e6f7a8b9c01",
      "order": 0,
      "setOperator": null,
      "from": { "table": "event_transactions", "joins": [] },
      "select": {
        "distinct": true,
        "items": [
          { "kind": "column", "column": { "table": "event_transactions", "column": "event_id" } }
        ]
      },
      "timeWindow": null,
      "where": {
        "kind": "group",
        "logicalOperator": "AND",
        "children": [
          {
            "kind": "predicate",
            "column": { "table": "event_transactions", "column": "status" },
            "comparisonOperator": "EQUALS",
            "value": "Facturada"
          }
        ]
      },
      "groupBy": null,
      "having": null
    }
  ]
}

Validation Rules

The definition is validated before being persisted: a filter that does not compile to SQL is not created. The full catalog of rules and their exact messages is in Definition → Validation Rules.

Error Responses

StatusDescription
400Invalid DTO (missing field, incorrect type, enum out of range, unknown property) or a violated business rule.
401Missing or invalid Authorization: Bearer.
403The user lacks the event-criteria:create permission, or the x-tenant-id is not authorized.