Skip to content

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

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 correct userId
  • 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.