Update Lifecycle Configs
In-place update of one or more lifecycle pillars on an AGC.
PUT /api/activity-generation-configs/:id/lifecycle
Update one or more lifecycle pillars of an AGC in place, in a single atomic transaction.
Auth: Required — activity-generation-config:update permission
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | UUID | Activity generation config id |
Request Body
Send only the pillars you want to update. Each pillar you send edits the matching pillar of the AGC in the path — an AGC has exactly one of each, so the body does not identify it. Within a pillar, send only the fields you want to change (the same fields as in create); omitted fields keep their current value. Request bodies are snake_case.
| Field | Type | Required | Description |
|---|---|---|---|
activation | object | No | Activation fields to update. Omit to leave activation untouched. |
engagement | object | No | Engagement fields to update. Omit to leave engagement untouched. |
resurrection | object | No | Resurrection fields to update. Omit to leave resurrection untouched. |
Editing a pillar keeps its id — the same one you read from GET /:id.
Child reconciliation (by id)
Each child item (a moment / level / threshold) carries an optional id. When a pillar includes its child array (moments / levels / thresholds), the children are reconciled against the existing rows; when the array is omitted, the children are left untouched:
| Child in request | Effect |
|---|---|
WITH id matching an existing child | Updated in place (id preserved) |
WITHOUT id | Inserted as a new child |
| Existing child absent from the array | Deleted |
The whole operation runs in one transaction — either every change applies, or none does.
Example — update engagement only
Edit one level (kept by its id), add a new level (no id), and drop a level by omitting it.
curl -X PUT https://api.reten.ai/api/activity-generation-configs/f47ac10b-58cc-4372-a567-0e02b2c3d479/lifecycle \
-H "Authorization: Bearer <token>" \
-H "x-tenant-id: <tenant-id>" \
-H "x-project-id: <project-id>" \
-H "Content-Type: application/json" \
-d '{
"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": [
{
"id": "6e2d4055-af66-4177-c288-ee99ffaa00bb",
"status_code": "casual",
"user_retention_status_config_id": "cc33dd44-ee55-4f66-a077-bb99ccaaddbb",
"label": "Casual",
"min_threshold": 1,
"max_threshold": 9,
"order": 1
},
{
"status_code": "power",
"user_retention_status_config_id": "1122aabb-3344-4ccd-9eef-556677889900",
"label": "Power",
"min_threshold": 10,
"order": 2
}
]
}
}'import axios from 'axios';
const id = 'f47ac10b-58cc-4372-a567-0e02b2c3d479';
const body = {
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: [
{
id: '6e2d4055-af66-4177-c288-ee99ffaa00bb', // has id -> updated in place
status_code: 'casual',
user_retention_status_config_id: 'cc33dd44-ee55-4f66-a077-bb99ccaaddbb',
label: 'Casual',
min_threshold: 1,
max_threshold: 9,
order: 1,
},
{
// no id -> inserted as a new level
status_code: 'power',
user_retention_status_config_id: '1122aabb-3344-4ccd-9eef-556677889900',
label: 'Power',
min_threshold: 10,
order: 2,
},
// the previous "core" level is omitted -> deleted
],
},
// activation and resurrection are omitted -> left untouched
};
await axios.put(
`https://api.reten.ai/api/activity-generation-configs/${id}/lifecycle`,
body,
{ headers: { Authorization: 'Bearer <token>', 'x-tenant-id': '<tenant-id>', 'x-project-id': '<project-id>' } },
);In this example: the casual level is updated in place (its id is preserved), a new power level is inserted, and the previous core level — absent from the array — is deleted. activation and resurrection are omitted, so they are left untouched.
Response 200 OK
Empty body. Fetch GET /:id afterward to read the updated pillars and the recomputed configHashes.
Error Responses
| Status | Description |
|---|---|
400 | Validation failed — including a pillar that carries an id (the pillar is always the one of the AGC in the path) or a child id that does not belong to that pillar |
404 | Activity generation config not found |