--- name: fullstory-saas version: v2 description: Industry-specific guide for implementing Fullstory in B2B SaaS applications. Covers feature adoption tracking, onboarding optimization, churn prediction signals, multi-tenant privacy considerations, role-based experiences, and enterprise customer requirements. Includes detailed examples for dashboards, workflows, settings, and collaboration features. related_skills: - fullstory-privacy-controls - fullstory-privacy-strategy - fullstory-user-properties - fullstory-analytics-events - fullstory-page-properties - fullstory-element-properties --- # Fullstory for B2B SaaS > ⚠️ **LEGAL DISCLAIMER**: This guidance is for educational purposes only and does not constitute legal, compliance, or regulatory advice. SaaS applications may be subject to various regulations (GDPR, CCPA, SOC 2, industry-specific requirements) depending on your customers and data processed. Always consult with your legal and compliance teams before implementing any data capture solution. Your organization is responsible for ensuring compliance with all applicable regulations and customer contracts. ## Industry Overview B2B SaaS applications have unique characteristics for session analytics: - **Feature adoption focus**: Understanding which features users adopt (or don't) - **Onboarding optimization**: Critical first-use experience - **Multi-tenant concerns**: Data separation between customers - **Enterprise requirements**: SOC 2, single-tenant options, data residency - **Complex user hierarchies**: Organizations, teams, roles - **Workflow optimization**: Multi-step processes, collaboration ### Key Goals for SaaS Implementations 1. **Improve onboarding completion** and time-to-value 2. **Understand feature adoption** and usage patterns 3. **Identify friction points** in core workflows 4. **Reduce churn** by identifying at-risk signals 5. **Optimize pricing page** and upgrade flows 6. **Support enterprise customer** requirements --- ## Recommended: Private by Default for Enterprise SaaS For SaaS applications handling customer data, **Private by Default mode is recommended**: ``` ┌─────────────────────────────────────────────────────────────────┐ │ SaaS: Consider Private by Default │ │ │ │ • Multi-tenant = high data sensitivity │ │ • Customer data displayed in your UI → mask by default │ │ • Selectively unmask your UI (buttons, nav, feature names) │ │ • Contact Fullstory Support to enable │ └─────────────────────────────────────────────────────────────────┘ ``` | SaaS Type | Private by Default? | Reason | |-----------|---------------------|--------| | **CRM/Sales tools** | ⚠️ Recommended | Displays customer contact info | | **Project management** | ⚠️ Consider | User-generated content | | **Analytics dashboards** | ⚠️ Consider | Customer business data | | **Developer tools** | ✅ Highly recommended | Code, credentials, secrets | | **HR/Payroll** | ✅ Required | Employee PII | | **Collaboration tools** | ⚠️ Consider | Messages, documents | > **Reference**: [Fullstory Private by Default](https://help.fullstory.com/hc/en-us/articles/360044349073-Fullstory-Private-by-Default) --- ## SaaS Privacy Considerations ### What Can Typically Be Captured | Data Type | Capture? | Notes | |-----------|----------|-------| | Feature usage | ✅ Yes | Core SaaS analytics | | User role/permissions | ✅ Yes | For segmentation | | Account/plan info | ✅ Yes | For segmentation | | Product interactions | ✅ Yes | Core value | | Workflow steps | ✅ Yes | Optimization | | User names | ⚠️ Consider | Mask or use IDs | | Email addresses | ⚠️ Consider | Hash or mask | | User-generated content | ⚠️ Consider | Depends on product | | Customer data in product | ⚠️ Careful | May need exclusion | | File contents | ❌ Usually not | Customer's IP | | API keys/tokens | ❌ Never | Security risk | | Passwords | ❌ Never | Security risk | ### Multi-Tenant Privacy ``` Important: In SaaS, you're capturing data about YOUR users, but they may be working with THEIR customers' data. ┌─────────────────────────────────────────────────────────────────┐ │ YOUR SaaS Application │ │ ┌─────────────────────────────────────────────────────────────┐│ │ │ Customer A's Workspace (their data shown in your UI) ││ │ │ - Their customer lists ││ │ │ - Their financial data ││ │ │ - Their proprietary content ││ │ │ → May need to exclude/mask depending on product ││ │ └─────────────────────────────────────────────────────────────┘│ │ ┌─────────────────────────────────────────────────────────────┐│ │ │ Customer B's Workspace ││ │ │ → Same considerations ││ │ └─────────────────────────────────────────────────────────────┘│ └─────────────────────────────────────────────────────────────────┘ ``` --- ## Implementation Architecture ### Privacy Zones for SaaS ``` ┌─────────────────────────────────────────────────────────────────┐ │ B2B SAAS APPLICATION │ ├─────────────────────────────────────────────────────────────────┤ │ VISIBLE (fs-unmask) │ │ • Navigation and menus │ │ • Feature names and labels │ │ • Action buttons │ │ • Empty states and onboarding UI │ │ • Error messages (generic) │ │ • Settings labels (not values) │ │ • Dashboard structure (not data) │ │ • Pricing and plans │ ├─────────────────────────────────────────────────────────────────┤ │ MASKED (fs-mask) │ │ • User names │ │ • Email addresses (consider hash for ID) │ │ • Company names (unless your user) │ │ • User-generated titles/names │ ├─────────────────────────────────────────────────────────────────┤ │ EXCLUDED (fs-exclude) │ │ • Customer's customer data (CRM contacts, etc.) │ │ • Customer's financial data │ │ • File contents and documents │ │ • API keys and tokens │ │ • Passwords and credentials │ │ • Proprietary/sensitive business data │ │ • Healthcare/financial SaaS: customer's regulated data │ └─────────────────────────────────────────────────────────────────┘ ``` ### User Identification Pattern ```javascript // SaaS: Rich identification for product analytics function onUserLogin(user, organization) { FS('setIdentity', { uid: user.id, // Your internal user ID displayName: user.firstName // Just first name }); FS('setProperties', { type: 'user', properties: { // User context user_role: user.role, // "admin", "member", "viewer" user_created_at: user.createdAt, user_title: user.jobTitle, // If available is_account_owner: user.isOwner, // Organization context (your customer) org_id: organization.id, org_name: organization.name, // Usually OK for your customer org_industry: organization.industry, org_size: getOrgSizeRange(organization.employeeCount), org_plan: organization.plan, // "free", "pro", "enterprise" org_created_at: organization.createdAt, // Feature access has_feature_x: organization.features.includes('feature_x'), has_feature_y: organization.features.includes('feature_y'), // Engagement signals days_since_signup: daysSince(user.createdAt), login_count_30d: user.loginCount30d, last_active_feature: user.lastFeature, // Lifecycle stage is_trial: organization.isTrial, trial_days_remaining: organization.trialDaysRemaining, is_paying: organization.isPaying, mrr: organization.mrr, // Your revenue from this customer // Onboarding onboarding_completed: user.onboardingCompleted, onboarding_step: user.onboardingStep, // Integrations (what they've connected) has_slack_integration: organization.integrations.includes('slack'), has_salesforce_integration: organization.integrations.includes('salesforce'), // Joinable keys crm_account_id: organization.salesforceAccountId, support_org_id: organization.zendeskOrgId } }); } ``` --- ## AI/ML Feature Tracking Modern SaaS applications increasingly use AI/ML features. Track these carefully: ### What to Track for AI Features | AI Feature Type | Track | Don't Track | |-----------------|-------|-------------| | **AI assistants/copilots** | Feature activated, suggestions accepted/rejected | Actual suggestions or prompts containing user data | | **Smart recommendations** | Recommendation shown, clicked, dismissed | The recommended content itself (may contain customer data) | | **Automated workflows** | Automation triggered, completed, failed | Customer data processed by automation | | **Predictive analytics** | Feature viewed, exported | The predictions themselves | | **AI-generated content** | Generation requested, accepted, edited | The generated content | ```javascript // Track AI feature usage without capturing customer data FS('trackEvent', { name: 'ai_feature_interaction', properties: { feature_name: 'smart_compose', interaction_type: 'suggestion_accepted', context: 'email_compose', suggestion_count: 3, accepted_index: 1, response_time_ms: 850, // NEVER: The actual suggestion text, user prompt, or generated content } }); // Track AI feature adoption over time FS('trackEvent', { name: 'ai_feature_first_use', properties: { feature_name: 'report_generator', days_since_signup: 14, user_role: 'analyst', trial_or_paid: 'trial', // Helps understand AI feature discovery patterns } }); ``` ### AI Ethics Considerations | Consideration | Guidance | |---------------|----------| | **Bias auditing** | Track AI feature usage across segments to identify disparities | | **Transparency** | Log when AI made a decision vs user | | **Opt-out tracking** | Track users who disable AI features | | **Error rates** | Track AI failures without capturing the data that caused them | --- ## Page-Specific Implementations ### Onboarding Flow ```html
1. Welcome
2. Team
3. Integration
4. First Project

