Skip to main content

Overview

Track subscription lifecycle, user engagement, feature adoption, and churn risk in your SaaS application. Monitor key metrics like MRR, activation rates, and customer health scores.

Subscription Tracking

Initial Setup with Subscription Data

Identify users with their subscription information for automatic enrichment of all events.
import { init, identify, track } from "mentiq-sdk";
import { useEffect } from "react";

function App() {
  useEffect(() => {
    // Initialize MentiQ SDK
    init({
      apiKey: 'your-api-key',
      projectId: 'your-project-id',
      debug: true,
      enableSessionRecording: true,
    });

    // Identify user with subscription data
    identify('user_123', {
      email: '[email protected]',
      name: 'John Doe',
      subscription: {
        status: 'active',
        plan_id: 'plan_abc123',
        plan_name: 'Pro Plan',
        plan_tier: 'pro',
        mrr: 9900, // $99.00 in cents
        billing_interval: 'month',
        current_period_start: '2024-01-01T00:00:00Z',
        current_period_end: '2024-02-01T00:00:00Z',
        provider: 'stripe',
        provider_customer_id: 'cus_abc123',
        provider_subscription_id: 'sub_xyz789',
      },
    });

    // All subsequent events are now automatically enriched with subscription data!
    track('feature_used', { feature: 'analytics_dashboard' });
    // Event will include: subscription_status, subscription_plan, subscription_mrr, is_paid_user
  }, []);

  return <Dashboard />;
}

Track Subscription Events

Monitor the complete subscription lifecycle.
import { useSubscriptionTracking } from "mentiq-sdk";

function CheckoutSuccess() {
  const { trackSubscriptionStarted } = useSubscriptionTracking();

  useEffect(() => {
    // User just completed checkout
    trackSubscriptionStarted({
      status: 'active',
      plan_name: 'Pro Plan',
      plan_tier: 'pro',
      mrr: 9900,
      billing_interval: 'month',
      provider: 'stripe',
      provider_subscription_id: 'sub_xyz789',
    });

    // Update user identity
    identify('user_123', {
      subscription: {
        status: 'active',
        plan_name: 'Pro Plan',
        mrr: 9900,
      },
    });
  }, []);

  return (
    <div>
      <h1>Welcome to Pro!</h1>
      <p>Your subscription is now active.</p>
    </div>
  );
}

Churn Risk Monitoring

Automatically detect at-risk users and trigger retention campaigns.
import { useChurnRisk, useSubscriptionData } from "mentiq-sdk";
import { useState } from "react";

function Dashboard() {
  const { churnRisk, isHighRisk, isCriticalRisk, refresh } = useChurnRisk({
    refreshInterval: 30000, // Check every 30 seconds
    onHighRisk: (risk) => {
      console.log('User is at risk of churning!', risk);
      if (risk.risk_score > 70) {
        showRetentionModal();
      }
    },
  });

  const { subscription, isPaidUser, isTrialing, isCanceled } = useSubscriptionData();

  if (!isPaidUser) {
    return <UpgradePrompt />;
  }

  return (
    <div className="dashboard">
      <header>
        <h1>Dashboard</h1>
        <div className="subscription-info">
          <SubscriptionStatus />
          <ChurnRiskBadge />
        </div>
      </header>

      {/* Show warning for at-risk users */}
      {isHighRisk && (
        <div className="alert alert-warning">
          <h3>Your account health score is {churnRisk?.risk_score}/100</h3>
          <p>We noticed you haven't been using the product much lately.</p>
          <button onClick={showHelpModal}>Get help from our team</button>
        </div>
      )}

      {/* Show critical intervention for very at-risk users */}
      {isCriticalRisk && (
        <RetentionModal
          healthScore={churnRisk?.risk_score}
          factors={churnRisk?.factors}
          onAcceptOffer={handleRetentionOffer}
        />
      )}

      {/* Conditional features based on subscription */}
      <ConditionalRender showFor="paid">
        <PremiumFeatures />
      </ConditionalRender>

      <ConditionalRender showFor="trial">
        <TrialBanner daysLeft={calculateTrialDaysLeft(subscription)} />
      </ConditionalRender>
    </div>
  );
}

Retention Modal Component

Show targeted retention offers based on churn risk.
import { track } from "mentiq-sdk";
import { useState } from "react";

