Skip to main content
Use the lifecycle surface when memories mirror records your database owns — CRM rows, profile fields, tickets. Unlike append-only save, these memories have a durable identity and version history, so corrections and deletes from the source of truth apply exactly once, in order, no matter how messy delivery gets.

The identity model

A source-owned memory is identified by (endUserId, source, externalId). version must increase whenever the source record changes.

Delivery guarantees

Mutations are synchronous, and the rules are simple:
  • Retrying the same version + payload returns the same durable receipt. Re-sending after a crash is safe — that is the crash-recovery story.
  • A different payload for an existing version returns 409. Versions are immutable.
  • A delayed older version returns 409 and never overwrites newer content or resurrects a deleted memory.
Deletes follow the same versioning:
The delete is durable: retries converge to the original receipt, and delayed upserts with lower versions cannot recreate the memory.

Bootstrapping with an outbox

Bulk-mirror existing records through lifecycleBatch — up to 100 items and 1 MiB of aggregate content per call. There is no server-side import job; a client-side outbox that re-sends after a crash is the entire resume story:
result.success only means “the batch was processed” — always check per-item outcomes. Mark a row done on success or stale_source_version (both mean the version is already durable), then send the next batch.

Reading back

GET /api/v1/memories/{externalId} returns the memory and its latest applied receipt — useful for verifying convergence after a migration.