User Identification & Grouping
Advanced features for tracking user identity and organizing users into groups for deeper analytics.
Overview
Beyond basic event tracking, LoopKit provides powerful tools for:
- User Identification: Link anonymous sessions to known users
- User Grouping: Organize users into segments (teams, organizations, plans)
- Cross-Device Tracking: Connect user activity across devices and sessions
User Identification
What is Identify?
The identify
call links an anonymous user to a known user identity when they sign up or log in. This enables LoopKit to:
- Merge anonymous session data with authenticated user data
- Track user journeys across multiple sessions
- Provide more accurate user-level insights
When to Use Identify
javascript
// When user signs up
LoopKit.identify('user_123', {
email: 'user@example.com',
plan: 'pro',
signup_date: '2025-01-15',
});
// When user logs in
LoopKit.identify('user_123', {
last_login: '2025-01-15T10:30:00Z',
login_method: 'email',
});
// When user profile changes
LoopKit.identify('user_123', {
plan: 'enterprise',
team_size: 25,
});
Identify API
javascript
LoopKit.identify(userId, traits);
csharp
LoopKit.Identify(userId, traits);
http
POST https://api.loopkit.ai/v1/identifies
Content-Type: application/json
Authorization: Bearer your-api-key
{
"userId": "user_123",
"anonymousId": "anon_456",
"traits": {
"email": "user@example.com",
"plan": "pro",
"signup_date": "2025-01-15"
},
"timestamp": "2025-01-15T10:30:00Z"
}
User Grouping
What is Group?
The group
call associates users with a group (team, organization, account). This enables:
- Organization-level analytics
- Team performance insights
- Account-based tracking and attribution
When to Use Group
javascript
// When user joins a team
LoopKit.group('team_456', {
name: 'Acme Corp Engineering',
plan: 'enterprise',
size: 25,
industry: 'software',
});
// When team details change
LoopKit.group('team_456', {
plan: 'enterprise_plus',
size: 30,
});
Group API
javascript
LoopKit.group(groupId, traits);
csharp
LoopKit.Group(groupId, traits);
http
POST https://api.loopkit.ai/v1/groups
Content-Type: application/json
Authorization: Bearer your-api-key
{
"groupId": "team_456",
"userId": "user_123",
"anonymousId": "anon_789",
"traits": {
"name": "Acme Corp Engineering",
"plan": "enterprise",
"size": 25,
"industry": "software"
},
"timestamp": "2025-01-15T10:30:00Z"
}
Complete User Journey Example
Here's how to implement a complete user identification and grouping flow:
1. Anonymous User Activity
javascript
// User visits your app (anonymous)
LoopKit.track('page_view', {
page: '/pricing',
});
LoopKit.track('button_click', {
button: 'start_trial',
});
2. User Signs Up
javascript
// User creates account
LoopKit.track('user_signup', {
method: 'email',
source: 'pricing_page',
});
// Identify the user
LoopKit.identify('user_123', {
email: 'john@acme.com',
plan: 'trial',
signup_date: '2025-01-15',
source: 'pricing_page',
});
3. User Joins Team
javascript
// User gets invited to team
LoopKit.track('team_invitation_accepted', {
team_id: 'team_456',
role: 'developer',
});
// Group the user with their team
LoopKit.group('team_456', {
name: 'Acme Corp',
plan: 'enterprise',
size: 25,
industry: 'software',
});
4. Ongoing Activity
javascript
// Continued tracking with rich context
LoopKit.track('feature_used', {
feature: 'api_integration',
team_id: 'team_456',
user_role: 'developer',
});
Implementation Patterns
React/Next.js
jsx
import { useLoopKit } from '../hooks/useLoopKit';
function useAuth() {
const { identify, group, track } = useLoopKit();
const signUp = async (userData) => {
const user = await createUser(userData);
// Track signup event
track('user_signup', {
method: userData.method,
source: userData.source,
});
// Identify the user
identify(user.id, {
email: user.email,
plan: user.plan,
signup_date: user.createdAt,
});
return user;
};
const joinTeam = async (teamId, teamData) => {
// Track team join
track('team_joined', {
team_id: teamId,
role: teamData.role,
});
// Group with team
group(teamId, {
name: teamData.name,
plan: teamData.plan,
size: teamData.memberCount,
industry: teamData.industry,
});
};
return { signUp, joinTeam };
}
Unity
csharp
public class UserManager : MonoBehaviour
{
public void OnUserSignup(User user)
{
// Track signup
LoopKit.Track("user_signup", new {
method = user.signupMethod,
platform = "mobile"
});
// Identify user
LoopKit.Identify(user.id, new {
email = user.email,
platform = "mobile",
device_type = SystemInfo.deviceType.ToString()
});
}
public void OnGuildJoined(string guildId, Guild guild)
{
// Track guild join
LoopKit.Track("guild_joined", new {
guild_id = guildId,
guild_level = guild.level
});
// Group with guild
LoopKit.Group(guildId, new {
name = guild.name,
level = guild.level,
member_count = guild.memberCount,
guild_type = guild.type
});
}
}
Data Privacy & GDPR
User Consent
javascript
// Check user consent before identifying
const hasAnalyticsConsent = await getUserConsent('analytics');
if (hasAnalyticsConsent) {
LoopKit.identify(user.id, {
plan: user.plan,
signup_date: user.createdAt,
// Don't include PII without explicit consent
});
}
Data Deletion
When users request data deletion:
javascript
// Request user data deletion
LoopKit.deleteUser(userId);
// Or delete group data
LoopKit.deleteGroup(groupId);
Best Practices
1. Identify Early and Often
javascript
// ✅ Good: Identify immediately after signup
LoopKit.identify(user.id, userTraits);
// ✅ Good: Update traits when they change
LoopKit.identify(user.id, { plan: 'pro' });
// ❌ Avoid: Waiting too long to identify
2. Use Meaningful Group IDs
javascript
// ✅ Good: Descriptive group IDs
LoopKit.group('acme-corp-team-123', traits);
// ❌ Avoid: Generic or unclear IDs
LoopKit.group('group-1', traits);
3. Include Relevant Traits
javascript
// ✅ Good: Rich, relevant traits
LoopKit.identify(user.id, {
plan: 'enterprise',
role: 'admin',
team_size: 25,
signup_date: '2025-01-15',
});
// ❌ Avoid: Empty or meaningless traits
LoopKit.identify(user.id, {});
4. Respect Privacy
javascript
// ✅ Good: Hash or anonymize PII
LoopKit.identify(user.id, {
email_hash: hashEmail(user.email),
plan: user.plan,
});
// ❌ Avoid: Raw PII without consent
LoopKit.identify(user.id, {
email: user.email,
full_name: user.name,
});
Troubleshooting
Common Issues
Q: User data isn't merging properly
- Ensure you're calling
identify
with the correctuserId
- Check that
anonymousId
is consistent across calls - Verify API key has identify permissions
Q: Group insights aren't appearing
- Confirm group traits include meaningful data
- Check that multiple users are associated with the group
- Ensure group calls happen after user identification
Q: Cross-device tracking not working
- Verify users are identified on all devices
- Check that the same
userId
is used consistently - Ensure identify calls happen early in the session
Next Steps
Need help with identification and grouping? Join our Discord for expert guidance.