/v1/lifecycle
Observe the processing lifecycle of an event — list, per-event summary, SSE stream, and cancel.
The lifecycle API exposes how an event moves through the pipeline — captured → extracted → indexed → consolidated → …. See Lifecycle for the model.
List
GET /v1/lifecycle → { items: [...], next_offset, has_more } (offset pagination). Each item:
{ "lifecycle_id": "lce_01HX...", "ts": "2026-05-15T10:42:01Z", "scope": "org:acme", "event": "indexed", "data": { "event_id": "evt_01HX...", "layers_indexed": ["events"] } }Item field names (v0.9.9; field set unchanged through the v0.10.1 schema)
The type field is event (not kind), the body is data (not payload), and the
event_id lives inside data (not top-level).
SSE stream
GET /v1/lifecycle/stream?scope=… (with Accept: text/event-stream). Real frame data shapes:
| Frame | data |
|---|---|
captured | { event_id, wal_offset, actor, modality } |
extracted | { event_id, derived: {} } |
indexed | { event_id, layers_indexed: ["events"] } |
consolidated | { event_id, beliefs_updated, conflicts_resolved } |
Two extra event types
Live also emits synthesis_progress and synthesis_complete (from
/understanding/synthesize), in addition to
captured / extracted / indexed / consolidated / compressed / forgotten. Use Last-Event-ID (or the
since_lifecycle_id filter) to resume. Stream filters: scope, event_id, events,
since_lifecycle_id.
Per-event summary and cancel
GET /v1/lifecycle/event/{lce_id}→ the single lifecycle event.GET /v1/lifecycle/memory-event/{id}→{ event_id, stages_completed, lifecycle_event_ids, derived }. On a self-host the syncderivedcame back{}even for events that later produced facts — facts arrive via the async enrichment router and are not linked into this summary.POST /v1/lifecycle/memory-event/{id}/cancel(send no body, or{}as JSON; an empty body labelledContent-Type: application/json→400, andcurl -d '', which labels it a form, →415) →200{ event_id, stages_cancelled, stages_already_completed, excluded_from_recall: true }. Verified on v0.10.2: the event leavesGET /v1/events,GET /v1/events/{id}answers404, and it is gone from every recall view —granular,raw, the defaultholistic,descend,prefer_exhaustiveandorder: "recency"— and from the/v1/answercontext. On v0.10.1 theholisticpack,prefer_exhaustiveandrecencystill returned it. The event is still stored (a later forget by id reports it deleted); use forget or erasures to delete it. After a cancel,GET /v1/experience/statusreports the event asfailed("excluded from recall after indexing failed terminally"): that is the cancel, not an indexing failure, so don't re-send the write. (Unlike this cancel, an erasure's cancel only reaches a job that is still running.)
Retry a cancel that answers 404 (v0.10.2)
While other captures are creating new scopes — anywhere on the server — a cancel can answer a spurious
404 NOT_FOUND and cancel nothing (14 of 30 cancels beside 12 such writers in one test). Unlike forgets
and erasures, this route still checks against the scope registry it started with. Retry it; most
retries succeed.