Upsert Individual
Crea o actualiza el estado de ciclo de vida de un único comercio bajo una AGC.
POST /api/commerce-lifecycle-snapshots
Crea o actualiza (upsert) el estado de ciclo de vida de un comercio bajo una AGC concreta. Si ya existe un estado para el par (comercio, AGC), se actualiza; si no, se crea. Devuelve el estado resultante.
Auth: Requerida — permiso commerce-lifecycle-snapshot:create
Para escribir muchos estados a la vez, usa el upsert por
lote (hasta 1000
items en una sola operación). Este endpoint escribe uno y solo acepta
commerce_id (UUID), no código externo.
Cuerpo de la Petición
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
commerce_id | UUID | Sí | UUID del comercio en Reten. Debe existir. |
activity_generation_config_id | UUID | Sí | AGC bajo la cual se escribe el estado. Ver identificador de AGC. |
code | string | Sí | Código del estado de retención (1–255 caracteres). Debe corresponder a un UserRetentionStatusConfig del tenant; un código desconocido responde 400. |
stage | enum | Sí | Etapa: ACTIVATION, ENGAGEMENT o RESURRECTION. |
last_computed_at | ISO 8601 | Sí | Cuándo el motor calculó este estado. |
El label no se envía: Reten lo deriva del code a partir de la config
de estados de retención (fuente de verdad del par code → label). El
state_changed_at tampoco se envía: lo gestiona Reten — solo avanza si cambia
el par (stage, code). Ver
frescura.
Ejemplo
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()Respuesta 201 Created
Tanto al crear como al actualizar, el endpoint devuelve el recurso snapshot resultante:
{
"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": "En onboarding",
"stage": "ACTIVATION",
"last_computed_at": "2026-06-10T06:00:00.000Z",
"state_changed_at": "2026-06-10T06:00:00.000Z"
}Errores
| Status | Descripción |
|---|---|
400 | Cuerpo inválido, code desconocido, o stage no válido. |
404 | El comercio (commerce_id) no existe. |
401 | Clave de API faltante o inválida. |
403 | La credencial no tiene el permiso commerce-lifecycle-snapshot:create. |