> ## Documentation Index
> Fetch the complete documentation index at: https://docs.datalyr.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Identity Calls

> Link users across devices and sessions with identify() calls

Identity calls link anonymous visitors to known users, enabling cross-device attribution and complete customer journey tracking.

## What is identify()

The `identify()` method associates a user ID with an anonymous visitor, creating a permanent link between all their activity before and after login.

**Web:**

```javascript theme={null}
datalyr.identify('user_123', {
  email: 'user@example.com',
  name: 'John Doe',
  plan: 'pro'
});
```

**iOS:**

```swift theme={null}
await DatalyrSDK.shared.identify("user_123", properties: [
    "email": "user@example.com",
    "name": "John Doe",
    "plan": "pro"
])
```

**React Native:**

```typescript theme={null}
await Datalyr.identify('user_123', {
  email: 'user@example.com',
  name: 'John Doe',
  plan: 'pro'
});
```

## When to Call identify()

Call `identify()` whenever you learn who the user is:

**After Signup**

```javascript theme={null}
// User completes registration
datalyr.identify(newUser.id, {
  email: newUser.email,
  name: newUser.name,
  signup_date: new Date().toISOString()
});
```

**After Login**

```javascript theme={null}
// User logs in
datalyr.identify(user.id, {
  email: user.email,
  name: user.name,
  last_login: new Date().toISOString()
});
```

**After Email Capture**

```javascript theme={null}
// User subscribes to newsletter
datalyr.identify(user.email, {
  email: user.email,
  subscribed: true,
  subscription_source: 'footer_signup'
});
```

**On Page Load (Logged-In Users)**

```javascript theme={null}
// Restore identity on page load
if (currentUser) {
  datalyr.identify(currentUser.id, {
    email: currentUser.email,
    plan: currentUser.plan
  });
}
```

## User ID Format

The user ID can be any string that uniquely identifies the user:

**Database ID:**

```javascript theme={null}
datalyr.identify('12345');
```

**UUID:**

```javascript theme={null}
datalyr.identify('f47ac10b-58cc-4372-a567-0e02b2c3d479');
```

**Email Address:**

```javascript theme={null}
datalyr.identify('user@example.com');
```

**Custom Format:**

```javascript theme={null}
datalyr.identify('cus_abc123xyz');
```

**Requirements:**

* Must be unique per user
* Must be consistent across sessions and devices
* Recommended: Use your database primary key
* Max length: 255 characters

## User Traits

Traits are optional properties that describe the user.

### Standard Traits

**Contact Information:**

```javascript theme={null}
datalyr.identify('user_123', {
  email: 'user@example.com',
  phone: '+1-555-123-4567',
  name: 'John Doe',
  first_name: 'John',
  last_name: 'Doe'
});
```

**Account Information:**

```javascript theme={null}
datalyr.identify('user_123', {
  plan: 'pro',
  mrr: 99,
  status: 'active',
  created_at: '2025-01-15T10:30:00Z',
  trial_end: '2025-02-15T10:30:00Z'
});
```

**Company Information:**

```javascript theme={null}
datalyr.identify('user_123', {
  company: 'Acme Inc',
  company_size: '50-100',
  industry: 'SaaS',
  role: 'Engineering Manager'
});
```

### Custom Traits

Add any traits relevant to your business:

```javascript theme={null}
datalyr.identify('user_123', {
  // E-commerce
  lifetime_value: 1250.00,
  order_count: 12,
  favorite_category: 'Electronics',

  // SaaS
  seats: 25,
  integrations_enabled: ['slack', 'github'],
  onboarding_completed: true,

  // Media
  subscription_tier: 'premium',
  content_preferences: ['tech', 'business'],
  watch_time_minutes: 1250
});
```

**Best Practices:**

* Use snake\_case for trait names
* Keep trait names consistent
* Don't include sensitive data (passwords, SSNs, credit cards)
* Limit to 50 traits per call

## Identity Resolution