Welcome to ProductName!

Let's get you set up in just a few minutes.

What best describes your role?

Invite Your Team

ProductName works better with your team.

Connect Your Tools

Connect the tools you already use.

``` ```javascript // Comprehensive onboarding tracking function trackOnboardingStep(step, data) { FS('trackEvent', { name: 'onboarding_step_completed', properties: { step_number: step, step_name: data.stepName, time_on_step_seconds: data.timeOnStep, // Step-specific data ...getStepSpecificData(step, data) } }); } function getStepSpecificData(step, data) { switch(step) { case 'welcome': return { selected_role: data.role, selected_use_case: data.useCase }; case 'team': return { teammates_invited: data.inviteCount, skipped: data.skipped }; case 'integrations': return { integrations_connected: data.connectedIntegrations, skipped: data.skipped }; default: return {}; } } // Track onboarding completion FS('trackEvent', { name: 'onboarding_completed', properties: { total_time_minutes: totalOnboardingTime, steps_skipped: skippedSteps, teammates_invited: inviteCount, integrations_connected: connectedIntegrations, first_project_created: hasFirstProject } }); // Track onboarding abandonment window.addEventListener('beforeunload', () => { if (!onboardingCompleted && currentOnboardingStep) { FS('trackEvent', { name: 'onboarding_abandoned', properties: { abandoned_at_step: currentOnboardingStep, time_in_onboarding_minutes: getOnboardingTime(), steps_completed: completedSteps } }); } }); ``` ### Main Dashboard ```html

