Yaşam döngüleri
Kayıtlar oluşturulduğunda veya değiştiğinde e-posta, uygulama içi ve tarayıcı bildirimleri, alan güncellemeleri, zamanlanmış tetikleyiciler ve kayıt oluşturma eylemlerini otomatikleştirin (şema odaklı; nesne türü başına en fazla 20 olay).
Per object type, lifecycles run automated actions when entries are created, updated, or become due on a schedule. Configure them in Admin → Objects → Lifecycles, or via the API/MCP lifecycle endpoints.
How it works
A lifecycle config is { version: 3, events: [...] }. Each event has: id, name, optional enabled (default true), when (trigger), constraints (all must pass), and actions. On create/update, matching events run in order. Schedule events are evaluated by a periodic worker sweep (not one-shot enqueue). Actions can send email, create in-app notifications, modify fields, or create related entries. Nested email/notification actions can include links or one-click trigger tokens that apply modify_field effects when opened.
Scheduled events
Use when: { type: "schedule", anchorPath, offsetDays } where anchorPath is an own date/dateTime field or created_at/mutated_at. offsetDays is an integer (default 0; negative allowed). Due instant is the start of the UTC calendar day of the anchor plus the offset. The event is eligible when now >= due. Each firing is recorded once per (entry, event, due_at); if the anchor date later changes, a new due key can fire again.
Field bindings & templates
Binding paths reference own fields (title) or short relation chains (author.display_name, max depth limited by schema). Email/notification subject and title use template segments: { kind: "text", text } or { kind: "field", fieldKey }. HTML bodies may embed {{fieldKey}} placeholders for field chips from the rich-text editor.
Constraints
Constraints are field_compare (leftPath + op + optional right) or related_count (inverse relation count). field_compare rights may be a literal, another field path, or { kind: "relative_date", path, offsetDays } for date comparisons. created_at / mutated_at may be used as date sides. Use changed / changed_to only on update events. related_count counts entries of another type whose relation field points at the current entry (op: eq/neq/lt/gt).
Safety guards
The engine rejects configs that form modify-field cycles across events, or that modify the same field twice in one event. create_entry may trigger the destination type’s entry_created events with the same depth/ruleStack caps as nested updates. Prefer a single modify_field per field per event; chain follow-up work with constraints on the next update.
API & MCP
Read/update lifecycle JSON with GET/PUT /api/v1/{locale}/{websiteId}/objects/{objectTypeId}/lifecycle. MCP tools: get_object_lifecycle, update_object_lifecycle. Use get_lifecycle_docs for this guide.
Reference
Event triggers
entry_created— Fires after a new entry is successfully created.entry_updated— Fires after an entry is updated. Pair withchanged/changed_toconstraints.schedule— Fires from the task worker when now is on/after anchorPath + offsetDays (day granularity).
Actions
send_email— Email toself, a user-relation path, or legacy email field. Optional nested link/trigger actions.create_notification— In-app notification to a relation_user path. Optional link actions.modify_field— Set a field on the current entry to a literal value.create_entry— Create an entry of another type. Each target field maps from a literal, a compatible source field, orself(relation to the triggering entry).
Constraint operators
eq / neq— Equal / not equal to literal or field.empty / not_empty— Presence checks.lt / gt— Numeric comparisons (and related_count).before / after— Date/time comparisons (literal, field, or relative_date).changed / changed_to— Update-only: field changed, or changed to a value.related_count— Compare how many inverse-related entries exist (eq/neq/lt/gt).
Relation hops
forward— Follow a relation field on the current type.inverse— Hop via another type that points at this entry.match— Match another type on a shared field value.
Examples
Welcome email after approval
On update, when approved changes to true, email the member and include a login link.
{
"version": 3,
"events": [
{
"id": "welcome_after_approval",
"name": "Welcome member",
"when": {
"type": "entry_updated"
},
"constraints": [
{
"type": "field_compare",
"leftPath": "approved",
"op": "changed_to",
"right": {
"kind": "literal",
"value": true
}
}
],
"actions": [
{
"type": "send_email",
"emailFieldKey": "self",
"subject": [
{
"kind": "text",
"text": "Welcome to "
},
{
"kind": "field",
"fieldKey": "display_name"
}
],
"bodyHtml": "<p>Your account is ready.</p>",
"actions": [
{
"type": "link",
"label": "Sign in",
"pathTemplate": "/login"
}
]
}
]
}
]
}
Email verification with trigger
On create, send a verification email whose button is a trigger token that sets email_verified (and optionally approved) when clicked.
{
"version": 3,
"events": [
{
"id": "send_email_verification",
"name": "Send email verification",
"when": {
"type": "entry_created"
},
"constraints": [],
"actions": [
{
"type": "send_email",
"emailFieldKey": "self",
"subject": [
{
"kind": "text",
"text": "Verify your email"
}
],
"bodyHtml": "<p>Click below to verify.</p>",
"actions": [
{
"type": "trigger",
"label": "Verify your email",
"tokenTtlMinutes": 1440,
"effects": [
{
"type": "modify_field",
"fieldKey": "email_verified",
"value": true
}
]
}
]
}
]
}
]
}
Notify author on status change
Create an in-app notification for a related user when a status field changes.
{
"version": 3,
"events": [
{
"id": "notify_status",
"name": "Notify author of status",
"when": {
"type": "entry_updated"
},
"constraints": [
{
"type": "field_compare",
"leftPath": "status",
"op": "changed"
}
],
"actions": [
{
"type": "create_notification",
"targetPath": [
{
"kind": "forward",
"fieldKey": "author"
}
],
"title": [
{
"kind": "text",
"text": "Status updated"
}
],
"bodyHtml": "<p>Your item status changed.</p>",
"actions": [
{
"type": "link",
"label": "View",
"pathTemplate": "/items/[id]",
"appendEntryHash": true
}
]
}
]
}
]
}
Schedule first related entry
When first_service_after is due and no service appointments point at this order yet, create one with mapped fields.
{
"version": 3,
"events": [
{
"id": "schedule_first_service",
"name": "Create first service appointment",
"when": {
"type": "schedule",
"anchorPath": "first_service_after",
"offsetDays": 0
},
"constraints": [
{
"type": "related_count",
"objectTypeSlug": "service_appointment",
"fieldKey": "order",
"op": "eq",
"value": 0
}
],
"actions": [
{
"type": "create_entry",
"objectTypeSlug": "service_appointment",
"fields": [
{
"fieldKey": "order",
"source": {
"kind": "self"
}
},
{
"fieldKey": "scheduled_for",
"source": {
"kind": "field",
"path": "first_service_after"
}
},
{
"fieldKey": "status",
"source": {
"kind": "literal",
"value": "planned"
}
}
]
}
]
}
]
}
Notes
- Omit
enabledor setenabled: trueto keep an event active; setenabled: falseto soft-disable. - Locale overlays can localize event names, email subject/body, and action labels per website locale.
- Trigger tokens are time-limited (
tokenTtlMinutes) and apply effects once when redeemed. - Schedule events use day granularity only; hour/minute offsets are out of scope for v1.