Reten Docs
Activity Generation Configs

Crear Activity Generation Config

Crea una activity generation config solo de ciclo de vida con los tres pilares.

POST /api/activity-generation-configs

Crea una activity generation config. La operación es transaccional: la AGC y los tres pilares de ciclo de vida (con sus hijos) se crean juntos, o no se crea nada.

La AGC se crea en el proyecto activo, siempre con status: "draft" (ver Estado). Para que corra, publícala.

Auth: Requerida — permiso activity-generation-config:create

Invariante de tres pilares. activation, engagement y resurrection son todos obligatorios. Omitir cualquiera devuelve 400 Bad Request. No hay forma de crear una AGC sin los tres pilares.

Los cuerpos de solicitud son snake_case. En la UI de administración, el wizard precarga cada pilar con valores por defecto razonables desde GET /api/lifecycle-defaults; luego el administrador edita y envía los datos completos. Los valores de user_retention_status_config_id referencian entradas del catálogo de estados de retención del tenant.

Cuerpo de la Solicitud

CampoTipoRequeridoDescripción
namestringSíNombre de la config
descriptionstringNoDescripción de texto libre
audience_idUUIDNoAudiencia propia de la AGC; debe ser una audiencia del proyecto activo. Sin ella, la AGC corre sobre la audiencia raíz del proyecto (ver Audiencia efectiva)
activationobjectSíPilar de activación (ver abajo)
engagementobjectSíPilar de engagement (ver abajo)
resurrectionobjectSíPilar de resurrección (ver abajo)

source_config_id, usage_type y cualquier campo de plantilla/clonado no se aceptan. Una AGC se crea únicamente con datos completos de ciclo de vida.

Tampoco se aceptan status, projectId ni project_id: la AGC siempre se crea en el proyecto activo y en draft. Enviar cualquiera de ellos responde 400.

Objeto activation

CampoTipoRequeridoDescripción
namestringSíNombre del pilar
descriptionstringNoDescripción de texto libre
source_tablestringSíTabla origen de los datos de activación
source_columnsstring[]NoColumnas usadas para calcular la activación
date_columnstringSíColumna de fecha usada para el windowing
aggregation_methodenumSínunique, count, sum o active_weeks
momentsobject[]SíMomentos de activación (ver abajo)

Cada elemento de moments:

CampoTipoRequeridoDescripción
status_codestringSíCódigo de estado de retención asignado por este momento
user_retention_status_config_idUUIDNoEntrada del catálogo de estados de retención. Si se omite, la API la deriva de status_code; si se envía, tiene que ser la entrada de ese status_code
min_actionsint ≥ 0NoMínimo de acciones para alcanzar este momento
window_daysint ≥ 0NoVentana de look-back en días
time_windowint ≥ 0NoVentana de tiempo del momento
priorityint ≥ 0SíPrioridad de resolución (gana el menor)

Objeto engagement

CampoTipoRequeridoDescripción
namestringSíNombre del pilar
descriptionstringNoDescripción de texto libre
source_tablestringSíTabla origen de los datos de engagement
source_columnsstring[]NoColumnas usadas para calcular el engagement
date_columnstringSíColumna de fecha usada para el windowing
engagement_window_daysint ≥ 1SíVentana móvil para el conteo de engagement
min_lifetime_actions_for_engagedint ≥ 1SíMínimo de acciones de por vida para ser considerado engaged (por defecto de plataforma 1)
counting_methodenumSíevent_ids, active_days o active_weeks
levelsobject[]SíNiveles de engagement (ver abajo)

Cada elemento de levels:

CampoTipoRequeridoDescripción
status_codestringSíCódigo de estado de retención para este nivel
user_retention_status_config_idUUIDNoEntrada del catálogo de estados de retención. Si se omite, la API la deriva de status_code; si se envía, tiene que ser la entrada de ese status_code
labelstringSíEtiqueta visible
min_thresholdint ≥ 0SíCota inferior (inclusiva) del nivel
max_thresholdint ≥ 0NoCota superior; omitir para el nivel más alto
orderint ≥ 0SíOrden de presentación del nivel

Objeto resurrection

CampoTipoRequeridoDescripción
namestringSíNombre del pilar
descriptionstringNoDescripción de texto libre
source_tablestringSíTabla origen de los datos de resurrección
source_columnsstring[]NoColumnas usadas para calcular la resurrección
date_columnstringSíColumna de fecha usada para el windowing
thresholdsobject[]SíUmbrales de resurrección (ver abajo)

Cada elemento de thresholds:

CampoTipoRequeridoDescripción
status_codestringSíCódigo de estado de retención para este umbral
user_retention_status_config_idUUIDNoEntrada del catálogo de estados de retención. Si se omite, la API la deriva de status_code; si se envía, tiene que ser la entrada de ese status_code
labelstringSíEtiqueta visible
threshold_daysint ≥ 1SíDías de inactividad que disparan este estado
orderint ≥ 0SíOrden de presentación del umbral

Ejemplo