Dashboard

Active Users

127 +12%

Projects

24

API Calls

1.2M

Recent Activity

Sarah J. created a new project "Q4 Marketing Campaign" 2 hours ago
``` ```javascript // Dashboard page properties FS('setProperties', { type: 'page', properties: { page_type: 'dashboard', // Usage metrics (your analytics about them) active_users_count: metrics.activeUsers, project_count: metrics.projects, // Feature usage indicators has_active_project: metrics.hasActiveProject, has_recent_activity: metrics.hasRecentActivity, // Dashboard customization widgets_visible: getVisibleWidgets(), date_range_selected: dateRange } }); ``` ### Feature Usage Tracking (Core SaaS Value) ```html

Report Builder

``` ```javascript // Feature usage tracking FS('setProperties', { type: 'page', properties: { page_type: 'report_builder', feature_name: 'report_builder', // Feature state report_id: report.id, is_new_report: report.isNew, chart_count: report.charts.length, // Feature engagement editing_mode: 'visual', // or "code" has_unsaved_changes: report.isDirty } }); // Track feature interactions function onChartAdded(chartType) { FS('trackEvent', { name: 'feature_used', properties: { feature: 'report_builder', action: 'chart_added', chart_type: chartType, total_charts_after: report.charts.length } }); } function onReportSaved(report) { FS('trackEvent', { name: 'feature_used', properties: { feature: 'report_builder', action: 'report_saved', chart_count: report.charts.length, is_first_report: user.reportCount === 1, time_to_create_minutes: report.creationTime } }); } // Track feature discovery function onFeatureFirstUse(featureName) { FS('trackEvent', { name: 'feature_first_use', properties: { feature_name: featureName, days_since_signup: user.daysSinceSignup, discovery_method: getDiscoveryMethod() // "navigation", "search", "help" } }); } ``` ### Settings and Configuration ```html

