Home › Blog › Connect Smartlead and Instantly to HubSpot Without Duplicate Contacts
The naive integration creates a new HubSpot contact for every sequencer event and floods your CRM with duplicates inside a week. The correct build uses a stable contact key and create-or-update logic, and syncs five things: contacts, replies, campaign names, dispositions, and suppressions. Here is the whole wiring.

Duplicates come from blind creates. Fix: normalize email as the contact key, search HubSpot first, update if found, create only if absent, and route every flow through that one upsert. Sync five things: contacts, reply text as timeline activity, campaign name, a disposition property, and suppressions in both directions. Native integrations cover basics; Make or n8n middleware is where dedupe guarantees and agency routing live.
Every event-driven integration that creates records without looking first will duplicate: the send event makes a contact, the reply event makes another, a rep imports a CSV and makes a third, and now revenue attribution is spread across three copies of one human. HubSpot dedupes on exact email match at creation in some paths but not others, and trusting it is how the mess happens. The fix is architectural, not a cleanup job: one upsert function, called by everything, that owns the search-then-write logic.
UPSERT (the only writer):
in: email, fields → normalize email →
HubSpot search by email →
found? update : create → return contact id
FLOWS:
reply webhook → classify (see classifier post) →
upsert contact → log reply as activity →
set disposition → positive? route to rep
campaign launch → per contact: upsert +
set campaign property (or: sync-on-reply only)
HubSpot unsubscribe/customer workflow →
sequencer blocklist API (both tools)
sequencer opt-out webhook →
HubSpot opt-out property + suppression hub
DISPOSITION property values:
in_sequence → replied → positive → meeting
→ closed_no / opted_out / bouncedUse email address as the stable contact key and ALWAYS call HubSpot's create-or-update path (search by email first, then update if found, create only if not) instead of blind creates. Normalize the email (lowercase, trimmed) before every lookup. Duplicates come from event-driven blind creation: a reply event, a click event, and a manual import each creating their own copy of the same human. One upsert function that every flow calls kills the problem permanently.
Five things: (1) contacts, on first outbound send, with company, source, and campaign; (2) replies, logged as timeline activities with the actual text; (3) campaign name on the contact so revenue can be attributed to campaigns later; (4) disposition, a custom property tracking the outcome (in sequence, replied, positive, meeting, closed-no, opted out); (5) suppressions, opt-outs flowing both directions so HubSpot unsubscribes stop sequencer sends and vice versa. Skip opens and clicks, they are noise in a CRM.
Decide deliberately, both are defensible. Sync-on-send gives sales full visibility into who is being worked and prevents an SDR cold-calling someone mid-sequence, at the cost of thousands of never-replied contacts in the CRM. Sync-on-reply keeps the CRM clean and human, at the cost of pre-reply invisibility. Most teams we see land on sync-on-reply plus a suppression check against the CRM before launch, so existing customers and open deals never enter a sequence at all.
Both sequencers ship native HubSpot integrations that cover basic contact and reply sync, and they are fine for a simple single-workspace setup. You outgrow them when you need disposition mapping, dedupe guarantees, multi-workspace agency routing, or suppression flowing in both directions, which is most serious operations within a quarter. The middleware build (Make or n8n calling both APIs) is a few hours and gives you the upsert logic natively integrations refuse to promise.
Reverse sync: before any list loads into a sequencer, check it against HubSpot for existing contacts with open deals, customer status, or unsubscribed marketing status, and remove the matches. Then ongoing: a HubSpot workflow adds anyone who unsubscribes or becomes a customer to the sequencer blocklists via API. This is the same hub-and-spoke pattern as the suppression sync, with the CRM as one more spoke.
Prewarmed Inboxes So You Can Send Cold Emails Today
Get Prewarmed & Fresh InboxesGoogle, Microsoft 365 and Azure inboxes with free prewarmed domains and DNS configured before you log in. Prewarmed inboxes send the day they land; every order is delivered within 48 to 72 hours.
Get Prewarmed & Fresh Inboxes