events.track() — you get autocomplete and protection against name typos.
The ten helpers
signedUp
user_signed_up — account created.trialStarted
trial_started — trial activated.featureUsed
feature_used — meaningful action in product.onboardingStep
onboarding_step — step started or completed.subscriptionChanged
subscription_changed — any plan/interval change.subscriptionCancelled
subscription_cancelled — cancel requested, still has access.paymentFailed
payment_failed — billing decline.trialExpiring
trial_expiring — trial about to end.userInvited
user_invited — teammate invited.usageThresholdReached
usage_threshold_reached — nearing a plan cap.Reference table
signedUp
Fires when a user creates their account. Drives the signup audience and the “welcome” trigger rule.
trialStarted
Fires when a trial activates. Often the same moment as signup; emit both if so. trialDays is the integer length of the trial in days — Vibefollow uses it to derive the trial-end date, which powers the trial_expiring trigger automatically. Send it once and you don’t need to track the expiry yourself.
featureUsed
Fires when the user does something interesting in your product. The feature string is the audience key — pick stable identifiers (dashboard_export, not Dashboard Export!).
onboardingStep
Fires when a user completes (or starts) an onboarding step. Powers the “onboarding stalled” trigger that nudges users who got partway through.
subscriptionChanged
Fires on any plan change — trial → pro, pro → enterprise, monthly → yearly. The interval field is denormalised onto the user row so audience filters like “all yearly subscribers” can be answered without scanning event JSON. mrr should be in cents (9900 = $99/mo).
subscriptionCancelled
Fires when the user clicks Cancel but still has access. Distinct from churned (truly gone after the grace period — emit a follow-up subscription_changed with to: 'churned' when access actually ends).
paymentFailed
Fires on any billing decline. Powers the “card declined” recovery flow.
trialExpiring
You usually don’t need this. The
trial_expiring trigger is derived automatically — Vibefollow reads trialDays from the most recent trial_started event and fires when the trial is within ~48h of ending. Just call trialStarted with { trialDays } once and the rest is handled.trialDays is the integer number of days left.
userInvited
Fires when a user invites a teammate. Powers the team-expansion nudges.
usageThresholdReached
Fires when a paying user crosses a usage threshold against a metered plan limit (default ~80%). Drives the plan_limit_upsell trigger so the AI can pitch an upgrade before the user hits the cap. meter is an optional free-form label (seats, api_calls, …) so audience rules can target a specific meter; limit is the absolute cap if known.
What if my event isn’t on this list?
Use
events.track(). Custom event names are accepted as-is and become first-class citizens in audience filters. See Custom events.