Comprehensive guide for implementing Fullstory's User Properties API (setProperties with type 'user') for web applications. Teaches proper property naming, type handling, incremental updates, and special fields (displayName, email). Includes detailed good/bad examples for CRM integration, progressive profiling, and subscription tracking to help developers enrich user profiles for analytics and segmentation.
Comprehensive guide for implementing Fullstory's User Properties API (setProperties with type 'user') for web applications. Teaches proper property naming, type handling, incremental updates, and special fields (displayName, email). Includes detailed good/bad examples for CRM integration, progressive profiling, and subscription tracking to help developers enrich user profiles for analytics and segmentation.
Fullstory's User Properties API allows developers to capture custom user data that enriches user profiles for search, filtering, segmentation, and analytics. Unlike setIdentity which links a session to a known user ID, setProperties with type: 'user' lets you add or update attributes about any user - including anonymous users.
Important: Every new browser/device starts as an anonymous user, tracked via the fs_uid first-party cookie (1-year expiry). You can set user properties on anonymous users before they ever identify. These properties persist across sessions and transfer when/if the user later identifies via setIdentity.
Key use cases:
Anonymous User Enrichment: Add attributes before the user logs in (referral source, landing page, visitor type)
Progressive Profiling: Update properties as you learn more about the user
Subscription/Plan Changes: Track plan upgrades without re-identifying
Preference Tracking: Store user settings and preferences
CRM Sync: Mirror key CRM fields in Fullstory
Core Concepts
setIdentity vs setProperties
API
Purpose
When to Use
Works for Anonymous?
setIdentity
Link session to a known user ID + optional initial properties
Login, authentication
No (converts anonymous → identified)
setProperties (user)
Add/update properties for the current user
Anytime - works for anonymous AND identified users
Yes ✅
Key Distinction: Use setIdentity when you need to link a session to a known user (requires a uid). Use setProperties when you just want to add or update attributes about the current user - this works for both identified AND anonymous users.
Anonymous Users in Fullstory
Every user starts as anonymous, tracked via the fs_uid first-party cookie:
Cookie-based identity: Fullstory sets an fs_uid cookie (1-year expiry) that tracks the same anonymous user across sessions and page views
Persistent across sessions: As long as the cookie exists, all sessions are linked to the same anonymous user
Can receive user properties: Use setProperties to add attributes to anonymous users
Properties transfer on identification: When setIdentity is called, ALL previous sessions (linked by the cookie) merge into the identified user
Searchable and segmentable: Anonymous users work just like identified users in Fullstory
// User lands on your site (anonymous - "User 4521" in Fullstory)FS('setProperties', {
type: 'user',
properties: {
landing_page: '/pricing',
referral_source: 'google_ads',
campaign: 'spring_sale_2024'
}
});
// ... user browses for a while ...// Later, user creates an account and logs inFS('setIdentity', {
uid: 'user_abc123',
properties: {
displayName: 'Jane Smith',
email: 'jane@example.com'
}
});
// The anonymous properties (landing_page, referral_source, campaign) // are now attached to the identified user "Jane Smith"
When to Use Each
User logs in → setIdentity({ uid: "user_123", properties: { displayName: "Jane" } })
↓
User updates profile → setProperties({ type: 'user', properties: { plan: "pro" } })
↓
User upgrades plan → setProperties({ type: 'user', properties: { plan: "enterprise" } })
For anonymous users (not yet logged in):
// User hasn't logged in yet, but we know something about themFS('setProperties', {
type: 'user',
properties: {
visitor_type: 'returning',
referral_source: 'google_ads',
landing_page: '/pricing'
}
});
// These properties will be associated with the anonymous user// and will persist if/when they later identify
Property Persistence
User properties persist across sessions
Properties can be updated at any time
New properties are added; existing properties are overwritten
Properties cannot be deleted via the API (contact support)
Special Fields
Field
Behavior
displayName
Shown in session list and user card in Fullstory UI
Example 1: Using setProperties Instead of setIdentity
// BAD: Trying to use setProperties for initial identificationFS('setProperties', {
type: 'user',
properties: {
uid: user.id, // This won't work!displayName: user.name,
email: user.email
}
});
Why this is bad:
❌ setProperties doesn't establish identity
❌ uid as a property doesn't link sessions
❌ User remains anonymous
❌ Misunderstanding of API purpose
CORRECTED VERSION:
// GOOD: Use setIdentity for identificationFS('setIdentity', {
uid: user.id,
properties: {
displayName: user.name,
email: user.email
}
});
Example 2: Calling Before Identification
// BAD: Setting user properties before user is identifiedfunctionupdateUserPreferences(preferences) {
// This won't persist properly if user is anonymous!FS('setProperties', {
type: 'user',
properties: {
theme: preferences.theme,
language: preferences.language
}
});
}
Why this is bad:
❌ Properties on anonymous users are session-scoped
❌ Data won't persist across sessions
❌ Can't segment by these properties reliably
CORRECTED VERSION:
// GOOD: Check identification status firstfunctionupdateUserPreferences(preferences) {
// Only set user properties if identifiedif (isUserIdentified()) {
FS('setProperties', {
type: 'user',
properties: {
theme: preferences.theme,
language: preferences.language
}
});
}
// For anonymous users, consider page properties or just skip
}
Example 3: Excessive Calls
// BAD: Calling setProperties too frequentlyfunctionhandleFormFieldChange(fieldName, value) {
// BAD: This fires on every keystroke!FS('setProperties', {
type: 'user',
properties: {
[`form_${fieldName}`]: value
}
});
}
Why this is bad:
❌ Will hit rate limits (30/min, 10/sec)
❌ Wastes API calls on intermediate states
❌ Transient form data isn't good for user properties
CORRECTED VERSION:
// GOOD: Batch updates on form submissionfunctionhandleFormSubmit(formData) {
// Set meaningful final valuesFS('setProperties', {
type: 'user',
properties: {
preferredContact: formData.contactMethod,
marketingOptIn: formData.optIn,
timezone: formData.timezone
}
});
// Track the form submission as eventFS('trackEvent', {
name: 'Preferences Updated',
properties: formData
});
}
This skill document was created to help Agent understand and guide developers in implementing Fullstory's User Properties API correctly for web applications.