When you call `identify()`, DATALYR creates a permanent link between the anonymous ID and user ID.

### Before identify()

```json theme={null}
{
  "anonymous_id": "anon_abc123",
  "user_id": null,
  "distinct_id": "anon_abc123"
}
```

**Events:**

```
Day 1, 10:00 AM - Page view (anon_abc123)
Day 1, 10:05 AM - Product viewed (anon_abc123)
Day 1, 10:10 AM - Add to cart (anon_abc123)
```

### Call identify()

```javascript theme={null}
datalyr.identify('user_456', {
  email: 'user@example.com'
});
```

### After identify()

```json theme={null}
{
  "anonymous_id": "anon_abc123",
  "user_id": "user_456",
  "distinct_id": "user_456"
}
```

**\$identify Event Sent:**

```json theme={null}
{
  "event_name": "$identify",
  "anonymous_id": "anon_abc123",
  "user_id": "user_456",
  "previous_id": null,
  "traits": {
    "email": "user@example.com"
  },
  "identified_at": "2025-09-29T10:15:00.123Z"
}
```

**All Events Now Linked:**

```
Day 1, 10:00 AM - Page view (user_456, was anon_abc123)
Day 1, 10:05 AM - Product viewed (user_456, was anon_abc123)
Day 1, 10:10 AM - Add to cart (user_456, was anon_abc123)
Day 1, 10:15 AM - Signup (user_456)
```

DATALYR retroactively links all past anonymous events to the user ID.

## Cross-Device Attribution

Identity calls enable attribution across devices and browsers.

### Example: Multi-Device Purchase Journey

**Mobile Phone (Day 1):**

```javascript theme={null}
// User clicks Meta ad on phone
// anonymous_id: anon_mobile_123
// fbclid captured: abc123

// Browse products
datalyr.track('view_item', { product_id: 'SKU123' });

// Add to cart
datalyr.track('add_to_cart', { product_id: 'SKU123' });

// User leaves without purchasing
```

**Desktop (Day 2):**

```javascript theme={null}
// User types URL directly on desktop
// anonymous_id: anon_desktop_456
// source: direct

// User logs in
datalyr.identify('user_789', {
  email: 'user@example.com'
});
// DATALYR links anon_desktop_456 → user_789

// Complete purchase
datalyr.track('purchase', {
  order_id: 'ORDER123',
  revenue: 99.99
});
```

**Mobile Phone (Day 3):**

```javascript theme={null}
// User opens app on phone again
// anonymous_id: anon_mobile_123

// User logs in
datalyr.identify('user_789');
// DATALYR links anon_mobile_123 → user_789
```

**Result:**
DATALYR now knows all three anonymous IDs belong to `user_789` and attributes the purchase to the original Meta ad (fbclid from Day 1).

## Updating User Traits

Call `identify()` multiple times to update user traits:

**Initial Signup:**

```javascript theme={null}
datalyr.identify('user_123', {
  email: 'user@example.com',
  plan: 'free',
  signup_date: '2025-09-01'
});
```

**Upgrade to Pro:**

```javascript theme={null}
datalyr.identify('user_123', {
  plan: 'pro',
  upgrade_date: '2025-09-15',
  mrr: 99
});
```

**Add Company Info:**

```javascript theme={null}
datalyr.identify('user_123', {
  company: 'Acme Inc',
  company_size: '50-100',
  role: 'Manager'
});
```

Traits are merged (new traits added, existing traits updated).

## Reset Identity

Call `reset()` when a user logs out:

**Web:**

```javascript theme={null}
// User logs out
datalyr.reset();
```

**iOS:**

```swift theme={null}
await DatalyrSDK.shared.reset()
```

**React Native:**

```typescript theme={null}
await Datalyr.reset();
```

**What reset() does:**

* Clears user ID from storage
* Keeps anonymous ID (device/browser still tracked)
* Next events tracked as anonymous until next `identify()`

**When to call reset():**

