---
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.
```
```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
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
```
```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
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
Starter
$29/month
- 5 team members
- 10 projects
- Basic analytics
Most Popular
Professional
$99/month
- Unlimited team members
- Unlimited projects
- Advanced analytics
- Priority support
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
```
```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.*
Can we adjust the timeline for Q4?
Sure, I'll update it now.