Event tracking guide
Track product usage events to power Customer Insights health scores and customer health monitoring.
Last Updated: November 25, 2025
Overview
Event tracking allows you to monitor how customers use your product. Events are automatically batched (20 per batch) and sent to FirstDistro every 5 seconds or on page unload.
Prerequisites: Before tracking events, ensure you've completed the Getting Started guide - specifically installing the SDK (see Installation Guide) and enabling event tracking.
Basic tracking
Track an event
FirstDistro.track('event_name', {
property1: 'value1',
property2: 'value2'
});
Example events
// User actions
FirstDistro.track('user_signed_up', { plan: 'pro', source: 'website' });
FirstDistro.track('user_logged_in', { method: 'email' });
FirstDistro.track('user_logged_out');
// Feature usage
FirstDistro.track('feature_used', {
feature: 'export',
format: 'pdf',
page_count: 10
});
FirstDistro.track('feature_used', {
feature: 'import',
file_type: 'csv',
row_count: 1000
});
// Page views
FirstDistro.track('page_viewed', {
page: '/dashboard',
referrer: '/login'
});
// Milestones
FirstDistro.track('milestone_reached', {
milestone: '100_users',
user_count: 100
});
FirstDistro.track('milestone_reached', {
milestone: 'first_payment',
amount: 99.00
});
Setting user and account context (recommended)
Use setup() to set both user and account context in one call. This is the recommended approach as it handles the correct ordering automatically.
FirstDistro.setup({
user: {
id: 'user-123',
name: 'John Doe',
email: 'john@example.com',
role: 'admin'
},
account: {
id: 'account-456',
name: 'Acme Corp',
plan: 'enterprise',
industry: 'SaaS'
}
});
When to call:
- After user logs in
- When user/account information loads
- When switching accounts (just pass the new account)
Benefits of setup():
- One method instead of two
- Impossible to get the ordering wrong
- Cleaner, more readable code
Updating context:
// Update only user traits
FirstDistro.setup({
user: { id: 'user-123', role: 'superadmin' }
});
// Switch to a different account
FirstDistro.setup({
account: { id: 'new-account', name: 'New Team', plan: 'pro' }
});
User identification (legacy)
Note: We recommend using
setup()instead. See Setting user and account context above.
For granular control, you can identify users separately:
FirstDistro.identify('user-123', {
name: 'John Doe',
email: 'john@example.com',
role: 'admin',
plan: 'pro'
});
⚠️ Important: If using legacy methods, always call group() BEFORE identify() to ensure the user is linked to the account context.
Account grouping (legacy)
Note: We recommend using
setup()instead. See Setting user and account context above.
For granular control, you can group users into accounts separately:
FirstDistro.group('account-456', {
name: 'Acme Corp',
industry: 'SaaS',
plan: 'enterprise',
user_count: 25
});
⚠️ Important:
- Always call
group()FIRST, thenidentify() - Do NOT put user data (user_id, user_email, etc.) in
group()traits
Account grouping required for customer insights
Important: Customer Insights requires account grouping to function. Without FirstDistro.group():
- ✅ Events are stored in the database
- ❌ Events are not processed for health scoring
- ❌ Customers won't appear in Customer Insights dashboard
- ❌ Health scores won't be calculated
- ❌ Alerts won't be generated
With account grouping:
- ✅ Events are stored with
account_id - ✅ Events are aggregated into
customer_accountstable - ✅ Health scores are calculated hourly
- ✅ Customers appear in Customer Insights dashboard
- ✅ Alerts are generated for at-risk customers
Setup: See the Getting Started guide for account grouping setup instructions.
Recommended pattern: setup() → track()
// Set user and account context in one call
FirstDistro.setup({
user: { id: user.id, name: user.name, email: user.email },
account: { id: account.id, name: account.name, plan: account.plan }
});
// Track events (user_id and account_id auto-attached)
FirstDistro.track('feature_used', { feature: 'export' });
// This event will be processed for health scoring ✅
Legacy pattern (still supported): group() → identify() → track()
// Step 1: Group to the ACCOUNT FIRST (sets account context)
FirstDistro.group(account.id, {
name: account.name,
plan: account.plan
});
// Step 2: Identify the USER SECOND (now linked to account)
FirstDistro.identify(user.id, {
name: user.name,
email: user.email
});
// Step 3: Track events
FirstDistro.track('feature_used', { feature: 'export' });
Advanced patterns: For complex account grouping scenarios (multiple accounts, account switching, etc.), see the API Reference.
Handling logout
When a user logs out of your application, you must call FirstDistro.reset() to clear the current user session. This ensures that subsequent events are not incorrectly attributed to the previous user.
// Example: Call this in your logout handler
function handleLogout() {
// Clear FirstDistro user context BEFORE signing out
if (window.FirstDistro) {
FirstDistro.reset();
}
// ... your existing logout logic ...
}
Why this matters:
- The SDK persists
user_idandaccount_idin localStorage - Without
reset(), a new user logging in may inherit the previous user's context - This can cause events to be incorrectly attributed, polluting your analytics data
When to call reset():
- User clicks "Log out" or "Sign out"
- User session expires
- Before switching between accounts (if your app supports multiple accounts)
Recommended events
Track these events for best Customer Insights:
1. authentication events
user_signed_up- New user registrationuser_logged_in- User loginuser_logged_out- User logout
2. feature usage events
feature_used- Any feature interactiondata_imported- Data import completeddata_exported- Data export completedreport_generated- Report created
3. milestone events
milestone_reached- Important milestonesfirst_feature_used- First feature interactionmilestone_100_users- User count milestonesmilestone_1000_users- User count milestones
4. engagement events
page_viewed- Page navigationsession_started- Session beginssession_ended- Session ends
Event properties
Include relevant properties with each event:
FirstDistro.track('feature_used', {
// Feature details
feature: 'export',
feature_category: 'data',
// Usage context
format: 'pdf',
page_count: 10,
file_size_kb: 250,
// User context (auto-added if identified)
user_id: 'user-123', // Auto-added
account_id: 'account-456', // Auto-added after group() call
// Custom properties
source: 'dashboard',
workflow: 'monthly_report'
});
Event batching
Events are automatically batched:
- Batch size: 20 events per batch
- Flush interval: 5 seconds
- Unload flush: Events sent on page close using
sendBeacon()
You don't need to manage batching - it's handled automatically!
Best practices
1. track key user actions
Focus on actions that indicate product value:
- Feature usage
- Data operations
- User milestones
- Engagement patterns
2. use consistent event names
Use snake_case and be descriptive:
- ✅
user_signed_up - ✅
feature_used - ✅
milestone_reached - ❌
signup(too vague) - ❌
click(not descriptive)
3. include relevant properties
Add properties that provide context:
- Feature names
- User/account identifiers
- Quantities (counts, sizes, etc.)
- Timestamps (auto-added)
4. use setup() for context
Use setup() to set user and account context - it handles the ordering automatically:
// Set user and account context in one call
FirstDistro.setup({
user: { id: user.id, name: user.name, email: user.email },
account: { id: account.id, name: account.name, plan: account.plan }
});
// Track events (both user_id and account_id auto-attached)
FirstDistro.track('feature_used', { feature: 'export' });
Why use setup():
- Handles correct ordering internally (account before user)
- Both user_id and account_id are automatically included in tracked events
- This ensures user data appears correctly in Customer Insights
Examples
React integration
Step 1: Add the script tag to your public/index.html:
<!-- Add before closing </body> tag -->
<script src="https://firstdistro.com/sdk/install/fd_your-token-here.js"></script>
Step 2: Use the SDK in your React components:
function App() {
useEffect(() => {
// SDK is automatically initialized after script loads
if (user && account) {
// Set user and account context in one call
FirstDistro.setup({
user: { id: user.id, name: user.name, email: user.email },
account: { id: account.id, name: account.name, plan: account.plan }
});
}
}, [user, account]);
const handleFeatureUse = () => {
FirstDistro.track('feature_used', {
feature: 'export',
format: 'pdf'
});
};
return <button onClick={handleFeatureUse}>Export</button>;
}
Get your token: Dashboard → Settings → SDK Configuration
Next.js integration
// app/layout.tsx
import Script from 'next/script';
export default function RootLayout({ children }) {
return (
<html>
<body>
<Script
src="https://firstdistro.com/sdk/install/fd_your-token-here.js"
strategy="afterInteractive"
/>
{children}
</body>
</html>
);
}
Then use the SDK in your pages:
// app/page.tsx
'use client';
import { useEffect } from 'react';
export default function HomePage() {
useEffect(() => {
if (typeof window === 'undefined' || !window.FirstDistro) return;
// SDK is automatically initialized
if (user && account) {
// Set user and account context in one call
window.FirstDistro.setup({
user: { id: user.id, name: user.name, email: user.email },
account: { id: account.id, name: account.name, plan: account.plan }
});
}
window.FirstDistro.track('page_viewed', { page: '/' });
}, []);
return <div>Welcome</div>;
}
See the Installation Guide for complete setup instructions.
Troubleshooting
Events not sending?
- Check tracking is enabled in dashboard
- Verify API key is correct
- Check browser console for errors
- Verify network requests in Network tab
Events delayed?
- Events are batched (up to 5 seconds delay)
- Events flush on page unload
- This is normal behavior
Too many events?
- Use sample rate in dashboard config
- Filter events client-side before tracking
- Batch related events together
Customers not appearing in Customer Insights?
- Ensure you've called
FirstDistro.group()with account ID - Verify events include
account_id(check browser console) - See Getting Started guide for setup
"No users found" in Customer Detail Modal?
- Ensure you've called
FirstDistro.identify()beforegroup() - Verify
identify()is called with user ID and traits (name, email) - Check that events include
user_id(check browser console) - See API Reference for correct usage pattern
For more help, see the API Reference or email us at jide@firstdistro.com.