Profile Settings

Organization Settings

Professional Upgrade

API Access

sk_live_abc123xyz789...
whsec_...

API Usage

This month: 45,000 / 100,000 requests

``` ```javascript // Settings page tracking FS('setProperties', { type: 'page', properties: { page_type: 'settings', settings_section: currentSection // "profile", "billing", "api" } }); // Track settings changes function onSettingsChanged(section, changes) { FS('trackEvent', { name: 'settings_changed', properties: { section: section, fields_changed: Object.keys(changes), // Don't include actual values (could be PII) } }); } ``` ### Billing and Upgrade ```html

Choose Your Plan

Scale as you grow

Starter

$29/month

  • 5 team members
  • 10 projects
  • Basic analytics

Enterprise

Custom

  • Everything in Professional
  • SSO & SAML
  • Dedicated support
  • Custom contracts

Frequently Asked Questions

``` ```javascript // Pricing page tracking FS('setProperties', { type: 'page', properties: { page_type: 'pricing', current_plan: organization.plan, is_trial: organization.isTrial, trial_days_remaining: organization.trialDaysRemaining, billing_cycle_viewed: selectedBillingCycle } }); // Track plan interest function onPlanHover(plan) { FS('trackEvent', { name: 'pricing_plan_interest', properties: { plan_name: plan, interaction_type: 'hover', current_plan: organization.plan } }); } function onPlanSelected(plan) { FS('trackEvent', { name: 'pricing_plan_selected', properties: { plan_name: plan, billing_cycle: selectedBillingCycle, current_plan: organization.plan, is_upgrade: isPlanUpgrade(organization.plan, plan) } }); } // Track upgrade completion function onUpgradeComplete(upgrade) { FS('trackEvent', { name: 'subscription_upgraded', properties: { from_plan: upgrade.previousPlan, to_plan: upgrade.newPlan, billing_cycle: upgrade.billingCycle, mrr_change: upgrade.mrrChange, upgrade_trigger: upgrade.trigger // "trial_end", "feature_limit", "self_serve" } }); } ``` ### Collaboration Features ```html

Comments

Sarah J. 2h ago

Can we adjust the timeline for Q4?

Mike T. 1h ago

Sure, I'll update it now.

