Single Upsert
Create or update the lifecycle state of a single commerce under an AGC.
POST /api/commerce-lifecycle-snapshots
Creates or updates (upsert) the lifecycle state of a commerce under a specific AGC. If a state already exists for the (commerce, AGC) pair, it is updated; otherwise it is created. Returns the resulting state.
Auth: Required — commerce-lifecycle-snapshot:create permission
To write many states at once, use the batch
upsert (up to 1000
items in a single operation). This endpoint writes one and only accepts
commerce_id (UUID), not an external code.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
commerce_id | UUID | Yes | UUID of the commerce in Reten. Must exist. |
activity_generation_config_id | UUID | Yes | AGC under which the state is written. See AGC identifier. |
code | string | Yes | Retention state code (1–255 characters). Must correspond to a UserRetentionStatusConfig of the tenant; an unknown code responds 400. |
stage | enum | Yes | Stage: ACTIVATION, ENGAGEMENT or RESURRECTION. |
last_computed_at | ISO 8601 | Yes | When the engine computed this state. |
The label is not sent: Reten derives it from the code based on the
retention states config (source of truth for the code → label pair). The
state_changed_at is not sent either: Reten manages it — it only advances if
the (stage, code) pair changes. See
freshness.
Example
curl -X POST "https://api.reten.ai/api/commerce-lifecycle-snapshots" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"commerce_id": "c0000000-0000-4000-8000-000000000004",
"activity_generation_config_id": "a1b2c3d4-0000-4000-8000-000000000001",
"code": "ONBOARDING",
"stage": "ACTIVATION",
"last_computed_at": "2026-06-10T06:00:00.000Z"
}'const response = await fetch(
"https://api.reten.ai/api/commerce-lifecycle-snapshots",
{
method: "POST",
headers: {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
commerce_id: "c0000000-0000-4000-8000-000000000004",
activity_generation_config_id: "a1b2c3d4-0000-4000-8000-000000000001",
code: "ONBOARDING",
stage: "ACTIVATION",
last_computed_at: "2026-06-10T06:00:00.000Z",
}),
},
);
const snapshot = await response.json();import requests
response = requests.post(
"https://api.reten.ai/api/commerce-lifecycle-snapshots",
headers={"x-api-key": "YOUR_API_KEY"},
json={
"commerce_id": "c0000000-0000-4000-8000-000000000004",
"activity_generation_config_id": "a1b2c3d4-0000-4000-8000-000000000001",
"code": "ONBOARDING",
"stage": "ACTIVATION",
"last_computed_at": "2026-06-10T06:00:00.000Z",
},
)
snapshot = response.json()Response 201 Created
Both on create and on update, the endpoint returns the resulting snapshot resource:
{
"id": "5d000000-0000-4000-8000-000000000004",
"commerce_id": "c0000000-0000-4000-8000-000000000004",
"external_id": "SV-004",
"activity_generation_config_id": "a1b2c3d4-0000-4000-8000-000000000001",
"code": "ONBOARDING",
"label": "Onboarding",
"stage": "ACTIVATION",
"last_computed_at": "2026-06-10T06:00:00.000Z",
"state_changed_at": "2026-06-10T06:00:00.000Z"
}Errors
| Status | Description |
|---|---|
400 | Invalid body, unknown code, or invalid stage. |
404 | The commerce (commerce_id) does not exist. |
401 | Missing or invalid API key. |
403 | The credential lacks the commerce-lifecycle-snapshot:create permission. |