Skip to main content

Auto-Identify

By default, Outlit automatically identifies visitors when they submit a form containing an email field—no code required.

How It Works

When a form is submitted, Outlit:
  1. Detects email by looking for:
    • Field names: email, e-mail, user_email, emailAddress
    • Input type: type="email"
    • Any field with a valid email value (fallback)
  2. Extracts name by looking for:
    • Full name: name, full_name, fullname, your_name
    • First name: first_name, fname, firstname, given_name
    • Last name: last_name, lname, surname, family_name
  3. Calls identify() automatically:
// This happens behind the scenes when a form with email is submitted
identify({
  email: 'jane@acme.com',
  traits: {
    name: 'Jane Doe',      // If full name found
    firstName: 'Jane',     // If first name found
    lastName: 'Doe'        // If last name found
  }
})
The form submission event is still captured separately. Auto-identify adds an additional identify event when an email is found.

Supported Form Types

Auto-identify works with common form patterns:
Form TypeFields Detected
Newsletter signupemail
Contact formemail, name, company
Demo requestemail, first_name, last_name, company
Lead magnetemail, name
Account signupemail, password (password excluded from capture)

Disabling Auto-Identify

If you prefer to handle identification manually (e.g., for custom validation or delayed identification):
<script
  src="https://cdn.outlit.ai/stable/outlit.js"
  data-public-key="pk_xxx"
  data-auto-identify="false"
  async
></script>
When auto-identify is disabled, form submissions are still captured. Only the automatic identify() call is skipped. You’ll need to call identify() manually when appropriate.

The Identity Challenge

Modern customers interact with your business across multiple touchpoints:
  • Multiple devices (phone, laptop, tablet)
  • Different browsers
  • Various email addresses
  • Social logins vs email logins
  • Website visits before signup
Outlit automatically resolves these identities into unified customer profiles.

How Identity Resolution Works

Identity Priority

When multiple identifiers exist, Outlit uses this priority order:
PriorityIdentifier TypeExampleSource
1 (Highest)Emailjane@acme.comIdentify call, form submission
2External User IDusr_12345Auth provider (Supabase, Auth0)
3Stripe Customer IDcus_abc123Stripe integration
4CRM Contact IDcontact_xyzSalesforce, HubSpot sync
5Phone Number+1-555-1234Form submission
6 (Lowest)Anonymous IDabc-def-123Browser visitor ID

Resolution Process

When you call identify():
  1. Search existing contacts by provided identifiers
  2. Match found? Link the anonymous visitor to existing contact
  3. No match? Create new CustomerContact and Customer
  4. Multiple matches? Merge profiles, keeping the most complete one

Identifier Types

Email (Primary)

Email is the most reliable identifier because:
  • Unique per person (usually)
  • Verified through login/signup
  • Works across devices
outlit.identify({
  email: 'jane@acme.com', // Primary identifier
  traits: { name: 'Jane' }
})

External User ID

Your application’s internal user ID (from Supabase, Auth0, Firebase, etc.):
outlit.identify({
  userId: 'usr_12345', // Your auth system's ID
  email: 'jane@acme.com',
  traits: { authProvider: 'auth0' }
})
Always send both email and userId when available. This creates the strongest identity link.

Anonymous Visitor ID

Automatically generated for browser visitors:
// Generated and stored automatically
const visitorId = outlit.getVisitorId()
// "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
This ID:
  • Is stored in localStorage and cookies
  • Persists across sessions (same browser)
  • Gets linked to CustomerContact after identify

Profile Merging

When Outlit detects the same person with different identifiers, profiles are merged:

Merge Triggers

User visits on phone (visitorId: A), then laptop (visitorId: B), identifies with same email on both.Result: Both visitor histories merge into one CustomerContact.
User identifies as jane@old-company.com, later updates to jane@new-company.com while logged into same account (userId).Result: New email added to contact identifiers, profiles linked.
User signs up with email, later links Google OAuth which has different email.Result: Both emails link to same contact via shared userId.

Merge Rules

When merging two contacts:
DataRule
Events/ActivitiesCombined into unified timeline
TraitsNewer values overwrite older
IdentifiersAll identifiers preserved
Anonymous historyAll visitor events included

Browser vs Server Identity

Anonymous visitors are supported
  • visitorId auto-generated
  • Events stored until identification
  • Later linked via identify() or setUser()
// Works without identity
outlit.track('page_viewed', { page: '/pricing' })

// Later, when they sign up
outlit.identify({ email: 'user@example.com' })

// Or for SPAs, use setUser after authentication
outlit.setUser({ 
  email: 'user@example.com',
  userId: 'usr_123'
})

Best Practices

1. Identify Early

Call identify() as soon as you have user information:
// After login
onLogin(user) {
  outlit.identify({
    email: user.email,
    userId: user.id,
    traits: { plan: user.plan }
  })
}

// After form submission
onFormSubmit(data) {
  outlit.identify({
    email: data.email,
    traits: { source: 'contact_form' }
  })
}

2. Always Send Both Identifiers

When you have both email and userId, send both:
// Good - creates strong identity link
outlit.identify({
  email: user.email,
  userId: user.id,
  traits: { ... }
})

// Less good - single identifier
outlit.identify({
  email: user.email,
  traits: { ... }
})

3. Update Traits on Changes

Re-identify when user data changes:
// User upgraded their plan
onPlanChange(user, newPlan) {
  outlit.identify({
    email: user.email,
    traits: { plan: newPlan, upgradedAt: new Date().toISOString() }
  })
}

4. Handle Multiple Emails

If users can have multiple emails, use a primary:
outlit.identify({
  email: user.primaryEmail, // The one they log in with
  traits: {
    secondaryEmails: user.otherEmails // For reference
  }
})

Debugging Identity Issues

Check Current Visitor ID

// Browser
console.log('Visitor ID:', outlit.getVisitorId())

Verify Identify Calls

Check the Network tab for /api/i/v1/ requests:
{
  "visitorId": "abc-123",
  "events": [{
    "type": "identify",
    "email": "jane@acme.com",
    "userId": "usr_456"
  }]
}

Common Issues

  • Ensure identify() is called after the user authenticates
  • Check that email/userId matches what you expect
  • Verify the domain is in your allowlist
  • Same person using different emails
  • Missing userId that would link them
  • Contact support for manual merge
  • identify() must be called from the same browser/device
  • Check visitorId is consistent (not cleared)
  • Background job processes links periodically (up to 5 min delay)

Next Steps