function RetentionModal({ healthScore, factors, onAcceptOffer }) {
  const [showModal, setShowModal] = useState(true);

  const getOffer = () => {
    if (healthScore < 25) {
      return {
        title: 'We want to make this right',
        discount: 50,
        duration: 3,
        message: 'Get 50% off for 3 months while we help you get the most out of our product.',
      };
    } else if (healthScore < 50) {
      return {
        title: 'Let us help you succeed',
        discount: 25,
        duration: 3,
        message: 'Get 25% off and a personalized onboarding session.',
      };
    }
    return null;
  };

  const offer = getOffer();
  if (!offer || !showModal) return null;

  return (
    <div className="modal-overlay">
      <div className="modal retention-modal">
        <h2>{offer.title}</h2>

        <div className="health-score">
          <div className="score-circle">
            <span className="score">{healthScore}</span>
            <span className="label">/100</span>
          </div>
          <p>Your current account health score</p>
        </div>

        <div className="factors">
          <h4>We noticed:</h4>
          <ul>
            {factors.days_since_last_active > 14 && (
              <li>You haven't logged in for {factors.days_since_last_active} days</li>
            )}
            {factors.feature_adoption_rate < 0.3 && (
              <li>You're only using {(factors.feature_adoption_rate * 100).toFixed(0)}% of available features</li>
            )}
            {factors.payment_failures > 0 && (
              <li>{factors.payment_failures} failed payment attempts</li>
            )}
          </ul>
        </div>

        <div className="offer">
          <h3>{offer.message}</h3>
          <div className="discount-badge">
            {offer.discount}% OFF for {offer.duration} months
          </div>
        </div>

        <div className="actions">
          <button
            className="btn btn-primary"
            onClick={() => {
              onAcceptOffer(`discount_${offer.discount}`);
              track('retention_offer_accepted', {
                health_score: healthScore,
                discount: offer.discount,
              });
              setShowModal(false);
            }}
          >
            Accept Offer
          </button>
          <button className="btn btn-secondary" onClick={() => setShowModal(false)}>
            Maybe Later
          </button>
        </div>
      </div>
    </div>
  );
}

Onboarding Tracking

Track user activation and onboarding completion.
import { useOnboardingTracker, useMentiqAnalytics } from "mentiq-sdk";
import { useEffect, useState } from "react";

function OnboardingFlow() {
  const analytics = useMentiqAnalytics();
  const [currentStep, setCurrentStep] = useState(0);

  // Define your onboarding steps
  const onboardingConfig = {
    steps: [
      { name: "account_created", index: 0, required: true },
      { name: "profile_completed", index: 1, required: true },
      { name: "team_invited", index: 2, required: false },
      { name: "first_project_created", index: 3, required: true },
      { name: "integration_connected", index: 4, required: false },
    ],
  };

  const tracker = useOnboardingTracker(analytics, onboardingConfig);

  useEffect(() => {
    tracker?.start({
      signup_method: "email",
      referral_source: "organic",
      plan: "pro_trial",
    });
  }, []);

  const handleAccountCreated = async () => {
    await createAccount();

    tracker?.completeStep("account_created", {
      account_type: "business",
      email_verified: true,
    });

    setCurrentStep(1);
  };

  const handleProfileCompleted = async () => {
    await saveProfile();

    tracker?.completeStep("profile_completed", {
      fields_completed: ["name", "company", "role"],
    });

    setCurrentStep(2);
  };

  const handleSkipTeamInvite = () => {
    tracker?.skipStep("team_invited", "user_wants_to_explore_first");
    setCurrentStep(3);
  };

  const handleFirstProject = async () => {
    await createProject();

    tracker?.completeStep("first_project_created", {
      project_type: "web_app",
    });

    // Onboarding auto-completes when all required steps are done
  };

  const progress = tracker?.getProgress();

  return (
    <div className="onboarding">
      <h2>Get Started - {progress?.progressPercent}% Complete</h2>
      
      <div className="progress-bar">
        <div 
          className="progress-fill" 
          style={{ width: `${progress?.progressPercent || 0}%` }}
        />
      </div>

      {currentStep === 0 && (
        <button onClick={handleAccountCreated}>Create Account</button>
      )}

      {currentStep === 1 && (
        <button onClick={handleProfileCompleted}>Complete Profile</button>
      )}

      {currentStep === 2 && (
        <div>
          <button onClick={() => tracker?.completeStep("team_invited")}>
            Invite Team Members
          </button>
          <button onClick={handleSkipTeamInvite}>Skip for Now</button>
        </div>
      )}

      {currentStep === 3 && (
        <button onClick={handleFirstProject}>Create First Project</button>
      )}
    </div>
  );
}

Feature Usage Tracking

Monitor which features users are engaging with.
import { useMentiqAnalytics } from "mentiq-sdk";

