Enrollment and data
Behavior Reviewed · not yet fact-checked
In short
How does Reply detect duplicate contacts?
The contact identifier chosen at import — Email, Last Name, or Phone — becomes the distinguishing key that prevents duplicates; rows matching an existing record are updated or skipped, never doubled. LinkedIn URLs are normalized to a canonical form on every ingestion source, so URL variants of one profile do not create duplicates.
At a glance
| Aspect | Detail |
|---|---|
| What it governs | Whether an incoming contact row creates a new record, updates an existing one, or is skipped as a duplicate |
| Trigger | A contact-creating operation: CSV import, API import, integrations, enrichment, CRM sync, or manual editing |
| Inputs | The contact identifier chosen at import (Email, Last Name, or Phone), the matched-records option, the LinkedIn profile URL |
| Result | Matches become updates or skips; import results report Imported, Updated, Skipped, and Import Errors counts |
| Configurable | The identifier field, Update Missing Fields vs. Skip for matched records, enrichment Keep-vs-Override, account import modes |
| Does not | Merge records that differ on the identifier, or normalize LinkedIn company-page URLs — those are stored as-is |
| Plans | Plan-specific differences are not documented for this rule |
Rule summary
During a CSV import you choose the contact identifier in a drop-down menu. When you choose a unique identifier — such as Email, Last Name, or Phone — it becomes the distinguishing key for each contact and prevents duplicates; once chosen, the other fields become optional. Rows that match an existing record are handled per your matched-records option (update or skip) instead of creating a second record. Separately, Reply normalizes every LinkedIn profile URL to one canonical format, so different URL variants of the same profile are recognized as the same person.
Trigger
Any contact-creating operation: a CSV import, a V3 API import, Website Visitors or RB2B events, email-based or LinkedIn URL enrichment, a CRM integration sync, or manual editing of the LinkedIn field in the contact card.
Decision logic
- Match the incoming row against existing contacts using the chosen identifier (Email, Last Name, or Phone).
- On a match, apply the Matched Records option: Update Missing Fields writes new data from the CSV into the existing contact's fields, while Skip leaves the existing record untouched.
- On no match, create a new contact.
- Normalize the LinkedIn profile URL to the canonical form
https://www.linkedin.com/in/usernamewhenever a contact is created or updated. Duplicate detection by LinkedIn URL is format-agnostic: trailing slashes, query parameters,http://vs.https://, and a missingwwware all recognized as the same profile and will not create duplicates.
Import results report the outcome:
| Import status | Meaning |
|---|---|
| Imported | New contacts added to the account |
| Updated | Existing contacts whose profiles were updated |
| Skipped | Duplicates the system removed during the import |
| Import Errors | Rows that failed — missing mandatory fields or incorrect formats (for example, symbols in the Phone field) |
Result
One record per identifier value. Re-importing a list does not double contacts — matching rows update or skip, and the notification after import breaks down exactly what happened. If the reason is unclear, download the full import result file for details.
State changes
| Field | Change |
|---|---|
| Matched contact | Fields updated per Update Missing Fields, or untouched per Skip |
| LinkedIn profile field | Stored in canonical https://www.linkedin.com/in/username form; automatic LinkedIn steps (Connect, Message) save the resolved profile URL back to the contact in the same form |
| Import summary | Imported / Updated / Skipped / Import Errors counts |
Exceptions
- Normalization is best-effort — URLs that cannot be parsed, such as company pages (
linkedin.com/company/acme) or a plain username without a URL, are stored as-is without an error. - CRM background sync historically skipped normalization — this has been fixed, but contacts synced from a CRM (Salesforce, HubSpot, Pipedrive, Copper) before the fix may still hold non-normalized URLs until they are next updated.
- RB2B leads arrive pre-normalized — the LinkedIn URL received from RB2B is saved in the canonical format, so variants of the same profile from that source do not create duplicates either.
- Two identifier values are two records — deduplication keys on the chosen identifier, so a person appearing under two email addresses is not merged automatically.
- Accounts have their own import modes — including a deliberate Duplicate mode that creates a copy with the new data instead of touching the original.
Configuration that changes this rule
At contact import: the identifier drop-down and the Matched Records choice (Update Missing Fields vs. Skip). In Settings > Contact handling, the enrichment settings decide what an update writes when new information is found: Keep existing data preserves current information and skips conflicting new data; Override with new data replaces existing fields. For account (company) imports from CSV, four modes exist: Overwrite existing fields, Update missing fields, Skip, and Duplicate — with Account name mandatory for mapping. See Manage duplicate contacts.
Limits
| Limit | Value |
|---|---|
| Rows per contact CSV | Up to 10,000 |
| Rows per account CSV | Up to 10,000 |
| Identifier choices | A unique field such as Email, Last Name, or Phone |
| Canonical LinkedIn form | https://www.linkedin.com/in/username |
| Normalization coverage | CSV import, V3 API import, Website Visitors, RB2B, email-based enrichment, LinkedIn URL enrichment, CRM sync, manual edits, and automatic LinkedIn steps |
FAQ
What does "Skipped" mean in my import results?
Skipped rows are duplicates the system removed during the import — the identifier matched an existing contact and your matched-records choice did not update it. Updated rows, by contrast, are existing contacts whose profiles were changed. See Import contacts.
Do LinkedIn URL variants create duplicate contacts?
No. Duplicate detection by LinkedIn URL is format-agnostic — trailing slash, query parameters, http:// vs. https://, and missing www all resolve to the same canonical https://www.linkedin.com/in/username form. The exception is unparseable values like company-page URLs, which are stored as-is.
What happens when the same person has two email addresses?
With Email as the identifier, each address is its own key, so the person gets two records — automatic merging across different identifier values is not documented. Pick the record whose address you actually contact, and see Manage duplicate contacts for cleanup.
Are accounts deduplicated the same way as contacts?
Accounts imported from CSV offer four explicit modes — Overwrite existing fields, Update missing fields, Skip, and Duplicate (which intentionally creates a copy while leaving the original unchanged). Account name is the mandatory mapped field. See Companies.
Related
Build with Reply
- REST API: docs.reply.io — create/update contact semantics
- MCP: agents.reply.io/mcp