Read the lifecycle event log.
The append-only record every metric derives from — how to query it, why it stores two deltas and two timestamps, and how to reconcile a dashboard number back to its events.
01One log, fourteen verbs
Every revenue-moving moment writes exactly one event: CREATED, RENEWED, REACTIVATED, EXPANDED, CONTRACTED, CANCEL_SCHEDULED, CHURNED, plus the migration and component events MIGRATE_MODULE, MIGRATE_BUNDLE, MIGRATE_COMPONENT, ADD_COMPONENT and REMOVE_COMPONENT. Subscription status is a convenience view; the event log is the source of truth. If a number in analytics looks wrong, the log is where you check — not the subscription document.
02Two deltas per event
Each event stamps the MRR delta twice: in the subscription's native currency and converted to your reporting currency at that day's rate. FX shifts later never rewrite history — a EUR expansion from March keeps March's conversion forever, which is what makes month-over-month comparisons stable.
03Two timestamps per event
occurredAt is the economically real moment (the renewal boundary, the day the expansion took effect); createdAt is when the row was written. Backfills and late corrections make these differ. Analytics windows use a third field, attributedAt, which defaults to occurredAt. It differs only for usage movements, which are booked in the service period the usage was consumed in, not on the invoice date. A correction entered today for a March event still lands in March, where it belongs.
- Event recordedoccurredAt is the economically real moment.
- Any other eventattributedAt equals occurredAt.orUsage movementattributedAt falls in the service period the usage was consumed in.
- Analytics windowFilters on attributedAt.
04Query it
subscriptionLifecycleEvents(subscriptionId) returns one subscription's timeline, oldest first. organizationLifecycleEvents(organizationId, from?, to?) is the customer-wide view across all their subscriptions, capped at 1000 rows — use the date window to page through long histories.
05Corrections are new events
The log is append-only: nothing is ever updated or deleted. A wrong CHURNED gets balanced by a REACTIVATED; a mis-sized expansion gets a compensating CONTRACTED. This is deliberate — an audit trail you can edit is not an audit trail. If a delta looks odd, look for its correcting sibling before assuming a bug.
06Reconcile analytics against it
MRR movement, ARR, NRR, and churn are all derived by summing event deltas over windows — mrrMovement's New/Expansion/Contraction/Churn buckets map one-to-one onto event types. To verify any dashboard figure, sum the reporting-currency deltas for that window yourself; monthlyDrillDown gives you the per-subscription rows behind any single bar.