function FeatureUsageExample() {
  const { trackFeatureUsage } = useMentiqAnalytics();

  const handleExportData = () => {
    trackFeatureUsage("data_export", {
      format: "csv",
      rows: 1500,
      feature_tier: "premium",
    });

    exportData();
  };

  const handleGenerateReport = () => {
    trackFeatureUsage("report_generation", {
      report_type: "analytics",
      date_range: "last_30_days",
    });

    generateReport();
  };

  const handleAPIKeyCreated = () => {
    trackFeatureUsage("api_key_created", {
      key_type: "production",
      permissions: ["read", "write"],
    });
  };

  return (
    <div className="features">
      <button onClick={handleExportData}>Export Data</button>
      <button onClick={handleGenerateReport}>Generate Report</button>
      <button onClick={handleAPIKeyCreated}>Create API Key</button>
    </div>
  );
}

Backend Webhook Integration

Handle subscription events from payment providers.
// Node.js/Express webhook handler
import express from 'express';
import Stripe from 'stripe';
import axios from 'axios';

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
const app = express();

app.post('/webhooks/stripe', express.raw({ type: 'application/json' }), async (req, res) => {
  const sig = req.headers['stripe-signature'];
  let event;

  try {
    event = stripe.webhooks.constructEvent(
      req.body,
      sig,
      process.env.STRIPE_WEBHOOK_SECRET
    );
  } catch (err) {
    return res.status(400).send(`Webhook Error: ${err.message}`);
  }

  switch (event.type) {
    case 'customer.subscription.created':
      await handleSubscriptionCreated(event.data.object);
      break;

    case 'customer.subscription.updated':
      await handleSubscriptionUpdated(event.data.object);
      break;

    case 'invoice.payment_failed':
      await handlePaymentFailed(event.data.object);
      break;
  }

  res.json({ received: true });
});

async function handleSubscriptionCreated(subscription) {
  const userId = subscription.metadata.user_id;

  // Track in MentiQ
  await trackToMentiQ({
    event_type: 'subscription_started',
    user_id: userId,
    properties: {
      subscription_status: subscription.status,
      subscription_plan: subscription.plan.nickname,
      subscription_mrr: subscription.plan.amount,
      subscription_provider: 'stripe',
      provider_subscription_id: subscription.id,
      billing_interval: subscription.plan.interval,
    },
  });
}

async function handlePaymentFailed(invoice) {
  const userId = invoice.metadata.user_id;

  await trackToMentiQ({
    event_type: 'payment_failed',
    user_id: userId,
    properties: {
      amount: invoice.amount_due,
      currency: invoice.currency,
      payment_status: 'failed',
      failure_reason: invoice.last_payment_error?.message,
      attempt_count: invoice.attempt_count,
    },
  });
}

async function trackToMentiQ(data) {
  await axios.post('https://api.mentiq.io/api/v1/events', data, {
    headers: {
      'Authorization': `ApiKey ${process.env.MENTIQ_API_KEY}`,
      'X-Project-ID': process.env.MENTIQ_PROJECT_ID,
    },
  });
}

Key SaaS Metrics

The SDK automatically tracks and calculates:

MRR (Monthly Recurring Revenue)

Automatically calculated from subscription data

Churn Risk Score

AI-powered prediction based on user behavior

Feature Adoption Rate

Percentage of available features being used

Activation Rate

Users who complete onboarding successfully

Subscription Components

Pre-built React components for common subscription UI patterns.
import { 
  SubscriptionStatus, 
  SubscriptionMetric, 
  ChurnRiskBadge,
  ConditionalRender 
} from "mentiq-sdk";

function AccountPage() {
  return (
    <div>
      <h2>Account Settings</h2>
      
      {/* Show current subscription status */}
      <SubscriptionStatus />
      
      {/* Display specific metrics */}
      <p>
        Current Plan: <SubscriptionMetric metric="plan" />
      </p>
      <p>
        MRR: <SubscriptionMetric metric="mrr" prefix="$" divisor={100} />
      </p>
      
      {/* Show churn risk indicator */}
      <ChurnRiskBadge />
      
      {/* Conditional content based on subscription */}
      <ConditionalRender showFor="paid">
        <PremiumFeatures />
      </ConditionalRender>
      
      <ConditionalRender showFor="trial">
        <UpgradeBanner />
      </ConditionalRender>
    </div>
  );
}

Analytics Dashboard Insights

Once implemented, access these insights:
  • Monthly Recurring Revenue (MRR) trends
  • Churn rate and at-risk user identification
  • Feature adoption and usage patterns
  • Onboarding completion rates
  • Customer lifetime value (LTV)
  • Trial conversion rates
  • Payment failure rates

Next Steps

Content Tracking

Track reading time and engagement

Advanced Features

Explore session recording and A/B testing

Build docs developers (and LLMs) love