* User logs out
* User switches accounts
* Session ends

## Server-Side Identification

Identify users from your backend:

```javascript theme={null}
// Node.js
await fetch('https://ingest.datalyr.com/events', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    workspaceId: 'ws_123',
    events: [{
      event_name: '$identify',
      anonymous_id: 'anon_abc123', // From client
      user_id: 'user_456',
      properties: {
        email: 'user@example.com',
        plan: 'pro',
        mrr: 99
      },
      timestamp: new Date().toISOString()
    }]
  })
});
```

**Getting anonymous\_id:**

```javascript theme={null}
// Client sends anonymous_id to server
const anonymousId = datalyr.getAnonymousId();

await fetch('/api/signup', {
  method: 'POST',
  body: JSON.stringify({
    email: 'user@example.com',
    anonymous_id: anonymousId // Send to server
  })
});

// Server receives and uses it
app.post('/api/signup', async (req, res) => {
  const { email, anonymous_id } = req.body;

  // Create user in database
  const user = await createUser(email);

  // Send identify event to DATALYR
  await identifyUser(user.id, anonymous_id, {
    email: user.email
  });
});
```

## Identity Best Practices

**Call identify() early and often**

```javascript theme={null}
// Good: Call on every page for logged-in users
if (currentUser) {
  datalyr.identify(currentUser.id);
}

// Bad: Only calling once during signup
// (Users will be anonymous after page reload)
```

**Use consistent user IDs**

```javascript theme={null}
// Good: Same ID across all platforms
datalyr.identify('user_123');        // Web
DatalyrSDK.shared.identify("user_123") // iOS
Datalyr.identify('user_123');        // React Native

// Bad: Different IDs per platform
// (DATALYR won't link them together)
```

**Include email in traits**

```javascript theme={null}
// Good: Email helps with Meta/Google enhanced matching
datalyr.identify('user_123', {
  email: 'user@example.com'
});

// OK: Works but no enhanced matching
datalyr.identify('user_123');
```

**Don't identify anonymous users**

```javascript theme={null}
// Bad: Don't call identify() without a real user ID
datalyr.identify(anonymousId); // NO!

// Good: Only call when you know who the user is
if (userId) {
  datalyr.identify(userId);
}
```

**Hash sensitive data**

```javascript theme={null}
// Bad: Don't send passwords or SSNs
datalyr.identify('user_123', {
  password: 'secret123' // DON'T DO THIS
});

// Good: Only send safe user attributes
datalyr.identify('user_123', {
  email: 'user@example.com',
  plan: 'pro'
});
```

## Troubleshooting

**identify() not working?**

Check:

* User ID is non-empty string
* localStorage is available
* No errors in console
* Events appear in dashboard

**Users not linked across devices?**

Ensure:

* Same user ID used on all devices
* `identify()` called after login on each device
* User ID is consistent (not session-specific)

**Traits not updating?**

Verify:

* `identify()` called with new traits
* Traits are valid JSON types (string, number, boolean, array)
* Not exceeding 50 traits per call

**Previous events not linked?**

This is expected. DATALYR links:

* All events from same anonymous\_id → user\_id
* Does NOT link events from different anonymous IDs unless both are identified with same user\_id

## Next Steps

<CardGroup cols={2}>
  <Card title="Visitor Identification" icon="fingerprint" href="/understanding-data/visitor-identification">
    Understand anonymous IDs
  </Card>

  <Card title="Events Overview" icon="bolt" href="/understanding-data/events-overview">
    Learn about event tracking
  </Card>

  <Card title="Properties and Metadata" icon="tags" href="/understanding-data/properties-and-metadata">
    Add context to events
  </Card>

  <Card title="Cross-Domain Tracking" icon="link" href="/understanding-data/cross-domain-tracking">
    Track across domains
  </Card>
</CardGroup>

## Need Help?

Questions about identity calls? Check our [troubleshooting guide](/troubleshooting/tracking-not-working) or contact support.
