Thisbefine
Guides

Lifecycle Events

Track signups, subscriptions, churn, and more with dedicated methods

Lifecycle Events

Type-safe methods for signups, subscriptions, and churn. Consistent naming, autocomplete, automatic insights.

analytics.signup({ method: 'google' });
analytics.subscriptionCancelled({ plan: 'pro', reason: 'too_expensive' });

User Lifecycle

signup(props?)

User created an account.

analytics.signup({
  method: 'google',
  plan: 'free',
  invitedBy: 'user_123',
  campaign: 'producthunt',
});

Prop

Type


login(props?)

User logged in.

analytics.login({
  method: 'passkey',
  isNewDevice: true,
});

Prop

Type


logout(props?)

User logged out.

analytics.logout({
  reason: 'manual', // "manual", "session_expired", "forced"
});

accountDeleted(props?)

User deleted their account. Track this to understand churn.

analytics.accountDeleted({
  reason: 'not_using',
  feedbackScore: 3,
  tenure: 180, // Days since signup
});

Prop

Type


Subscription Lifecycle

subscriptionStarted(props)

User started a paid subscription. Triggers a "New Subscriber" insight.

analytics.subscriptionStarted({
  plan: 'pro',
  interval: 'monthly',
  mrr: 29,
  trialConverted: true,
});

Prop

Type


subscriptionCancelled(props)

User cancelled their subscription. Triggers a critical "Churn Alert" insight.

analytics.subscriptionCancelled({
  plan: 'pro',
  reason: 'too_expensive',
  feedback: 'Love the product but budget is tight',
  mrr: 29,
  tenure: 180,
  willChurnAt: '2025-03-01T00:00:00Z',
});

Prop

Type

This triggers a critical insight. You'll see it immediately in your briefing.


subscriptionRenewed(props)

Subscription auto-renewed. Track retention.

analytics.subscriptionRenewed({
  plan: 'pro',
  interval: 'yearly',
  mrr: 29,
  renewalCount: 3,
});

planUpgraded(props)

User upgraded their plan.

analytics.planUpgraded({
  fromPlan: 'free',
  toPlan: 'pro',
  mrrChange: 29,
});

Prop

Type


planDowngraded(props)

User downgraded their plan. Triggers a "Plan Downgrade" insight.

analytics.planDowngraded({
  fromPlan: 'pro',
  toPlan: 'free',
  reason: 'not_using_features',
  mrrChange: -29,
});

Prop

Type


trialStarted(props)

User started a trial.

analytics.trialStarted({
  plan: 'pro',
  trialDays: 14,
  expiresAt: '2025-02-15T00:00:00Z',
});

trialEnded(props)

Trial expired. Triggers a "Failed Trial" insight if they didn't convert.

analytics.trialEnded({ plan: 'pro', converted: true });

analytics.trialEnded({
  plan: 'pro',
  converted: false,
  reason: 'no_credit_card',
});

Prop

Type


Engagement

inviteSent(props?)

User invited someone to their workspace.

analytics.inviteSent({
  inviteEmail: 'colleague@company.com',
  role: 'member',
});

inviteAccepted(props?)

Invited user joined.

analytics.inviteAccepted({
  invitedBy: 'user_123',
  role: 'member',
});

featureActivated(props)

User activated a key feature for the first time.

analytics.featureActivated({
  feature: 'api_keys',
  isFirstTime: true,
});

Prop

Type


React Hooks

Every lifecycle method has a corresponding hook:

import {
  useSignup,
  useLogin,
  useLogout,
  useAccountDeleted,
  useSubscriptionStarted,
  useSubscriptionCancelled,
  useSubscriptionRenewed,
  usePlanUpgraded,
  usePlanDowngraded,
  useTrialStarted,
  useTrialEnded,
  useInviteSent,
  useInviteAccepted,
  useFeatureActivated,
} from '@thisbefine/analytics/react';

Example:

const SubscriptionPage = () => {
  const subscriptionCancelled = useSubscriptionCancelled();

  const handleCancel = async (reason: string) => {
    await cancelSubscription();

    subscriptionCancelled({
      plan: user.plan,
      reason,
      mrr: user.mrr,
    });
  };

  return (/* ... */);
};

What Happens on the Backend

When you call a lifecycle method:

  1. Event is tracked - Stored like any other event

  2. Properties are validated - Type-checked against expected schema

  3. Insights may trigger - Critical events create briefing cards:

    • subscriptionCancelled → Critical churn alert
    • planDowngraded → High-priority downgrade alert
    • trialEnded (not converted) → Medium-priority trial failure
    • subscriptionStarted → Low-priority new subscriber notice
  4. Webhooks fire - If configured, you'll get notified


Best Practices

Call after the action succeeds:

const handleSignup = async (data) => {
  const user = await createUser(data);
  analytics.identify(user.id, { email: user.email });
  analytics.signup({ method: 'email' });
};

Include relevant properties for better insights.

Identify first, then track lifecycle events so insights know who the user is.

On this page