Fullstory User Properties API
Implementation Files: This document covers core concepts. For code examples, see:
Overview
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, user properties let you add or update attributes about any user — including anonymous users.
Important: Every new browser/device starts as an anonymous user. 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.
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 (User)
| 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 user properties when you just want to add or update attributes about the current user — this works for both identified AND anonymous users.
Anonymous Users
Every user starts as anonymous, tracked via platform-specific mechanisms:
- Web:
fs_uid first-party cookie (1-year expiry)
- Mobile: Device-based identifier persisted in app storage
Key behaviors:
- Persistent across sessions: As long as the identifier exists, all sessions are linked to the same anonymous user
- Can receive user properties: Add attributes to anonymous users before identification
- Properties transfer on identification: When identity is set, ALL previous sessions merge into the identified user
- Searchable and segmentable: Anonymous users work just like identified users in Fullstory
When to Use Each
User logs in → setIdentity({ uid: "user_123", properties: { displayName: "Jane" } })
↓
User updates profile → setProperties (user) { plan: "pro" }
↓
User upgrades plan → setProperties (user) { plan: "enterprise" }
For anonymous users (not yet logged in):
- Use user properties to capture attributes like visitor type, referral source, landing page
- These properties persist and transfer when/if 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 |
email |
Enables email-based search and HTTP API lookups |
Supported Property Types
| Type |
Description |
Examples |
str |
String value |
"premium", "enterprise" |
strs |
Array of strings |
["admin", "beta-tester"] |
int |
Integer |
42, -5, 0 |
ints |
Array of integers |
[1, 2, 3] |
real |
Float/decimal |
99.99, -3.14 |
reals |
Array of reals |
[10.5, 20.0] |
bool |
Boolean |
true, false |
bools |
Array of booleans |
[true, false, true] |
date |
ISO8601 date |
"2024-01-15T00:00:00Z" |
dates |
Array of dates |
["2024-01-01", "2024-02-01"] |
Rate Limits
| Type |
Limit |
| Sustained |
30 calls per page/screen per minute |
| Burst |
10 calls per second |
Property Naming Conventions
| Rule |
Good |
Bad |
| Use snake_case or camelCase |
plan_tier, planTier |
Plan-Tier, PLAN TIER |
| Be descriptive |
subscription_status |
ss |
| Include units where relevant |
trial_days_remaining |
trial |
| Avoid PII in names |
user_segment |
ssn, credit_card |
Best Practices
1. Property Design
- Set core properties in setIdentity: displayName, email, and other stable attributes
- Use setProperties for updates: Don't re-identify just to update properties
- Include business-relevant data: plan, role, company, feature access
- Use explicit types: Specify schema for non-string values
2. Batching Updates
- Batch rapid updates: If updating multiple properties quickly, combine into one call
- Consider debouncing: For frequently changing data, debounce updates
- Watch rate limits: 30 calls/minute sustained, 10 calls/second burst
3. Property Categories
Recommended property categories for comprehensive user profiles:
| Category |
Example Properties |
| Identity |
displayName, email |
| Subscription |
plan, planTier, billingCycle, mrr |
| Engagement |
lastActiveAt, sessionCount, featureUsageScore |
| Business |
companyName, companySize, industry, role |
| Lifecycle |
signupDate, trialStartedAt, onboardingComplete |
| Attribution |
referralSource, campaign, landingPage |
| Integration |
|
4. Events + Properties
Track both the change (event) and the new state (property):
User upgrades plan:
1. Event: "Plan Upgraded" with from_plan, to_plan, price_change
2. Property: plan = "enterprise", planChangedAt = now
Relationship with Other APIs
setIdentity + setProperties Workflow
- setIdentity: Called on login with core properties (displayName, email)
- setProperties (user): Called later to add/update attributes without re-identifying
setProperties (user) vs setProperties (page)
| Type |
Persistence |
Use For |
| User |
Across sessions |
Who they are (plan, role, company) |
| Page |
Current session/page |
Where they are (pageName, filters, view) |
setProperties vs trackEvent
| API |
Purpose |
Example |
| setProperties |
Current state (what IS) |
plan: "professional", seats: 10 |
| trackEvent |
Actions/changes (what HAPPENED) |
"Plan Upgraded" with from/to values |
Troubleshooting
Properties Not Appearing
| Symptom |
Cause |
Solution |
| No properties in Fullstory |
Missing type parameter |
Always include type: 'user' (web) |
| Properties on wrong user |
Called before identification |
Verify user state before setting |
| Properties not persisting |
Rate limits exceeded |
Batch updates to avoid limits |
Properties Show Wrong Values
| Symptom |
Cause |
Solution |
| Wrong type |
Value format doesn't match schema |
Use clean values (no currency symbols, etc.) |
| Boolean as string |
"true" instead of true |
Use actual boolean type |
| Date not queryable |
Not ISO8601 format |
Use YYYY-MM-DDTHH:mm:ssZ format |
displayName Keeps Getting Overwritten
| Symptom |
Cause |
Solution |
| Name changes unexpectedly |
Multiple places setting displayName |
Only set in identification flow |
| Generic name appears |
Automated scripts overwriting |
Audit all property-setting code |
Limits and Constraints
Property Limits
- Check your Fullstory plan for specific limits
- Property names: alphanumeric, underscores, hyphens
- Avoid high-cardinality properties (unique values for every user)
Value Requirements
- Strings: Must be valid UTF-8
- Numbers: Standard JSON number format
- Dates: ISO8601 format
- Arrays: Maximum length varies by plan
Key Takeaways for Agent
When helping developers implement User Properties:
Always emphasize:
- Include
type: 'user' (web) or use the user properties method
- Use schema for non-string types
- Batch updates to respect rate limits
- displayName and email have special behavior in UI
Common mistakes to watch for:
- Missing type parameter (web)
- Excessive call frequency
- Type mismatches in values
- Overwriting displayName accidentally
- Using setProperties instead of setIdentity for initial identification
Questions to ask developers:
- Will the user be anonymous or identified?
- How often will these properties be updated?
- What data types are these values?
- Do you need to track the change as an event too?
Platform routing:
- Web (JavaScript/TypeScript) → See SKILL-WEB.md
- iOS (Swift/SwiftUI) → See SKILL-MOBILE.md § iOS
- Android (Kotlin) → See SKILL-MOBILE.md § Android
- Flutter (Dart) → See SKILL-MOBILE.md § Flutter
- React Native → See SKILL-MOBILE.md § React Native
Reference Links
1---2name: fullstory-user-properties3description: Core concepts for Fullstory's User Properties API (setProperties with type 'user'). Platform-agnostic guide covering property naming, type handling, special fields, and best practices. See SKILL-WEB.md and SKILL-MOBILE.md for implementation examples.4---56# Fullstory User Properties API78> **Implementation Files**: This document covers core concepts. For code examples, see:9> - [SKILL-WEB.md](./SKILL-WEB.md) — JavaScript/TypeScript (Browser)10> - [SKILL-MOBILE.md](./SKILL-MOBILE.md) — iOS, Android, Flutter, React Native1112## Overview1314Fullstory'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, user properties let you add or update attributes about **any** user — including anonymous users.1516> **Important**: Every new browser/device starts as an anonymous user. 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.1718Key use cases:19- **Anonymous User Enrichment**: Add attributes before the user logs in (referral source, landing page, visitor type)20- **Progressive Profiling**: Update properties as you learn more about the user21- **Subscription/Plan Changes**: Track plan upgrades without re-identifying22- **Preference Tracking**: Store user settings and preferences23- **CRM Sync**: Mirror key CRM fields in Fullstory2425---2627## Core Concepts2829### setIdentity vs setProperties (User)3031| API | Purpose | When to Use | Works for Anonymous? |32|-----|---------|-------------|---------------------|33| `setIdentity` | Link session to a known user ID + optional initial properties | Login, authentication | No (converts anonymous → identified) |34| `setProperties` (user) | Add/update properties for the current user | **Anytime** — works for anonymous AND identified users | **Yes** ✅ |3536> **Key Distinction**: Use `setIdentity` when you need to **link a session to a known user** (requires a `uid`). Use user properties when you just want to **add or update attributes** about the current user — this works for both identified AND anonymous users.3738### Anonymous Users3940Every user starts as anonymous, tracked via platform-specific mechanisms:4142- **Web**: `fs_uid` first-party cookie (1-year expiry)43- **Mobile**: Device-based identifier persisted in app storage4445Key behaviors:46- **Persistent across sessions**: As long as the identifier exists, all sessions are linked to the same anonymous user47- **Can receive user properties**: Add attributes to anonymous users before identification48- **Properties transfer on identification**: When identity is set, ALL previous sessions merge into the identified user49- **Searchable and segmentable**: Anonymous users work just like identified users in Fullstory5051### When to Use Each5253```54User logs in → setIdentity({ uid: "user_123", properties: { displayName: "Jane" } })55 ↓56User updates profile → setProperties (user) { plan: "pro" }57 ↓58User upgrades plan → setProperties (user) { plan: "enterprise" }59```6061**For anonymous users** (not yet logged in):62- Use user properties to capture attributes like visitor type, referral source, landing page63- These properties persist and transfer when/if they later identify6465### Property Persistence6667- User properties persist across sessions68- Properties can be updated at any time69- New properties are added; existing properties are overwritten70- Properties cannot be deleted via the API (contact support)7172### Special Fields7374| Field | Behavior |75|-------|----------|76| `displayName` | Shown in session list and user card in Fullstory UI |77| `email` | Enables email-based search and HTTP API lookups |7879---8081## Supported Property Types8283| Type | Description | Examples |84|------|-------------|----------|85| `str` | String value | "premium", "enterprise" |86| `strs` | Array of strings | ["admin", "beta-tester"] |87| `int` | Integer | 42, -5, 0 |88| `ints` | Array of integers | [1, 2, 3] |89| `real` | Float/decimal | 99.99, -3.14 |90| `reals` | Array of reals | [10.5, 20.0] |91| `bool` | Boolean | true, false |92| `bools` | Array of booleans | [true, false, true] |93| `date` | ISO8601 date | "2024-01-15T00:00:00Z" |94| `dates` | Array of dates | ["2024-01-01", "2024-02-01"] |9596---9798## Rate Limits99100| Type | Limit |101|------|-------|102| Sustained | 30 calls per page/screen per minute |103| Burst | 10 calls per second |104105---106107## Property Naming Conventions108109| Rule | Good | Bad |110|------|------|-----|111| Use snake_case or camelCase | `plan_tier`, `planTier` | `Plan-Tier`, `PLAN TIER` |112| Be descriptive | `subscription_status` | `ss` |113| Include units where relevant | `trial_days_remaining` | `trial` |114| Avoid PII in names | `user_segment` | `ssn`, `credit_card` |115116---117118## Best Practices119120### 1. Property Design121122- **Set core properties in setIdentity**: displayName, email, and other stable attributes123- **Use setProperties for updates**: Don't re-identify just to update properties124- **Include business-relevant data**: plan, role, company, feature access125- **Use explicit types**: Specify schema for non-string values126127### 2. Batching Updates128129- **Batch rapid updates**: If updating multiple properties quickly, combine into one call130- **Consider debouncing**: For frequently changing data, debounce updates131- **Watch rate limits**: 30 calls/minute sustained, 10 calls/second burst132133### 3. Property Categories134135Recommended property categories for comprehensive user profiles:136137| Category | Example Properties |138|----------|-------------------|139| Identity | displayName, email |140| Subscription | plan, planTier, billingCycle, mrr |141| Engagement | lastActiveAt, sessionCount, featureUsageScore |142| Business | companyName, companySize, industry, role |143| Lifecycle | signupDate, trialStartedAt, onboardingComplete |144| Attribution | referralSource, campaign, landingPage |145| Integration | 146147### 4. Events + Properties148149Track **both** the change (event) and the new state (property):150151```152User upgrades plan:153 1. Event: "Plan Upgraded" with from_plan, to_plan, price_change154 2. Property: plan = "enterprise", planChangedAt = now155```156157---158159## Relationship with Other APIs160161### setIdentity + setProperties Workflow1621631. **setIdentity**: Called on login with core properties (displayName, email)1642. **setProperties (user)**: Called later to add/update attributes without re-identifying165166### setProperties (user) vs setProperties (page)167168| Type | Persistence | Use For |169|------|-------------|---------|170| User | Across sessions | Who they are (plan, role, company) |171| Page | Current session/page | Where they are (pageName, filters, view) |172173### setProperties vs trackEvent174175| API | Purpose | Example |176|-----|---------|---------|177| setProperties | Current state (what IS) | plan: "professional", seats: 10 |178| trackEvent | Actions/changes (what HAPPENED) | "Plan Upgraded" with from/to values |179180---181182## Troubleshooting183184### Properties Not Appearing185186| Symptom | Cause | Solution |187|---------|-------|----------|188| No properties in Fullstory | Missing type parameter | Always include `type: 'user'` (web) |189| Properties on wrong user | Called before identification | Verify user state before setting |190| Properties not persisting | Rate limits exceeded | Batch updates to avoid limits |191192### Properties Show Wrong Values193194| Symptom | Cause | Solution |195|---------|-------|----------|196| Wrong type | Value format doesn't match schema | Use clean values (no currency symbols, etc.) |197| Boolean as string | `"true"` instead of `true` | Use actual boolean type |198| Date not queryable | Not ISO8601 format | Use `YYYY-MM-DDTHH:mm:ssZ` format |199200### displayName Keeps Getting Overwritten201202| Symptom | Cause | Solution |203|---------|-------|----------|204| Name changes unexpectedly | Multiple places setting displayName | Only set in identification flow |205| Generic name appears | Automated scripts overwriting | Audit all property-setting code |206207---208209## Limits and Constraints210211### Property Limits212- Check your Fullstory plan for specific limits213- Property names: alphanumeric, underscores, hyphens214- Avoid high-cardinality properties (unique values for every user)215216### Value Requirements217- Strings: Must be valid UTF-8218- Numbers: Standard JSON number format219- Dates: ISO8601 format220- Arrays: Maximum length varies by plan221222---223224## Key Takeaways for Agent225226When helping developers implement User Properties:2272281. **Always emphasize**:229 - Include `type: 'user'` (web) or use the user properties method230 - Use schema for non-string types231 - Batch updates to respect rate limits232 - displayName and email have special behavior in UI2332342. **Common mistakes to watch for**:235 - Missing type parameter (web)236 - Excessive call frequency237 - Type mismatches in values238 - Overwriting displayName accidentally239 - Using setProperties instead of setIdentity for initial identification2402413. **Questions to ask developers**:242 - Will the user be anonymous or identified?243 - How often will these properties be updated?244 - What data types are these values?245 - Do you need to track the change as an event too?2462474. **Platform routing**:248 - Web (JavaScript/TypeScript) → See SKILL-WEB.md249 - iOS (Swift/SwiftUI) → See SKILL-MOBILE.md § iOS250 - Android (Kotlin) → See SKILL-MOBILE.md § Android251 - Flutter (Dart) → See SKILL-MOBILE.md § Flutter252 - React Native → See SKILL-MOBILE.md § React Native253254---255256## Reference Links257258- **User Properties (Web)**: https://developer.fullstory.com/browser/identification/set-user-properties/259- **User Properties (iOS)**: https://developer.fullstory.com/mobile/ios/identification/set-user-properties/260- **User Properties (Android)**: https://developer.fullstory.com/mobile/android/identification/set-user-properties/261- **User Properties (Flutter)**: https://developer.fullstory.com/mobile/flutter/identification/set-user-properties/262- **User Properties (React Native)**: https://developer.fullstory.com/mobile/react-native/identification/set-user-properties/263- **Custom Properties**: https://developer.fullstory.com/browser/custom-properties/264- **Help Center - Custom Properties**: https://help.fullstory.com/hc/en-us/articles/360020623234