``` ```javascript // Collaboration tracking FS('trackEvent', { name: 'collaboration_action', properties: { action_type: 'comment_added', context: 'project', context_id: project.id, is_reply: isReply, mentions_count: mentionsCount // Never: comment content } }); ``` --- ## Churn Prediction Signals Track signals that may indicate churn risk: ```javascript // User engagement signals FS('setProperties', { type: 'user', properties: { // Activity metrics login_frequency: getLoginFrequency(), // "daily", "weekly", "monthly", "rare" days_since_last_login: user.daysSinceLastLogin, // Feature engagement features_used_30d: user.featuresUsed30d.length, core_feature_usage: getCoreFeatureUsage(), // "high", "medium", "low" // Team engagement team_size: organization.teamSize, active_team_members: organization.activeMembers, // Value realization projects_created: user.projectCount, reports_exported: user.exportCount, integrations_active: organization.activeIntegrations.length, // Support/friction support_tickets_30d: organization.ticketCount30d, errors_encountered_30d: user.errorCount30d } }); // Track engagement drop signals function trackEngagementDrop(signal) { FS('trackEvent', { name: 'engagement_signal', properties: { signal_type: signal.type, // "login_frequency_drop", "feature_usage_drop" severity: signal.severity, // "warning", "critical" days_since_baseline: signal.daysSince } }); } ``` --- ## Enterprise Considerations ### For Enterprise Customers ```javascript // Enterprise-specific tracking if (organization.plan === 'enterprise') { FS('setProperties', { type: 'user', properties: { // Enterprise features sso_enabled: organization.ssoEnabled, scim_enabled: organization.scimEnabled, audit_log_enabled: organization.auditLogEnabled, // Compliance data_residency_region: organization.dataRegion, // Scale metrics seat_count: organization.seatCount, workspace_count: organization.workspaceCount } }); } ``` ### Respecting Enterprise Privacy Requirements Some enterprise customers may require special handling: ```javascript // Check for customer-specific privacy requirements function initializeFullstory(organization) { // Some enterprises may opt out of session replay if (organization.settings.disableSessionReplay) { // Don't initialize Fullstory at all return; } // Some may have stricter masking requirements if (organization.settings.strictPrivacyMode) { // Additional element exclusions document.body.classList.add('fs-mask'); } // Initialize with org-specific settings FS('setIdentity', { uid: user.id, consent: organization.settings.analyticsConsent }); } ``` --- ## Common SaaS Patterns ### Feature Adoption Tracking ```javascript // Track feature discovery and adoption const FEATURE_LIST = [ 'report_builder', 'integrations', 'team_collaboration', 'api_access', 'custom_dashboards', 'automation' ]; function trackFeatureAdoption(user) { const adopted = FEATURE_LIST.filter(f => user.hasUsed(f)); const notAdopted = FEATURE_LIST.filter(f => !user.hasUsed(f)); FS('setProperties', { type: 'user', properties: { features_adopted_count: adopted.length, features_adopted: adopted.join(','), features_not_adopted: notAdopted.join(','), adoption_rate: adopted.length / FEATURE_LIST.length } }); } ``` ### Organization Size Ranges ```javascript function getOrgSizeRange(employeeCount) { if (employeeCount <= 10) return '1-10'; if (employeeCount <= 50) return '11-50'; if (employeeCount <= 200) return '51-200'; if (employeeCount <= 1000) return '201-1000'; return '1000+'; } ``` --- ## KEY TAKEAWAYS FOR AGENT When helping SaaS clients with Fullstory: 1. **Feature adoption is core**: Track which features users discover and use 2. **Onboarding is critical**: Comprehensive tracking of first-use experience 3. **Churn signals matter**: Track engagement patterns that predict churn 4. **Multi-tenant privacy**: Customer's customer data may need exclusion 5. **Enterprise requirements**: Be prepared for stricter privacy requirements 6. **API keys/credentials**: Always exclude ### Questions to Ask SaaS Clients 1. "What are your core activation metrics?" 2. "How do you define a 'healthy' user engagement pattern?" 3. "Does your product display your customer's customer data?" 4. "Do you have enterprise customers with special privacy requirements?" 5. "What features are most important to track for conversion?" ### Key Events to Track in SaaS - Onboarding completion - Feature first use - Feature repeated use - Upgrade/downgrade - Team member invited - Integration connected - Export/share actions - Settings changes - Error encounters --- ## REFERENCE LINKS - **Fullstory for Product Teams**: https://www.fullstory.com/product-analytics/ - **Element Properties**: ../core/fullstory-element-properties/SKILL.md - **Analytics Events**: ../core/fullstory-analytics-events/SKILL.md - **User Properties**: ../core/fullstory-user-properties/SKILL.md --- *This skill document is specific to B2B SaaS implementations. Adjust based on your specific product's data sensitivity requirements.*