Reten Docs
Activity Generation Configs

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ámetroTipoDescripción
idUUIDID de la activity generation config

Cuerpo de la Solicitud

El cuerpo es opcional.

CampoTipoRequeridoDescripción
confirmDefaultRootbooleanNoConfirma 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 actualResultado
draftactive
pausedactive
activeSin 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, HAVING ni 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 en draft o paused en esa situación responde 409 con 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

EstadoDescripción
400id no es un UUID válido
400confirmDefaultRoot no es un boolean
400Campo desconocido en el cuerpo
404No existe una activity generation config con ese id en el proyecto activo — Activity generation config <id> not found
409La audiencia raíz del proyecto sigue siendo la por defecto y la solicitud no trae confirmDefaultRoot: true — code: DEFAULT_ROOT_CONFIRMATION_REQUIRED