Identity Resolution Guide
Identity Resolution Guide
A comprehensive guide to understanding and using identity resolution when integrating with our contact management platform.
Overview
Identity resolution is the process of matching incoming contact data against your existing contacts. It determines whether to create a new contact or update an existing one based on identifiers or IDs like email addresses, phone numbers, customer IDs, and other unique identifiers or IDs
Why Identity Resolution Matters
When integrating with our platform, you'll encounter situations where:
- The same person interacts through multiple channels (email, phone, web, app)
- Users provide different identifiers at different times (email first, phone later)
- External systems have different IDs for the same person
- You need to progressively build a complete customer profile over time
Without proper identity resolution, you end up with:
- ❌ Duplicate contact records for the same person
- ❌ Fragmented customer profiles across systems
- ❌ Incomplete view of customer interactions
- ❌ Poor user experience (multiple accounts, repeated onboarding)
With identity resolution, you achieve:
- ✅ Single, unified contact record per person
- ✅ Progressive enrichment as you learn more about each contact
- ✅ Accurate customer analytics and reporting
- ✅ Seamless experience across all touchpoints
Core Concepts
What is a Contact?
A contact represents a unique person profile in your workspace. Each contact:
- Has a unique system generated ID i.e. Contact ID
- Belongs to a workspace only
- Contains attributes (name, address, custom fields)
- Has events based on a timeline (opened email, viewed page)
- Has associated objects (companies, custom objects)
- Is associated with one or more identifiers e.g. email, phone number or external customer ID
What is an Identifier?
An identifier is a key-value pair that uniquely identifies a contact:
Codevoorbeeld
{
"key": "emailaddress",
"value": "jane@example.com"
}
Common identifier types:
- emailaddress: Email addresses
- phonenumber: Phone numbers
- customer_id: Your external system's customer ID
- user_id: Application user ID
- account_id: Account number
- Custom keys specific to your business
Key principle: Each identifier value can only belong to ONE contact at a time. This ensures uniqueness across your contact database.
Resolution vs Aliasing
When sending contact data to our platform, you work with two types of identifiers:
1. Resolution Identifiers
Purpose: Update existing or create a contact
These identifiers participate in your chosen identity resolution strategy and determine which contact record to work with.
Codevoorbeeld
{
"identifiers": [
{"key": "customer_id", "value": "CUST_12345"}
]
}
2. Alias Identifiers
Purpose: Add supplementary identifiers to an already-found contact
These are added on a best-effort basis after the contact is found. If an alias is already taken by another contact, it's simply skipped (not an error).
Codevoorbeeld
{
"aliasIdentifiers": [
{"key": "emailaddress", "value": "customer@example.com"},
{"key": "phonenumber", "value": "+12345678900"}
]
}
Identity Resolution Strategies
Choose the strategy that matches your data quality and business requirements.
Strategy 1: Strict Resolution
When to use:
- ✅ You have high-quality data with strong guarantees
- ✅ You want to catch data inconsistencies immediately
- ✅ You need strict control over identifier associations
- ✅ Data errors should be surfaced, not hidden
Behavior: All provided identifiers must match a single contact. If they match different contacts, the operation fails with an error.
Example scenario:
Imagine you're integrating a CRM system where each customer has both an email and phone number that should always be together:
Existing data in Bird:
Contact A: email = alice@company.com
Contact B: phone = +11234567890
Your integration sends the following to Bird:
Codevoorbeeld
{
"strategy": "strict",
"identifiers": [
{"key": "emailaddress", "value": "alice@company.com"},
{"key": "phonenumber", "value": "+11234567890"}
],
"attributes": {
"firstName": "Alice",
"company": "Acme Corp"
}
}
Result: ❌ ERROR - identifiers match different contacts
Action needed: Investigate why email and phone are on separate contacts in Bird
Use cases:
- Financial systems with strict data integrity requirements
- Healthcare systems requiring accurate patient matching
- Compliance-sensitive operations
- Data quality validation and auditing
Strategy 2: First Alias Resolution
When to use:
- ✅ You collect identifiers progressively over time
- ✅ You want flexibility in adding new identifiers
- ✅ You're okay with identifiers staying separate if they conflict
- ✅ You prefer successful operations over strict validation
Behavior: Uses the first available identifier to find the contact, then tries to add remaining identifiers. If an identifier is already on another contact, it's skipped (not an error).
Example scenario:
Your e-commerce site collects customer data across multiple sessions:
Session 1: User provides email during newsletter signup
Codevoorbeeld
{
"strategy": "first_alias",
"identifiers": [
{"key": "emailaddress", "value": "shopper@email.com"}
],
"attributes": {
"source": "newsletter_signup",
"interests": ["electronics"]
}
}
Bird creates Contact A with email
Session 2: Same user makes purchase, provides phone
Codevoorbeeld
{
"strategy": "first_alias",
"identifiers": [
{"key": "emailaddress", "value": "shopper@email.com"},
{"key": "phonenumber", "value": "+19876543210"}
],
"attributes": {
"lastPurchase": "2025-10-22",
"totalSpent": 299.99
}
}
Bird finds Contact A via email, adds phone number
Contact A now has both email and phone
Session 3: User provides loyalty card at physical store
Codevoorbeeld
{
"strategy": "first_alias",
"identifiers": [
{"key": "emailaddress", "value": "shopper@email.com"},
{"key": "loyalty_card", "value": "LOYAL_789456"}
],
"attributes": {
"inStoreVisit": true,
"preferredStore": "Downtown Location"
}
}
Bird finds Contact A via email, adds loyalty card
Contact is progressively enriched across touchpoints
Use cases:
- Multi-channel customer engagement platforms
- Progressive web app user tracking
- SaaS applications with gradual user onboarding
- Marketing automation platforms
Strategy 3: First Resolution
When to use:
- ✅ You only need to find the contact, not add identifiers
- ✅ You're updating attributes without changing identifiers
- ✅ You want minimal impact on existing identifier associations
- ✅ Read-mostly operations
Behavior: Uses the first available identifier to find the contact. Additional identifiers in the request are ignored.
Example scenario:
Your analytics system updates contact attributes based on user behavior:
You track user activity and want to update their profile
Codevoorbeeld
{
"strategy": "first",
"identifiers": [
{"key": "user_id", "value": "USER_12345"},
{"key": "session_id", "value": "sess_abc123"} // Ignored
],
"attributes": {
"lastActive": "2025-10-22T14:30:00Z",
"pageViews": 47,
"featureUsage": {
"dashboard": 15,
"reports": 8,
"settings": 2
}
}
}
Bird finds contact by user_id
Bird Updates attributes only
session_id is NOT added to the contact
Use cases:
- Activity tracking and analytics
- Attribute-only updates
- Event processing systems
- Webhook handlers that shouldn't modify identifiers
Alias Identifiers
The Challenge
Imagine this scenario:
- You're integrating an external CRM system
- Customers provide different identifiers through different touchpoints
- Sometimes an email or phone is already associated with another contact
- You don't want the entire operation to fail because of one conflict
The Solution: Alias Identifiers
Alias identifiers let you add supplementary identifiers on a best-effort basis, independent of your resolution strategy.
Key benefits:
- Best-effort addition: Skipped if already taken, not an error
- Explicit reporting: Know exactly which were added vs. skipped
- Strategy-independent: Same behavior regardless of resolution strategy
- Operation success: Conflicts don't fail the entire request
How It Works
Codevoorbeeld
{
"strategy": "first",
"identifiers": [
{"key": "customer_id", "value": "CUST_12345"}
],
"aliasIdentifiers": [
{"key": "emailaddress", "value": "customer@email.com"},
{"key": "phonenumber", "value": "+15551234567"},
{"key": "linkedin_profile", "value": "linkedin.com/in/customer"}
],
"attributes": {
"firstName": "Maria",
"lastName": "Garcia"
}
}
What happens:
- Bird finds or creates contact using customer_id
- For each alias identifier:
- ✅ If available → Added to the contact
- ✅ If already on this contact → Idempotent success
- ⚠️ If on another contact → Skipped, reported in response
Response:
Codevoorbeeld
{
"contact": {
"id": "contact-uuid-123",
"workspaceId": "workspace-uuid",
"attributes": {
"firstName": "Maria",
"lastName": "Garcia"
}
},
"created": false,
"addedAliases": [
{"key": "emailaddress", "value": "customer@email.com"},
{"key": "linkedin_profile", "value": "linkedin.com/in/customer"}
],
"skippedAliases": [
{"key": "phonenumber", "value": "+15551234567"}
]
}
In this example, the phone number was skipped because it's already associated with a different contact. Your application can then decide whether to
- Log it for manual review
- Update your source system
- Simply accept it (phone genuinely belongs to someone else)
Common Use Cases
Use Case 1: Anonymous to Known User Journey
Scenario: Track anonymous website visitors, then link them to authenticated users.
Challenge: You don't know if the email they provide is already in your system.
Solution:
Step 1: Anonymous visitor browses your site
Codevoorbeeld
{
"strategy": "first_alias",
"identifiers": [
{"key": "anonymous_id", "value": "anon_xyz789"}
],
"attributes": {
"source": "organic_search",
"visitedPages": ["/products", "/pricing", "/features"],
"firstSeen": "2025-10-22T10:00:00Z"
}
}
Creates a new contact with anonymous ID
Step 2: Visitor signs up with email
Codevoorbeeld
{
"strategy": "first_alias",
"identifiers": [
{"key": "anonymous_id", "value": "anon_xyz789"}
],
"aliasIdentifiers": [
{"key": "emailaddress", "value": "newcustomer@email.com"}
],
"attributes": {
"signupDate": "2025-10-22T10:15:00Z",
"accountType": "trial"
}
}
Bird finds contact by anonymous_id
Tries to add email:
- If email is new → Added successfully
- If email exists → Skipped
Benefits:
- No data loss if email already exists
- Complete visitor journey preserved
Use Case 2: Multi-Channel Customer Support
Scenario: Customers contact you via phone, email, chat, and social media.
Challenge: Same customer uses different channels, you need unified view.
Solution:
WhatsApp interaction
Codevoorbeeld
{
"strategy": "first",
"identifiers": [
{"key": "customer_id", "value": "CUST_98765"}
],
"aliasIdentifiers": [
{"key": "phonenumber", "value": "+15559876543"}
],
"attributes": {
"lastContactChannel": "phone",
"lastContactDate": "2025-10-22T09:00:00Z",
"supportTickets": ["TICKET_001"],
"satisfaction": "satisfied"
}
}
Email sign up follow-up
Codevoorbeeld
{
"strategy": "first",
"identifiers": [
{"key": "customer_id", "value": "CUST_98765"}
],
"aliasIdentifiers": [
{"key": "emailaddress", "value": "customer@company.com"}
],
"attributes": {
"lastContactChannel": "email",
"lastContactDate": "2025-10-22T14:00:00Z",
"supportTickets": ["TICKET_001", "TICKET_002"]
}
}
Live chat session
Codevoorbeeld
{
"strategy": "first",
"identifiers": [
{"key": "customer_id", "value": "CUST_98765"}
],
"aliasIdentifiers": [
{"key": "chat_handle", "value": "maria_g"}
],
"attributes": {
"lastContactChannel": "chat",
"lastContactDate": "2025-10-22T16:30:00Z",
"chatTranscript": "transcript_link"
}
}
Benefits:
- Single contact record with all channels
- Complete interaction history
- Support agents see full context
Use Case 3: Third-Party Integration
Scenario: Sync data from external systems (CRM, payment processor, marketing tools).
Challenge: External systems have their own IDs, conflicts can occur.
Solution:
Salesforce integration example:
Codevoorbeeld
{
"strategy": "first_alias",
"identifiers": [
{"key": "salesforce_id", "value": "SF_00Q123456"}
],
"aliasIdentifiers": [
{"key": "emailaddress", "value": "enterprise@client.com"},
{"key": "phonenumber", "value": "+15551234567"},
{"key": "company_id", "value": "COMP_789"}
],
"attributes": {
"source": "salesforce",
"accountValue": 50000,
"industry": "Technology",
"employees": 150,
"lastSyncedAt": "2025-10-22T12:00:00Z"
}
}
Check the response:
Codevoorbeeld
{
"addedAliases": [
{"key": "emailaddress", "value": "enterprise@client.com"},
{"key": "company_id", "value": "COMP_789"}
],
"skippedAliases": [
{"key": "phonenumber", "value": "+15551234567"}
]
}
Handle conflicts:
- Skipped phone means it's on another contact
- Investigate if it's a duplicate that should be merged on your external system and synced again
- Or accept it (legitimately different contact)
- Log for your integration monitoring
Use Case 4: E-commerce Customer Journey
Scenario: Complete customer lifecycle from browsing to purchase to loyalty.
Solution:
Browse: Visitor adds items to cart
Codevoorbeeld
{
"strategy": "first",
"identifiers": [
{"key": "device_id", "value": "device_abc123"}
],
"attributes": {
"cartItems": ["product_1", "product_2"],
"cartValue": 89.99,
"browsingCategory": "electronics"
}
}
Checkout: Provides email
Codevoorbeeld
{
"strategy": "first",
"identifiers": [
{"key": "device_id", "value": "device_abc123"}
],
"aliasIdentifiers": [
{"key": "emailaddress", "value": "shopper@email.com"}
],
"attributes": {
"checkoutStarted": "2025-10-22T10:30:00Z"
}
}
Purchase: Completes order
Codevoorbeeld
{
"strategy": "first",
"identifiers": [
{"key": "emailaddress", "value": "shopper@email.com"}
],
"aliasIdentifiers": [
{"key": "order_id", "value": "ORDER_2025_10_001"}
],
"attributes": {
"orderCompleted": "2025-10-22T10:45:00Z",
"orderValue": 89.99,
"paymentMethod": "credit_card",
"shippingAddress": "123 Main St..."
}
}
Loyalty: Joins rewards program
Codevoorbeeld
{
"strategy": "first",
"identifiers": [
{"key": "emailaddress", "value": "shopper@email.com"}
],
"aliasIdentifiers": [
{"key": "loyalty_id", "value": "LOYAL_12345"}
],
"attributes": {
"loyaltyMember": true,
"rewardsPoints": 89,
"memberSince": "2025-10-22"
}
}
Benefits:
- Complete customer journey in one profile
- Marketing can see browsing → purchase conversion
- Customer service sees order and loyalty status
- Analytics show full funnel
Use Case 5: Mobile App + Web Platform
Scenario: Users interact with both your web app and mobile app.
Solution:
Mobile app installation
Codevoorbeeld
{
"strategy": "first_alias",
"identifiers": [
{"key": "mobile_device_id", "value": "ios_device_xyz"}
],
"attributes": {
"platform": "iOS",
"appVersion": "2.3.1",
"installDate": "2025-10-20",
"pushToken": "push_token_abc..."
}
}
User logs in on mobile
Codevoorbeeld
{
"strategy": "first_alias",
"identifiers": [
{"key": "mobile_device_id", "value": "ios_device_xyz"}
],
"aliasIdentifiers": [
{"key": "user_id", "value": "USER_456"},
{"key": "emailaddress", "value": "user@email.com"}
],
"attributes": {
"lastLoginMobile": "2025-10-22T08:00:00Z",
"authenticated": true
}
}
User accesses web platform
Codevoorbeeld
{
"strategy": "first_alias",
"identifiers": [
{"key": "user_id", "value": "USER_456"}
],
"aliasIdentifiers": [
{"key": "web_session_id", "value": "web_sess_123"}
],
"attributes": {
"lastLoginWeb": "2025-10-22T09:00:00Z",
"browser": "Chrome",
"os": "macOS"
}
}
Benefits:
- Cross-platform user tracking
- Can send push notifications using mobile device ID and push token
- Can trigger email using email address
- Unified analytics across platforms
Checking for Conflicts
Always check the skippedAliases field in the response to understand which identifiers couldn't be added:
Response with skipped aliases:
Codevoorbeeld
{
"contact": {
"id": "contact-abc-123"
},
"addedAliases": [
{"key": "emailaddress", "value": "customer@example.com"}
],
"skippedAliases": [
{"key": "phonenumber", "value": "+15551234567"}
]
}
What to do when aliases are skipped:
- Option 1: Log for monitoring and trend analysis
- Option 2: Create a manual review task for your data quality team
- Option 3: Investigate if the contacts should be merged in your external system
- Option 4: Accept it if the identifier legitimately belongs to another person
Best Practices
1. Choose the Right Strategy for Your Use Case
| Use Case | Recommended Strategy | Why |
|---|---|---|
| Financial/Healthcare data | strict | Data integrity is critical |
| E-commerce customer tracking | first_alias | Progressive identifier collection |
| Analytics/Event tracking | first | Only updating attributes |
| Multi-channel engagement | first_alias | Flexible identifier management |
| High-quality CRM sync | strict | Catch inconsistencies early |
2. Prioritize Your Identifiers Wisely
The order of identifiers matters for strategies that check priority (first_alias, first).
Good prioritization:
Codevoorbeeld
{
"identifiers": [
{"key": "customer_id", "value": "CUST_123"}, // Most reliable
{"key": "emailaddress", "value": "user@email.com"}, // Very reliable
{"key": "session_id", "value": "sess_xyz"} // Least reliable
]
}
Poor prioritization:
Codevoorbeeld
{
"identifiers": [
{"key": "session_id", "value": "sess_xyz"}, // Least reliable (BAD!)
{"key": "customer_id", "value": "CUST_123"}, // Most reliable
{"key": "emailaddress", "value": "user@email.com"}
]
}
Why it matters: If session_id changes frequently but is checked first, you might create unnecessary duplicate contacts.
3. Use Alias Identifiers for Supplementary Data
Resolution identifiers = Critical for finding the right contact
Alias identifiers = Nice to have, but not critical
Alias identifiers = Nice to have, but not critical
Codevoorbeeld
{
"identifiers": [
// Critical: Must have to identify the contact
{"key": "customer_id", "value": "CUST_123"}
],
"aliasIdentifiers": [
// Supplementary: Try to add, but don't fail if you can't
{"key": "linkedin_profile", "value": "..."},
{"key": "twitter_handle", "value": "..."},
{"key": "secondary_email", "value": "..."}
]
}
4. Monitor Skipped Aliases
Track when aliases are being skipped to identify data quality issues:
Warning signs to watch for:
- High skip rate (>20% of aliases skipped): May indicate duplicate contacts in your system
- Specific identifiers always skipped (e.g., certain emails): Suggests a duplicate contact exists
- Skip patterns by source: Some data sources may consistently have conflicts
Actions to take:
- Review skipped aliases regularly to identify duplicate contacts
- Investigate contacts that frequently have identifier conflicts
- Merge duplicate contacts when appropriate in your external system
5. Validate Data Quality
Ensure identifiers are properly formatted before sending:
Email addresses
- ✅ Valid: user@example.com
- ❌ Invalid: user@ (missing domain), @example.com (missing local part), user @email.com (contains space
Phone numbers (E.164 format):
- ✅ Valid: +15551234567
- ❌ Invalid: 555-1234 (missing country code), 15551234567 (missing + prefix), +1 (555) 123-4567 (contains formatting
General rules:
- All identifiers must have non-empty values
- Trim leading/trailing whitespace
- Normalize case (lowercase for emails)
- Use consistent formatting (E.164 for phones)
6. Design for Idempotency
Your integrations should be safe to retry
This is safe to call multiple times
Codevoorbeeld
{
"identifiers": [
{"key": "customer_id", "value": "CUST_123"}
],
"aliasIdentifiers": [
{"key": "emailaddress", "value": "user@email.com"}
],
"attributes": {
"lastSyncedAt": "2025-10-22T14:30:00Z",
"syncVersion": "v2"
}
}
If called again:
- Same contact is found via customer_id
- Email already present → Reported in addedAliases (not an error)
- Attributes updated with new values
Result: Safe to retry
Troubleshooting Guide
Problem: "Multiple contacts found" Error
Symptom:
Codevoorbeeld
{
"error": "multiple_contacts_found",
"message": "The provided identifiers match multiple contacts"
}
Cause: Using strict strategy with identifiers that exist on different contacts
Solution:
Option 1: Switch to first_alias strategy if appropriate for your use case.
Option 2: Use only one identifier to resolve, move others to aliases:
Before (causes error)
Codevoorbeeld
{
"strategy": "strict",
"identifiers": [
{"key": "emailaddress", "value": "user@email.com"}, // On Contact A
{"key": "phonenumber", "value": "+15551234567"} // On Contact B
]
}
After (works)
Codevoorbeeld
{
"strategy": "first_alias",
"identifiers": [
{"key": "emailaddress", "value": "user@email.com"} // Find Contact A
],
"aliasIdentifiers": [
{"key": "phonenumber", "value": "+15551234567"} // Try to add
]
}
Option 3: Investigate and merge duplicate contacts in your external system if they represent the same person.
Problem: Aliases Always Being Skipped
Symptom:
Codevoorbeeld
{
"skippedAliases": [
{"key": "emailaddress", "value": "user@email.com"}
]
}
This means the email is already associated with a different contact.
Diagnosis steps:
- Search for the identifier:
GET /v1/contacts/search?emailaddress=user@email.com
This shows you which contact currently has that email.
- Compare contacts:
- Do they represent the same person? → Merge needed
- Do they represent different people? → Accept the skip
- Check your data source:
- Is your source system creating duplicates?
- Do you need data deduplication before sending?
Problem: Creating Duplicate Contacts
Symptom: The same person ends up with multiple contact records.
Cause: Not providing consistent identifiers across API calls.
Example of the problem:
Call 1: Uses email only
Codevoorbeeld
{
"identifiers": [
{"key": "emailaddress", "value": "user@email.com"}
],
"attributes": {
"firstName": "John"
}
}
Result: Creates Contact A
Call 2: Uses phone only (but doesn't include email!)
Codevoorbeeld
{
"identifiers": [
{"key": "phonenumber", "value": "+15551234567"}
],
"attributes": {
"lastName": "Doe"
}
}
Result: Creates Contact B (duplicate!)
Solution: Always include at least one consistent identifier across all your API calls:
Call 1
Codevoorbeeld
{
"identifiers": [
{"key": "user_id", "value": "USER_123"}
],
"aliasIdentifiers": [
{"key": "emailaddress", "value": "user@email.com"}
],
"attributes": {
"firstName": "John"
}
}
Call 2: Same user_id ensures same contact is found
Codevoorbeeld
{
"identifiers": [
{"key": "user_id", "value": "USER_123"}
],
"aliasIdentifiers": [
{"key": "phonenumber", "value": "+15551234567"}
],
"attributes": {
"lastName": "Doe"
}
}
Result: Finds existing Contact A, adds phone number
Problem: Validation Errors
Symptom:
Codevoorbeeld
{
"error": "validation_error",
"message": "Invalid identifier format",
"details": {
"key": "emailaddress",
"value": "not-an-email"
}
}
Common validation issues:
Email addresses:
❌ "user@" → Missing domain
❌ "@example.com" → Missing local part
❌ "user @email.com" → Space in email
✅ "user@email.com" → Valid
Phone numbers:
❌ "555-1234" → Missing country code
❌ "15551234567" → Missing + prefix
❌ "+1 (555) 123-4567" → Formatting characters (use digits only)
✅ "+15551234567" → Valid (E.164 format)
Solution: Normalize identifiers in your source system before sending:
For phone numbers:
- Remove all formatting characters (spaces, dashes, parentheses)
- Ensure it starts with + followed by country code
- US example: (555) 123-4567 → +15551234567
For email addresses:
- Convert to lowercase
- Trim leading/trailing whitespace
- Example: USER@EXAMPLE.COM → user@example.com
Problem: Race Conditions with Identifiers
Symptom: The same alias is sometimes added successfully, sometimes skipped (non-deterministic behavior).
Cause: Multiple systems or processes trying to add the same identifier to different contacts simultaneously.
Solution: This is expected behavior when concurrent operations occur:
- Accept eventual consistency:
- The first operation to complete will claim the identifier
- Subsequent operations will see it as skipped
- Check skippedAliases in the response to handle appropriately
- Review patterns:
- If the same identifier is frequently skipped, investigate for duplicate contacts
- Consider whether the conflicting contacts should be merged
Quick Reference
Strategy Comparison
| Strategy | Priority-based? | Add New Identifiers? | Conflict Behavior | Best For |
|---|---|---|---|---|
| strict | No | Yes | ERROR | High-quality data, validation |
| first_alias | Yes | Yes | Skip | Progressive collection |
| first | Yes | No | N/A | Attribute-only updates |
Identifier Priority Guide
High priority (check first):
- 🥇 Customer ID / User ID from your system
- 🥈 Email address (if verified)
- 🥉 Phone number (if verified)
Low priority (check last):
- Session IDs
- Device IDs
- Temporary identifiers
Alias Identifiers Decision Tree
Do you need explicit reporting of success/failure?
├─ YES → Use aliasIdentifiers
└─ NO
└─ Will conflicts occur frequently?
├─ YES → Use aliasIdentifiers
└─ NO → Use regular identifiers with first_alias strategy
Common Patterns
Pattern 1: Anonymous → Known
Resolution: anonymous_id
Aliases: emailaddress (when user signs up)
Strategy: first_alias
Pattern 2: Multi-Channel
Resolution: customer_id
Aliases: channel-specific identifiers
Strategy: first_alias
Pattern 3: External Sync
Resolution: external_system_id
Aliases: emailaddress, phonenumber, etc.
Strategy: first_alias (or strict for high-quality data)
Pattern 4: Analytics Only
Resolution: user_id
Aliases: None
Strategy: first