← all sprint docs

RC → Amplitude Event Taxonomy — CANONICAL (LOCKED)

Status: LOCKED by Aga + Nic, 9 Jul 2026. Amplitude event names are permanent — do not change without a formal taxonomy migration plan. Owner: tma-analytics-lead (definition) · tma-doc-steward (propagation) Scope: ALL subscription, paywall, and funnel analytics work. Follow exactly.

Core rules

Tiers — the three prerequisites (READ before wiring anything)

The rc_* events split into three tiers with three different prerequisites. Lumping them into one list is what produced the recurring "just do Task 1" loop — most of these are NOT Task 1.

Tier Events Prerequisite Gated by Live now?
A — lifecycle the 15 subscription-lifecycle events below server-side from RevenueCat; just enable the per-event toggles in RC → Integrations → Amplitude (no app change) Task 1 (Nic) ✅ toggle-able now
B — paywalls / experiments the 5 rc_paywall_* + rc_experiment_enrollment emitted only by the RevenueCat Paywalls SDK (RevenueCatUI). TMA's app has a hand-coded paywall, so these physically do not fire — toggling them surfaces nothing RN-4 (a store release) ❌ not until RN-4 ships
C — funnels the 4 rc_funnel_* emitted by RevenueCat Web Billing / hosted funnel. TMA's web checkout is Stripe + GA4, not RC Web Billing N/A to TMA — the web funnel is already measured in GA4 ⚫ will not fire

The rule that stops the loop: "(opt-in in RC dashboard)" only works if a source is actually emitting the event. Opting in a Tier-B/C event with no emitter yields nothing. Never tell anyone to "just do Task 1" for a paywall or funnel event.

Canonical mapping — subscription lifecycle

Tier A — Task 1 toggles. Server-side, no app release. Enable in RC → Integrations → Amplitude, then reconcile ±5% vs RC.

RevenueCat event Amplitude event name
Initial purchase rc_initial_purchase
Trial started rc_trial_started
Trial converted rc_trial_converted
Trial cancelled rc_trial_canceled
Renewal rc_renewal
Cancellation rc_cancellation
Uncancellation rc_uncancellation
Non-subscription purchase rc_non_subscription_purchase
Subscription paused rc_subscription_paused
Expiration rc_expiration
Billing issue rc_billing_issue
Product change rc_product_change
Transfer rc_transfer
Web purchase redeemed rc_web_purchase_redeemed
Experiment enrollment rc_experiment_enrollment

Canonical mapping — RC Paywalls (Tier B — blocked on RN-4)

These only fire once the app ships the RevenueCat Paywalls SDK (RevenueCatUI) — that is task RN-4, a store release. Opting them in without RN-4 surfaces nothing (TMA's paywall is hand-coded today). They are what will finally measure Leak #2 (paywall→card).

RevenueCat event Amplitude event name
Paywall impression rc_paywall_impression
Paywall close rc_paywall_close
Paywall cancel rc_paywall_cancel
Paywall exit offer rc_paywall_exit_offer
Paywall component interacted rc_paywall_component_interacted

Canonical mapping — RC Funnels (Tier C — N/A to TMA)

RevenueCat Web Billing feature; TMA's web funnel is Stripe + GA4. These will not fire unless TMA adopts RC Web Billing — do not put them on the dashboard plan.

RevenueCat event Amplitude event name
Funnel step started rc_funnel_step_started
Funnel step completed rc_funnel_step_completed
Funnel non-checkout completion rc_funnel_non_checkout_completion
Funnel purchase rc_funnel_purchase

Namespace separation — do not merge or conflate

Prefix / name Source Purpose
rc_* RevenueCat → Amplitude integration Server-side subscription lifecycle, RC paywalls, RC funnels
subscription_* TMA web app (amplitude.js) Client UI: checkout started/confirmed, cancel flow, billing portal
purchase, add_to_cart, generate_lead Quiz funnel (GA4 standard, mirrored to Amplitude) Web marketing funnel / Stripe quiz conversion
quiz_paywall_*, exit_popup_* Custom quiz paywall (NOT RC Paywalls) Web quiz paywall UX
af_* AppsFlyer Attribution-side events (af_purchase, af_start_trial, af_subscribe, af_app_open)

Amplitude's AI merge suggestions: merged/virtual events (e.g. a combined "Purchase" view) may be used at the ANALYSIS layer only — raw prefixed events stay unmerged for audit, and pullers reconcile against raw rc_* (±5% vs RC) per GROWTH-SCOREBOARD/SCOREBOARD_OPERATING_MODEL.md §3. ⚠️ Open question for Nic (raised 9 Jul): af_purchase fires 5×/90d vs 191 real subs — exclude it from any merged Purchase view, or fix AF first, so the merged metric isn't polluted by a broken source.

User identity

RevenueCat App User ID must equal Amplitude user_id for event stitching. If IDs differ, set RC attributes $amplitudeUserId / $amplitudeDeviceId.

Verification (T2 landing check)

  1. GET https://amplitude.com/api/2/events/list (Basic auth, creds in .env.local)
  2. Success = the exact names above appear (starting rc_initial_purchase, rc_renewal, rc_trial_started), volumes reconcile ±5% vs RevenueCat (193 subs, ~6 renewals/day).
  3. Status 10 Jul 2026 — ✅ LANDED (partial). rc_initial_purchase and rc_cancellation now exist in Amplitude (taxonomy 95→97 events), using the exact canonical names above. First event: 1 rc_cancellation (10 Jul). 13 of 15 lifecycle events still absent — critically rc_renewal (~6/day expected) and rc_trial_started. Action: enable the remaining per-event toggles in RevenueCat → Integrations → Amplitude, then run the ±5% reconciliation vs RC (240 subs). The 06:00 daily job auto-checks.
  4. Status 13 Jul 2026 — ✅ RESOLVED (live-checked via api/2/events/list). 7 rc_* event types now present in Amplitude: rc_initial_purchase, rc_cancellation, rc_expiration, rc_renewal, rc_trial_started, rc_trial_converted, rc_trial_canceled. The two "critically absent" events (rc_trial_started, rc_renewal) from the 10 Jul reading are LANDING — the trial denominator is live. Remaining: confirm volumes reconcile ±5% vs RC (240 subs, ~6 renewals/day rate as of 10 Jul) and the $amplitudeUserId identity stitch. Event-type presence ≠ volume-verified, so keep the daily reconciliation job.

Where this convention is embedded (steward keeps in sync)