Publicar Activity Generation Config
Pasar una activity generation config de draft o paused a active.
PATCH /api/activity-generation-configs/:id/publish
Publica una AGC del proyecto activo: la pasa de draft o paused a active (ver Estado). Sólo las configuraciones active están pensadas para correr. Una AGC pausada se reanuda con este mismo endpoint y conserva su id.
Auth: Requerida — permiso activity-generation-config:update
Parámetros de Ruta
| Parámetro | Tipo | Descripción |
|---|---|---|
id | UUID | ID de la activity generation config |
Cuerpo de la Solicitud
El cuerpo es opcional.
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
confirmDefaultRoot | boolean | No | Confirma la publicación mientras la audiencia raíz del proyecto sigue siendo la por defecto (ver abajo). Sólo true confirma; ausente, false o null no |
Transiciones
| Estado actual | Resultado |
|---|---|
draft | active |
paused | active |
active | Sin cambio: responde 200 con la AGC tal como está, sin revisar la audiencia raíz |
Confirmación de la audiencia raíz por defecto
Todo proyecto se crea con su audiencia raíz Toda la empresa: los comercios activos (ver Proyectos → Audiencia raíz). Mientras la audiencia raíz conserve esa definición por defecto, publicar hace correr la configuración sobre toda la empresa, así que la API pide una confirmación explícita.
- La audiencia raíz es por defecto mientras su definición siga siendo exactamente la original: un solo bloque de consulta equivalente a
SELECT DISTINCT user_id FROM user_properties WHERE is_active = true, sin joins, ventana de tiempo, agrupación,HAVINGni composiciones. Cualquier otro cambio de estructura la vuelve editada; renombrarla no. Una audiencia raíz editada y luego devuelta a esa definición vuelve a ser por defecto. - La revisión es siempre sobre la audiencia raíz del proyecto, aunque la AGC tenga su propio
audienceId. - Sin
confirmDefaultRoot: true, publicar una AGC endraftopauseden esa situación responde409con este cuerpo, y la AGC conserva su estado:
{
"statusCode": 409,
"error": "Conflict",
"code": "DEFAULT_ROOT_CONFIRMATION_REQUIRED",
"message": "La raíz del proyecto sigue siendo la raíz por defecto («Toda la empresa»): publicar hará correr esta configuración sobre toda la empresa. Para confirmarlo, reenvía la solicitud con `confirmDefaultRoot: true`."
}Ramifica por code, nunca por el texto de message, que puede cambiar (ver Respuestas de Error). Para confirmar, envía la misma solicitud con { "confirmDefaultRoot": true }; enviarlo con la audiencia raíz ya editada es inocuo, y la AGC se publica igual. Para publicar sin la confirmación, edita antes la audiencia raíz del proyecto.
Ejemplo
curl -X PATCH https://api.reten.ai/api/activity-generation-configs/f47ac10b-58cc-4372-a567-0e02b2c3d479/publish \
-H "Authorization: Bearer <token>" \
-H "x-tenant-id: <tenant-id>" \
-H "x-project-id: <project-id>" \
-H "Content-Type: application/json" \
-d '{ "confirmDefaultRoot": true }'import axios from 'axios';
const id = 'f47ac10b-58cc-4372-a567-0e02b2c3d479';
const url = `https://api.reten.ai/api/activity-generation-configs/${id}/publish`;
const headers = { Authorization: 'Bearer <token>', 'x-tenant-id': '<tenant-id>', 'x-project-id': '<project-id>' };
let published;
try {
published = (await axios.patch(url, {}, { headers })).data;
} catch (error) {
// La audiencia raíz del proyecto sigue siendo la por defecto
if (axios.isAxiosError(error) && error.response?.data?.code === 'DEFAULT_ROOT_CONFIRMATION_REQUIRED') {
// Confirma con el usuario antes de publicar sobre toda la empresa
published = (await axios.patch(url, { confirmDefaultRoot: true }, { headers })).data;
} else {
throw error;
}
}Respuesta 200 OK
Devuelve la AGC con su nuevo status y sus tres pilares anidados, en la misma forma camelCase que GET /:id, pero sin effectiveAudienceId ni configHashes.
{
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"projectId": "3f6c2b1a-8d4e-4f7a-9b2c-5e1d0a7f6c34",
"name": "Default lifecycle",
"description": "Activation, engagement and resurrection for the main funnel",
"audienceId": "1f0d2c3b-4a59-4687-9c12-abcdef012345",
"status": "active",
"updatedBy": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"createdAt": "2026-06-10T14:00:00.000Z",
"updatedAt": "2026-06-20T10:00:00.000Z",
"activationConfig": {
"id": "2a8f0c11-6b22-4d33-8e44-aa55bb66cc77",
"name": "Activation",
"description": "First-week activation moments",
"sourceTable": "events",
"sourceColumns": ["user_id", "event_id"],
"dateColumn": "occurred_at",
"activityGenerationConfigId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"aggregationMethod": "nunique",
"isActive": true,
"updatedBy": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"createdAt": "2026-06-10T14:00:00.000Z",
"updatedAt": "2026-06-10T14:00:00.000Z",
"activationMoments": [
{
"id": "3b9a1d22-7c33-4e44-9f55-bb66cc77dd88",
"activationConfigId": "2a8f0c11-6b22-4d33-8e44-aa55bb66cc77",
"statusCode": "aha",
"userRetentionStatusConfigId": "aa11bb22-cc33-4d44-9e55-ff66aa77bb88",
"minActions": 3,
"windowDays": 7,
"timeWindow": 30,
"priority": 1,
"isActive": true,
"createdAt": "2026-06-10T14:00:00.000Z",
"updatedAt": "2026-06-10T14:00:00.000Z"
}
]
},
"engagementConfig": {
"id": "5d1c3f44-9e55-4066-b177-dd88ee99ffaa",
"name": "Engagement",
"description": "Active-user engagement levels",
"sourceTable": "events",
"sourceColumns": ["user_id", "event_id"],
"dateColumn": "occurred_at",
"activityGenerationConfigId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"engagementWindowDays": 28,
"minLifetimeActionsForEngaged": 1,
"countingMethod": "active_days",
"isActive": true,
"updatedBy": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"createdAt": "2026-06-10T14:00:00.000Z",
"updatedAt": "2026-06-10T14:00:00.000Z",
"engagementLevels": [
{
"id": "6e2d4055-af66-4177-c288-ee99ffaa00bb",
"engagementConfigId": "5d1c3f44-9e55-4066-b177-dd88ee99ffaa",
"statusCode": "casual",
"userRetentionStatusConfigId": "cc33dd44-ee55-4f66-a077-bb99ccaaddbb",
"label": "Casual",
"minThreshold": 1,
"maxThreshold": 7,
"order": 1,
"isActive": true,
"createdAt": "2026-06-10T14:00:00.000Z",
"updatedAt": "2026-06-10T14:00:00.000Z"
}
]
},
"resurrectionConfig": {
"id": "8a4f6277-c188-4399-e400-aa00bb11ccdd",
"name": "Resurrection",
"description": "Recovery vs. churn classification",
"sourceTable": "events",
"sourceColumns": ["user_id"],
"dateColumn": "occurred_at",
"activityGenerationConfigId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"isActive": true,
"updatedBy": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"createdAt": "2026-06-10T14:00:00.000Z",
"updatedAt": "2026-06-10T14:00:00.000Z",
"resurrectionThresholds": [
{
"id": "9b5a7388-d299-44aa-f511-bb11ccdd22ee",
"resurrectionConfigId": "8a4f6277-c188-4399-e400-aa00bb11ccdd",
"statusCode": "dormant",
"userRetentionStatusConfigId": "ee55ff66-aa77-4188-c299-ddbbeeccffdd",
"label": "Dormant",
"thresholdDays": 30,
"order": 1,
"isActive": true,
"createdAt": "2026-06-10T14:00:00.000Z",
"updatedAt": "2026-06-10T14:00:00.000Z"
}
]
}
}Respuestas de Error
| Estado | Descripción |
|---|---|
400 | id no es un UUID válido |
400 | confirmDefaultRoot no es un boolean |
400 | Campo desconocido en el cuerpo |
404 | No existe una activity generation config con ese id en el proyecto activo — Activity generation config <id> not found |
409 | La audiencia raíz del proyecto sigue siendo la por defecto y la solicitud no trae confirmDefaultRoot: true — code: DEFAULT_ROOT_CONFIRMATION_REQUIRED |