curl -X POST https://api.reten.ai/api/activity-generation-configs \
  -H "Authorization: Bearer <token>" \
  -H "x-tenant-id: <tenant-id>" \
  -H "x-project-id: <project-id>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Default lifecycle",
    "description": "Activation, engagement and resurrection for the main funnel",
    "audience_id": "1f0d2c3b-4a59-4687-9c12-abcdef012345",
    "activation": {
      "name": "Activation",
      "source_table": "events",
      "source_columns": ["user_id", "event_id"],
      "date_column": "occurred_at",
      "aggregation_method": "nunique",
      "moments": [
        {
          "status_code": "aha",
          "user_retention_status_config_id": "aa11bb22-cc33-4d44-9e55-ff66aa77bb88",
          "min_actions": 3,
          "window_days": 7,
          "time_window": 30,
          "priority": 1
        },
        {
          "status_code": "setup",
          "user_retention_status_config_id": "bb22cc33-dd44-4e55-9f66-aa88bb99ccaa",
          "min_actions": 1,
          "priority": 2
        }
      ]
    },
    "engagement": {
      "name": "Engagement",
      "source_table": "events",
      "source_columns": ["user_id", "event_id"],
      "date_column": "occurred_at",
      "engagement_window_days": 28,
      "min_lifetime_actions_for_engaged": 1,
      "counting_method": "active_days",
      "levels": [
        {
          "status_code": "casual",
          "user_retention_status_config_id": "cc33dd44-ee55-4f66-a077-bb99ccaaddbb",
          "label": "Casual",
          "min_threshold": 1,
          "max_threshold": 7,
          "order": 1
        },
        {
          "status_code": "core",
          "user_retention_status_config_id": "dd44ee55-ff66-4077-b188-ccaaddbbeecc",
          "label": "Core",
          "min_threshold": 8,
          "order": 2
        }
      ]
    },
    "resurrection": {
      "name": "Resurrection",
      "source_table": "events",
      "source_columns": ["user_id"],
      "date_column": "occurred_at",
      "thresholds": [
        {
          "status_code": "dormant",
          "user_retention_status_config_id": "ee55ff66-aa77-4188-c299-ddbbeeccffdd",
          "label": "Dormant",
          "threshold_days": 30,
          "order": 1
        },
        {
          "status_code": "churned",
          "user_retention_status_config_id": "ff66aa77-bb88-4299-d3aa-eeccffdd00ee",
          "label": "Churned",
          "threshold_days": 90,
          "order": 2
        }
      ]
    }
  }'
import axios from 'axios';

const body = {
name: 'Default lifecycle',
description: 'Activation, engagement and resurrection for the main funnel',
audience_id: '1f0d2c3b-4a59-4687-9c12-abcdef012345',
activation: {
name: 'Activation',
source_table: 'events',
source_columns: ['user_id', 'event_id'],
date_column: 'occurred_at',
aggregation_method: 'nunique',
moments: [
{
status_code: 'aha',
user_retention_status_config_id: 'aa11bb22-cc33-4d44-9e55-ff66aa77bb88',
min_actions: 3,
window_days: 7,
time_window: 30,
priority: 1,
},
{
status_code: 'setup',
user_retention_status_config_id: 'bb22cc33-dd44-4e55-9f66-aa88bb99ccaa',
min_actions: 1,
priority: 2,
},
],
},
engagement: {
name: 'Engagement',
source_table: 'events',
source_columns: ['user_id', 'event_id'],
date_column: 'occurred_at',
engagement_window_days: 28,
min_lifetime_actions_for_engaged: 1,
counting_method: 'active_days',
levels: [
{
status_code: 'casual',
user_retention_status_config_id: 'cc33dd44-ee55-4f66-a077-bb99ccaaddbb',
label: 'Casual',
min_threshold: 1,
max_threshold: 7,
order: 1,
},
{
status_code: 'core',
user_retention_status_config_id: 'dd44ee55-ff66-4077-b188-ccaaddbbeecc',
label: 'Core',
min_threshold: 8,
order: 2,
},
],
},
resurrection: {
name: 'Resurrection',
source_table: 'events',
source_columns: ['user_id'],
date_column: 'occurred_at',
thresholds: [
{
status_code: 'dormant',
user_retention_status_config_id: 'ee55ff66-aa77-4188-c299-ddbbeeccffdd',
label: 'Dormant',
threshold_days: 30,
order: 1,
},
{
status_code: 'churned',
user_retention_status_config_id: 'ff66aa77-bb88-4299-d3aa-eeccffdd00ee',
label: 'Churned',
threshold_days: 90,
order: 2,
},
],
},
};

const response = await axios.post(
'https://api.reten.ai/api/activity-generation-configs',
body,
{ headers: { Authorization: 'Bearer <token>', 'x-tenant-id': '<tenant-id>', 'x-project-id': '<project-id>' } },
);
const created = response.data;

Respuesta 201 Created

Devuelve la AGC creada con su configuración anidada completa — incluidos projectId y status: "draft" — en la misma forma camelCase que GET /:id, pero sin effectiveAudienceId ni configHashes: lee la AGC con GET /:id para obtenerlos.

Respuestas de Error

EstadoDescripción
400Validación fallida, o falta un pilar obligatorio (activation / engagement / resurrection)
400status, projectId o project_id en el cuerpo
400Un status_code no es un código activo del catálogo de estados de retención del tenant — status_code "<code>" no es un user retention status válido y activo para este tenant
400Un user_retention_status_config_id no es la entrada del catálogo de su status_code — user_retention_status_config_id no corresponde al status_code "<code>"
400audience_id no es una audiencia del proyecto activo — La audiencia no existe en este proyecto.
409Otra AGC del proyecto activo ya tiene ese nombre — An activity generation config with name "<name>" already exists