Match to Client
3# Match to Client Task
Overview¶
The Match to Client Task searches your CRM for existing contacts or creates new ones automatically. It's essential for preventing duplicates and ensuring all workflow data connects to the correct contact record.
When to use this task:
- Connect form submissions to existing contacts
- Find contacts from incoming emails or webhooks
- Create new contacts when no match found
- Deduplicate contact data automatically
- Link external system data to CRM contacts
- Merge lead data with existing customer records
Key Features:
- Multiple matching strategies (email, phone, name, custom fields)
- Fuzzy matching for names and data variations
- Automatic contact creation if no match found
- Update existing contacts with new data
- Custom field matching
- Confidence scoring
[SCREENSHOT NEEDED: Match to Client task configuration panel showing matching criteria options]
Quick Start¶
- Add Match to Client task to workflow
- Select matching field (usually email or phone)
- Enter value to search for:
{{task_12345_email}} - Choose action: "Create if not found" or "Fail if not found"
- Map additional fields for contact creation
- Save and test
Simple Example:
Match By: Email
Search Value: {{task_55123_email}}
Action: Create contact if not found
First Name: {{task_55123_first_name}}
Last Name: {{task_55123_last_name}}
Matching Strategies¶
Match by Email (Most Common)¶
Best for: - Form submissions - Email triggers - API integrations - Most reliable matching method
Configuration:
Match Logic: - Exact match only (case-insensitive) - Searches all contact email fields - Returns first match if multiple found
Match by Phone Number¶
Best for: - Call tracking integrations - SMS triggers - WhatsApp integrations
Configuration:
Match By: Phone Number
Search Value: {{task_12345_phone}}
Phone Format: International (+27123456789)
Match Logic: - Removes formatting (spaces, dashes, parentheses) - Handles country codes intelligently - Fuzzy matching for similar numbers
Examples that match:
Match by Name¶
Best for: - Data imports - When email/phone unavailable - Legacy system integrations
Configuration:
Match By: Full Name
First Name: {{task_12345_first_name}}
Last Name: {{task_12345_last_name}}
Fuzzy Match: Enabled
Match Logic: - Combines first + last name - Handles variations (Bob vs Robert) - Case-insensitive - Ignores extra spaces
Fuzzy matching examples:
Match by Custom Field¶
Best for: - External system IDs - Membership numbers - Unique identifiers
Configuration:
Use cases: - Sync with external CRM - Connect to accounting systems - Match by customer number
Multiple Criteria Matching¶
Best for: - High accuracy requirements - Preventing false matches - Complex data sources
Configuration:
Match By: Multiple Fields
Criteria 1: Email = {{task_12345_email}}
AND
Criteria 2: Phone = {{task_12345_phone}}
Match Logic: - ALL criteria must match - Most accurate method - Lower match rate (more likely to create new)
Date Registered Filtering with Time Range¶
Best for: - UTM parameter tracking - Event correlation - Webhook timing matching - Form submission tracking
Problem: Sometimes you receive data from external sources (webhooks, APIs) with timing information, but the actual client creation happens separately. You need to match based on "which clients were created around the same time" rather than exact field matches.
Solution: Use date registered filtering with an optional time range (in minutes) to match clients created or matched within a specific time window around a reference timestamp.
Configuration:
Sequential Matching (tries each criterion in order):
1. Key: 📅 Date Registered
Value: 2024-01-15 14:30:00
±Minutes: 10
2. Key: 📅 Date Registered
Value: 2024-01-15 14:30:00
±Minutes: 30
3. Key: Email
Value: {{task_12345_email}}
How It Works: Date Registered works as a sequential matching criterion - just like Email or Phone. The system tries each criterion in the order you've added them, stopping at the first match.
Example Flow: 1. Try to match client created within ±10 minutes of timestamp → Found? Stop 2. If no match, try within ±30 minutes → Found? Stop 3. If still no match, try by email → Found? Stop 4. If no match found, proceed to "Create if not found" (if enabled)
Time Range Format: - Enter a positive number representing minutes - Examples: 10 = ±10 minutes, 120 = ±2 hours (120 minutes), 1440 = ±1 day (1440 minutes) - Leave empty for exact timestamp matching (no range)
Examples: - Date: 2024-01-15 14:30:00, Range: 10 → Match within ±10 minutes - Date: {{task_12345_submitted_at}}, Range: 120 → Match within ±2 hours - Date: 2024-03-20 09:00:00, Range: `` (empty) → Exact match only
How It Works: - Works like any other matching criterion (Email, Phone, etc.) - Tries each criterion sequentially until one matches - If ±Minutes provided, creates a bidirectional time window - Searches for ANY client whose date_registered falls within the time window - Returns the most recently created client in that window - Example: Date 2024-01-15 14:30:00 + Range 10 → matches clients created between 14:20:00 and 14:40:00
Important: - Date/Time field can use workflow variables like {{task_1_created_at}} - ±Minutes is optional - leave empty if you don't need time window matching - Multiple date_registered entries allowed for progressive fallback (try ±10min, then ±30min, etc.) - Can be used alone (as the only criterion) or mixed with other criteria (Email, Phone, etc.) - All criteria are tried in order - first match wins
Use Case Example 1: Progressive Fallback with Multiple Time Ranges
Problem: You receive a webhook notification at a specific time, but you're not sure how closely the timing aligns. You want to try narrow ranges first, then widen if needed.
Solution:
Workflow - External System Webhook:
Trigger: Webhook In
Task 1: Match to Client (progressive time ranges)
Matching Criteria (in order):
1. Key: 📅 Date Registered
Value: {{webhook_timestamp}}
±Minutes: 5
2. Key: 📅 Date Registered
Value: {{webhook_timestamp}}
±Minutes: 15
3. Key: 📅 Date Registered
Value: {{webhook_timestamp}}
±Minutes: 60
Result: Tries ±5min first, then ±15min, then ±60min - stops at first match
Output: task_100_contact_id = 12345
Output: task_100_criteria = "Date Registered (±5 minutes)" (or whichever matched)
Use Case Example 2: Google Ads UTM Tracking
Problem: 1. Google Ads sends webhook with UTM parameters at 14:30:00 2. User submits contact form at 14:31:00 (separate event) 3. Need to link the UTM data to the newly created contact
Solution:
Workflow 1 - Form Submission:
Trigger: Form Submit
Task 1: Match to Client
Matching Criteria:
1. Email: {{webhook_email}}
Create if not found: Yes
Output: task_100_contact_id = 12345
Output: task_100_contact_created = true
Workflow 2 - UTM Webhook:
Trigger: Webhook In (receives UTM data)
Task 1: Match to Client
Matching Criteria (tries in order):
1. Key: 📅 Date Registered
Value: {{webhook_received_at}}
±Minutes: 10
2. Key: Email
Value: {{webhook_email}}
Result: First tries time-based match (±10min), falls back to email if needed
Output: task_200_contact_id = 12345 (MATCHED!)
Output: task_200_criteria = "Date Registered (±10 minutes)"
Task 2: Update Client Custom Fields
- Client ID: {{task_200_contact_id}}
- utm_source: {{webhook_utm_source}}
- utm_campaign: {{webhook_utm_campaign}}
Output Fields:
| Field | Description | Example Value |
|---|---|---|
task_[ID]_criteria | Which criterion matched | "Date Registered (±10 minutes)" or "user_email" |
task_[ID]_date_filter_applied | Whether date matching was used | true |
task_[ID]_date_filter_minutes | The ±Minutes range that matched | 10 |
task_[ID]_match_client_id | The matched client ID | 12345 |
Example:
Sequential Matching:
1. Date Registered: {{webhook_time}}, ±10min → No match
2. Date Registered: {{webhook_time}}, ±30min | Successfully matched!
Output:
task_100_criteria: "Date Registered (±30 minutes)"
task_100_date_filter_applied: true
task_100_date_filter_minutes: 30
task_100_match_client_id: 12345
Validation: - Date/Time must be in format: YYYY-MM-DD HH:MM:SS - ±Minutes (if provided) must be a positive number - Invalid formats will be rejected with clear error messages - Variables like {{task_1_timestamp}} are supported
Contact Creation¶
When No Match Found¶
Options:
- Create New Contact - Automatically create if no match (default)
- Fail Workflow - Stop workflow if no match
- Continue with Empty - Proceed without contact
Best practice: Use "Create New Contact" for most workflows to prevent data loss.
Field Mapping¶
Map incoming data to contact fields:
Standard Fields:
First Name: {{task_12345_first_name}}
Last Name: {{task_12345_last_name}}
Email: {{task_12345_email}}
Phone: {{task_12345_phone}}
Company: {{task_12345_company}}
Custom Fields:
custom_source: {{task_12345_utm_source}}
custom_lead_score: 50
custom_signup_date: {{task_12345_date}}
Tags:
Update Existing Contacts¶
When a match is found, decide what to update:
Update Strategy Options:
- Never Update - Use existing data only
- Update Empty Fields - Only fill in missing data
- Always Update - Overwrite with new data
- Merge Data - Intelligent combination
Example Configuration:
If Match Found:
- First Name: Keep Existing
- Phone: Update if Empty
- Tags: Merge (add new, keep old)
- Custom Fields: Always Update
[SCREENSHOT NEEDED: Field mapping interface showing update strategy options for each field]
Output Fields¶
| Field | Description | Example Value |
|---|---|---|
task_[ID]_contact_id | Contact ID (matched or created) | 12345 |
task_[ID]_contact_found | Whether existing contact matched | true / false |
task_[ID]_contact_created | Whether new contact created | true / false |
task_[ID]_first_name | Contact first name | John |
task_[ID]_last_name | Contact last name | Smith |
task_[ID]_email | Contact email | john@example.com |
task_[ID]_phone | Contact phone | +27123456789 |
task_[ID]_company | Company name | ABC Corp |
task_[ID]_full_name | Combined name | John Smith |
task_[ID]_tags | Contact tags | Lead, Website, 2024 |
task_[ID]_match_confidence | Match accuracy score | 0.95 (0-1) |
task_[ID]_match_method | How match was found | email, phone, name |
task_[ID]_date_filter_applied | Whether timestamp filtering was used | true / false |
task_[ID]_date_filter_start | Start of time window (if timestamp used) | 2024-01-15 14:20:00 |
task_[ID]_date_filter_end | End of time window (if timestamp used) | 2024-01-15 14:40:00 |
Custom Fields:
Usage in subsequent tasks:
Send email to: {{task_15123_email}}
Update contact: {{task_15123_contact_id}}
Check if new: {{task_15123_contact_created}}
Real-World Examples¶
Example 1: Form Submission to CRM¶
Workflow: 1. Website Form - Website contact form 2. Match to Client - Find existing contact 3. Email - Send confirmation to contact 4. Email - Notify sales team
Match Configuration:
Match By: Email
Search Value: {{task_55001_email}}
If Not Found: Create Contact
Field Mapping:
- First Name: {{task_55001_first_name}}
- Last Name: {{task_55001_last_name}}
- Email: {{task_55001_email}}
- Phone: {{task_55001_phone}}
- Tags: Website Lead, Contact Form
- custom_source: Website
- custom_form_message: {{task_55001_message}}
Result: - Existing customer? Updates with new inquiry - New lead? Creates contact with all details - Email sends to correct address: {{task_15001_email}}
Example 2: Call Tracking Integration¶
Workflow: 1. Call Connect Trigger - Incoming call 2. Match to Client - Find by phone number 3. If Task - Check if contact found - Found: Edit Client - Log call - Not Found: Create alert for unknown caller
Match Configuration:
Match By: Phone Number
Search Value: {{task_50001_caller_number}}
Phone Format: International
If Not Found: Fail (don't create)
Why fail? We only want to log calls for known customers.
Conditional Logic:
If {{task_15001_contact_found}} = true:
→ Edit Client: Add call note
→ Update: custom_last_call_date
Else:
→ Email: Alert team of unknown caller
→ Include: {{task_50001_caller_number}}
Example 3: Email Lead Integration¶
Workflow: 1. Leads Mail Trigger - Facebook lead email 2. Match to Client - Find existing contact by email 3. Edit Client - Add Facebook tag 4. If Task - Check if new contact - New: Start welcome sequence - Existing: Send different follow-up
Match Configuration:
Match By: Email
Search Value: {{task_52001_email}}
If Not Found: Create Contact
Update Strategy:
- First Name: Update if Empty
- Phone: Update if Empty
- Tags: Merge (add "Facebook Lead 2024")
- custom_lead_source: Always Update → "Facebook"
Why this matters: - Existing customer who downloaded Facebook offer? Don't send "new lead" sequence - New lead? Full onboarding series - Always update source to track latest touchpoint
Example 4: External System Sync¶
Workflow: 1. Schedule Trigger - Every hour 2. MySQL Query - Fetch updated customers from external DB 3. Loop - Process each customer 4. Match to Client - Find by external ID 5. Edit Client - Update with latest data
Match Configuration:
Match By: Custom Field
Field Name: external_customer_id
Search Value: {{task_29001_customer_id}}
If Not Found: Create Contact
Field Mapping:
- Email: {{task_29001_email}}
- Phone: {{task_29001_phone}}
- custom_external_customer_id: {{task_29001_customer_id}}
- custom_last_sync: {{task_48001_current_time}}
Prevents duplicates: - Matches by external ID, not email (email may change) - Creates new contact with external ID if first sync - Subsequent syncs update existing contact
Example 5: Duplicate Prevention¶
Workflow: 1. Webhook In - API integration 2. Match to Client - Primary match by email 3. If Task - Check if match found - Not found: Match to Client - Secondary match by phone 4. If Task - Check second match - Not found: Match to Client - Tertiary match by name + company
Multi-Level Matching:
First Match Attempt:
Second Match Attempt (if first failed):
Third Match Attempt (if both failed):
Match By: Multiple Fields
First Name: {{task_46001_first_name}}
Last Name: {{task_46001_last_name}}
Company: {{task_46001_company}}
If Not Found: Create Contact (last resort)
Result: - Maximum duplicate prevention - Creates contact only if truly new - Handles incomplete data gracefully
Advanced Matching Techniques¶
Fuzzy Matching Configuration¶
Strictness Levels:
| Level | Tolerance | Use Case |
|---|---|---|
| Exact | 0% variation | Email, ID numbers |
| High | 5% variation | Phone numbers |
| Medium | 15% variation | Names with typos |
| Low | 30% variation | Company names |
Configuration:
Examples with Medium strictness:
"John Smith" matches:
✓ Jon Smith (typo)
✓ John Smyth (spelling)
✓ J Smith (abbreviation)
✗ Jane Smith (different first name)
Match Confidence Scoring¶
View how confident the match is:
Score ranges: - 1.0 = Perfect match (exact email) - 0.8-0.99 = High confidence (fuzzy name match) - 0.5-0.79 = Medium confidence (multiple similar) - 0-0.49 = Low confidence (weak match)
Use confidence in workflows:
If {{task_15001_match_confidence}} < 0.7:
→ Manual review required
→ Email admin for verification
Else:
→ Auto-process confidently
Handling Multiple Matches¶
When multiple contacts match criteria:
Strategy Options: 1. Return First - Use oldest contact (default) 2. Return Latest - Use newest contact 3. Highest Score - Use best confidence match 4. Fail - Stop workflow, require manual resolution
Best practice:
Best Practices¶
Choosing Match Fields¶
- Email is best - Unique, rarely changes, high accuracy
- Phone is good - Decent uniqueness, formatting challenges
- Name is risky - Common names create false matches
- Custom IDs ideal - For external system integrations
Update Strategies¶
- Lead data → Update empty - Don't overwrite good data with form entries
- CRM updates → Always update - Trust human-entered data
- Tags → Always merge - Never lose historical tags
- Source → Update if empty - Keep first touch attribution
Duplicate Prevention¶
- Use strongest available match field - Email > Phone > Name
- Enable fuzzy matching for names - Handles typos
- Multi-level matching - Try multiple strategies
- Periodic dedupe workflows - Clean up manually
Performance¶
- Email matching is fastest - Indexed in database
- Custom field matching - Ensure field is indexed
- Name matching is slowest - Fuzzy logic intensive
- Batch operations - Use loops for bulk matching
Troubleshooting¶
Creating Duplicates¶
Cause: Matching on unreliable field
Solution:
✗ Bad: Match by first name only
✓ Good: Match by email
✓ Better: Match by email OR phone
✓ Best: Match by custom external_id
Not Finding Existing Contacts¶
Check:
- Field format - Phone:
+27123456789vs012 345 6789 - Extra spaces - "John Smith" vs "John Smith" (double space)
- Case sensitivity - Email should be case-insensitive (verify config)
- Fuzzy matching disabled - Enable for name matching
Debug:
View execution history:
- Check search value: {{task_15001_search_value}}
- View match method: {{task_15001_match_method}}
- Check confidence: {{task_15001_match_confidence}}
Wrong Contact Matched¶
Common causes:
- Multiple contacts with same email - Dedupe your CRM
- Fuzzy match too loose - Tighten strictness
- Common name - Add additional criteria
- Data quality issues - Clean contact database
Prevention:
Match Confidence Low¶
Improve confidence:
- Use exact match fields - Email, phone, ID
- Tighten fuzzy settings - Increase strictness
- Add more criteria - Multiple field matching
- Clean source data - Remove typos, standardize
Frequently Asked Questions¶
Should I always create contacts if not found?¶
Depends on use case: - Form submissions: Yes - Never lose a lead - Call tracking: Maybe - Only for inbound? - Internal workflows: No - Should already exist - API integrations: Yes - Sync all data
Can I match on multiple emails?¶
Yes, if contact has multiple email addresses, any will match:
What if I want to update existing but not create new?¶
If Not Found: Fail Workflow
Then add If Task:
If {{task_15001_contact_found}} = false:
→ Stop workflow
→ Log for manual review
How do I prevent overwriting good data?¶
Update Strategy:
- First Name: Keep Existing (don't overwrite)
- Phone: Update if Empty (fill gaps only)
- Email: Keep Existing (critical field)
- Tags: Merge (combine old + new)
Can I create contacts in workflow without this task?¶
Yes, use "New Client" task, but: - ✗ Always creates new (duplicates likely) - ✓ Match to Client checks first (safer)
Best practice: Use Match to Client for external data sources.
What's the difference between Match and Get Contact?¶
Match to Client: - Searches by any field - Creates if not found - Best for unknown contacts
Get Contact: - Retrieves by known contact ID - Fails if ID invalid - Best when you already have ID
How do I match by contact ID?¶
If you already have the ID, use Get Contact instead.
Related Tasks¶
- Get Contact - Retrieve contact by ID
- New Client - Create contact without searching
- Edit Client - Update contact fields
- If Task - Conditional logic based on match results
- Loop Task - Batch contact matching