> ## Documentation Index
> Fetch the complete documentation index at: https://internal.softcrum.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Standard — Domain Events (v2)

> { id: uuidv7, name, tenant_id, occurred_at, correlation_id, causation_id, actor: {type: user|member|api_key|system, id}, version: int, payload }.

## Envelope (every event, no exceptions)

`{ id: uuidv7, name, tenant_id, occurred_at, correlation_id, causation_id, actor: {type: user|member|api_key|system, id}, version: int, payload }`

* `correlation_id` is born at the entry point (track call, console command, cron job) and propagates through: domain event → rule effect → notification job → send → status history → outgoing webhook. Every BetterStack log line includes `tenant_id` + `correlation_id`.
* `causation_id` = id of the event/command that directly caused this one (chain reconstruction).

## Naming

`{context}.{entity}.{verb_past}` — e.g., `core.contact.created`, `loyalty.points.earned`, `messaging.message.delivered`. Verbs in past tense. English only.

## Catalog v1 (emitted → outbox → 6 consumers; all available as outgoing webhooks)

* core: contact.created|updated|merged · consent.granted|revoked · event.tracked · segment.entered|exited
* loyalty: points.earned|redeemed|expired|adjusted|revoked · points.expiring\_soon · coupon.issued|redeemed|expired · referral.link\_created|converted · tier.upgraded|downgraded
* messaging: campaign.triggered · message.sent|delivered|opened|clicked|bounced|complained
* crm: note.created · activity.completed · list.membership\_changed

## Rules

* Events are emitted ONLY via the transactional outbox, inside the command's transaction. Direct publication is forbidden.
* Payloads are thin: ids + minimal denormalized fields consumers need; consumers fetch the rest. No PII beyond contact\_id unless the consumer contract requires it (webhooks: configurable PII inclusion, default OFF).
* Event schema changes are additive-only within a version; breaking change ⇒ `version+1` and both versions emitted during the deprecation window.
