HubSpot Salesforce Integration: The Complete Guide (From a Certified Practitioner)
What the native HubSpot-Salesforce connector actually does, the decisions that are expensive to reverse, field mapping, lifecycle stages, campaign sync, and the errors you'll actually see — from a certified practitioner.
I've lost count of how many HubSpot-Salesforce integrations I've walked into that were technically "connected" and functionally useless. The sync was green. Records were moving. And still nobody trusted the numbers, because nobody had made the decisions that make a sync trustworthy — which system owns which field, what a lead actually is, which stage means what.
This is the guide I wish existed before I did my first one of these. Not a click-through setup tutorial — HubSpot's own documentation covers that reasonably well. This is the practitioner version: what the connector actually does, the decisions that are expensive to reverse once you've made them, and the failure modes I see over and over in portals I'm brought in to fix.
I'm certified in the HubSpot-Salesforce integration and this is written from years of doing it, not reading about it.
What the native connector actually does (and doesn't)
The native HubSpot-Salesforce integration is a two-way sync engine, not a one-time import and not a reporting bridge. Once it's live, it keeps running — watching for changes on both sides and pushing updates across, on a near-real-time basis for most standard fields, with some processes running on a batch cadence under the hood.
What it syncs, by default:
- Contacts ↔ Leads/Contacts. HubSpot Contacts map to Salesforce Leads or Contacts depending on the record's state and your configuration. This is the single biggest source of confusion in the whole integration, and it gets its own section below.
- Companies ↔ Accounts. Generally a clean 1:1 mapping, assuming your data actually is 1:1 — which it often isn't once you've been running both systems for a while.
- Deals ↔ Opportunities. Two-way by default, including stage, amount, and close date, plus whatever custom properties you map.
- Engagement data, in a more limited way — some activity types sync, others don't, and the direction and completeness varies by activity type and by which side created it.
What it doesn't do well, or at all:
- It doesn't merge or dedupe records automatically. If you've got duplicates on either side, the connector will happily sync duplicate data into more duplicates.
- It doesn't resolve conflicting simultaneous edits with any nuance — it's essentially last-write-wins, which is fine until two systems both think they're right at the same time.
- It doesn't sync every object equally. Deals and Contacts get first-class treatment. Custom objects need explicit configuration and, on some HubSpot tiers, aren't supported for sync at all.
- It doesn't preserve field-level history across systems. It syncs current state. If you need to know what a field's value was on any given date, that has to come from somewhere else.
- It doesn't handle the Salesforce Lead-to-Contact conversion process gracefully by default — more on that in the next section, because it's the decision that causes the most long-term pain.
Licensing reality: you need HubSpot Marketing Hub or Sales Hub at Professional tier or above to use the native connector, and on the Salesforce side you need API access — included from Enterprise up, available as an add-on on some Professional editions. If you're on lower tiers on either side, you're looking at a middleware-based integration instead, which is a different set of trade-offs entirely.
Where it holds up at scale, and where it doesn't. For portals in the low thousands of contacts with a handful of custom objects, the native connector genuinely is close to "set it up properly once and leave it alone." Where I see it strain: high-volume marketing contact syncing against Salesforce API limits, custom object graphs that don't map cleanly to the connector's assumptions, and any workflow that needs to reason about both systems' state at once before deciding what to write. The connector moves data. It doesn't make decisions. Anything that needs conditional logic spanning both systems needs a workflow layer on top — in HubSpot, in Salesforce, or in middleware — because the sync itself won't do it for you.
Before you connect: the decisions that are expensive to reverse
Every integration I've been brought in to rescue has the same root cause: someone turned the connector on with default settings before anyone decided these four things.
1. Which system owns which field. For every property that exists on both sides, one system needs to be the source of truth. Deal owner, lifecycle stage, lead source, company industry — pick one owner per field and set sync direction accordingly. "Both can edit and it'll sort itself out" is not a strategy, it's a slow-motion data corruption process. Reversing this later means auditing every record to work out which system's value is actually correct.
2. Lead vs. contact strategy. Salesforce has two objects where HubSpot has one. A HubSpot Contact can map to a Salesforce Lead or a Salesforce Contact, and the connector has to decide which — usually based on whether the person already exists as a Salesforce Contact or Account relationship. The trap: when a Salesforce Lead converts, it becomes a Contact (and usually an Opportunity), and the connector's default behaviour for handling that conversion — what it does to the HubSpot record, what happens to activity history, whether the HubSpot record ends up pointing at the right Salesforce ID afterwards — needs to be understood and tested before you're relying on it for real pipeline. Get this wrong at scale and you end up with orphaned records on one side, duplicate Contacts on the other, and a support ticket queue nobody wants to own.
3. Sync direction, per property, not globally. "Two-way sync" as a single toggle is a beginner's mistake. You want two-way sync on some fields (deal amount, close date — wherever either side might legitimately update it first) and one-way on others (lead source should probably only ever flow from HubSpot; account tier might only ever flow from Salesforce). Deciding this field by field, before go-live, is the single highest-leverage hour you'll spend on the whole project.
4. Object mapping assumptions. The connector assumes roughly 1:1 between HubSpot Companies and Salesforce Accounts. If your Salesforce org has multiple Accounts representing subsidiaries of one HubSpot Company, or your HubSpot instance has multiple Companies that should map to one Account, you need to solve that before go-live — not discover it three months in when reporting stops reconciling.
None of these four decisions are hard to make correctly. They're just easy to skip, because the connector will happily sync without you making them, and it'll look like it's working right up until it doesn't.
Field mapping done properly
Default mappings get you Contact name, email, company, deal stage, deal amount — the obvious stuff. Real field mapping work is everything past that, and it's where most of the silent failures live.
Mapping types worth knowing:
- Default mappings are HubSpot-managed and can't be changed — mostly identity fields.
- Custom mappings are where you connect your own properties, and where you set sync direction per field.
- Calculated and read-only fields on either side (rollups, formula fields, HubSpot calculation properties) generally can't be sync targets — you can read from them, but writing to a formula field from the other system will fail silently or error, depending on the field type.
Picklist alignment is where most mappings quietly break. A dropdown field on both sides needs matching values — not just similar, matching, including case. Add a new value to a Salesforce picklist without adding the equivalent HubSpot option, and every record with that new value either fails to sync or lands with a blank field on the HubSpot side. This happens constantly because picklist values get added by whoever's closest to the field at the time — a sales manager adding a lead source value in Salesforce with zero awareness that HubSpot has a paired dropdown that now needs updating too.
The mappings that silently break, in rough order of how often I see them:
- Picklist drift — new values added on one side, not mirrored on the other.
- Validation rules on the Salesforce side rejecting a record HubSpot is trying to push, because a required field the rule depends on isn't in the sync.
- Record-type-dependent picklists — Salesforce picklist values that only exist for certain record types, which the connector doesn't natively understand as conditional.
- Multi-currency mismatches, if your Salesforce org has multi-currency enabled and HubSpot's currency handling doesn't line up per-record.
- Field-level security hiding a field from the integration user's profile, so the sync silently drops that field for records where the value differs — and nobody notices, because the integration user's permission set was set up by someone in IT who's never been in a sync error log.
The discipline that actually prevents this: whoever administers Salesforce picklists and whoever administers HubSpot properties both need visibility every time either one changes a mapped field. In practice this is usually a shared changelog or a standing Slack channel, not a technical control — but without it, drift is inevitable.
Selective sync and inclusion lists
Syncing every HubSpot contact to Salesforce by default is the single most common integration mistake, and it's rarely questioned because it's what the connector does out of the box. The problem: your HubSpot instance likely has thousands of contacts who never should have touched Salesforce — newsletter subscribers, one-time webinar attendees, people who filled in a gated content form and went nowhere. Sync all of them and you're burning Salesforce API calls on records sales will never look at, and filling their org with noise that makes real pipeline harder to find.
The fix is an inclusion list: a HubSpot list, built on criteria that actually indicate sales readiness, that gates what's eligible to sync. Only build the sync for records that clear a bar you define — lifecycle stage, lead score, explicit sales engagement, whatever's right for your funnel.
This deserves its own full treatment, because the edge cases (what happens when a record falls out of the list, re-sync behaviour, how this interacts with Salesforce sharing rules) matter as much as the initial setup. That's the companion piece: HubSpot Salesforce selective sync and inclusion lists.
Lifecycle stages vs. lead status — the mismatch that causes most reporting arguments
This is the one that generates the most Slack messages between marketing and sales ops, and it's almost always the same root cause: two different "stage" concepts, on two different objects, in two different systems, and nobody wrote down which one is authoritative for what.
HubSpot lifecycle stage lives on the Contact and is, by design, largely forward-only — it's a watermark of the furthest point a contact has reached (Subscriber → Lead → MQL → SQL → Opportunity → Customer). It resists being set backwards.
Salesforce Lead Status lives on the Lead object and is meant to move freely — Open, Working, Qualified, Unqualified, Nurturing — right up until conversion, at which point the Lead disappears into a Contact and an Opportunity, and Lead Status effectively stops applying.
Salesforce Opportunity Stage is a third concept entirely, tracking deal progression once an Opportunity exists.
These three don't map onto each other cleanly, and the connector doesn't pretend they do — it syncs what you tell it to sync, and leaves the interpretation to you. What actually happens in most unmanaged integrations: marketing reports MQL and SQL counts from HubSpot lifecycle stage. Sales reports pipeline from Salesforce Opportunity Stage. Someone builds a board deck combining both, the funnel doesn't reconcile, and the meeting turns into an argument about whose data is wrong instead of what to do about pipeline.
The fix isn't complicated, but it does require someone to make the call: decide which system's stage concept is authoritative for which reporting question, map lifecycle stage to lead status deliberately (not via default connector behaviour), and build funnel reports that pull from one consistent source rather than stitching two systems together after the fact. I've written the deeper version of the lifecycle-stage side of this in HubSpot Lifecycle Stages: The Quirks Everyone Hits — worth reading alongside this section if lifecycle stage specifically is where your pain is.
Campaign sync and attribution
Campaigns are the part of this integration most teams give up on properly configuring, and I understand why — the two systems model marketing campaigns fundamentally differently.
What syncs: HubSpot campaigns can be connected to Salesforce Campaigns, and Salesforce Campaign membership can reflect HubSpot engagement to a degree. Basic influence — a contact was part of a campaign that touched a won deal — can be represented.
What doesn't: HubSpot's multi-touch attribution models (first touch, last touch, linear, weighted, and the rest) don't have a native Salesforce equivalent. Salesforce Campaign Influence is a blunter tool — it tells you a campaign touched an opportunity, not how much credit it deserves relative to five other touches across the buyer's journey. If your CFO wants multi-touch attribution numbers in a Salesforce report, the native sync won't get you there on its own.
Workarounds that actually hold up:
- Sync UTM parameters and original source data as custom properties on the Contact/Lead, so at minimum Salesforce reports can filter and group by acquisition channel even without full attribution modelling.
- Keep attribution reporting in HubSpot, where the modelling actually lives, and treat Salesforce as the system of record for pipeline and revenue rather than marketing performance.
- If leadership genuinely needs unified multi-touch attribution across both systems, that's usually a case for a dedicated attribution or BI layer sitting on top of both — not something to force the native connector into doing.
Don't burn weeks trying to make Salesforce Campaigns replicate HubSpot's attribution models. It's not what the object was built for, and the sync isn't going to bridge that gap on its own.
The sync errors you'll actually see
Six error types account for most of what shows up in a sync error log once an integration's been running for a while. Practitioner detail — one-line cause for each, not a full troubleshooting walkthrough.
-
Required field missing / validation rule failure. Salesforce rejects a record HubSpot is pushing because a Salesforce validation rule requires a field that isn't part of the sync, or is blank on the HubSpot side. Cause: nobody checked Salesforce validation rules against the mapped field set before go-live.
-
Picklist value mismatch. The value being pushed doesn't exist as a valid option on the receiving picklist. Cause: picklist drift — someone added a value on one side without mirroring it on the other.
-
Duplicate rule block. Salesforce's duplicate management rules reject an incoming record because it matches an existing one closely enough to trigger a block rather than a merge. Cause: Salesforce dedupe rules weren't tuned with the sync in mind, so legitimate updates get treated as duplicate creation attempts.
-
Ownership or sharing rule error. The integration user doesn't have access to create or edit a record in the target owner's territory or queue. Cause: Salesforce sharing rules restrict the integration user more tightly than the humans who'll eventually own the record.
-
Field-level security error. A field is mapped, but the integration user's profile doesn't have edit access to it, so the write silently fails or the whole record sync errors depending on configuration. Cause: the integration user's permission set was configured for general access, not audited against the specific fields in the sync.
-
Lead conversion race condition. A Salesforce Lead gets converted by a rep at the exact moment HubSpot is pushing an update to it, and the update lands on a record ID that no longer exists in the state HubSpot expected. Cause: timing — rare individually, common in aggregate on high-volume portals.
Every one of these produces an entry in HubSpot's sync error dashboard with enough detail to diagnose if someone's actually looking at it. The failure isn't usually technical — it's that nobody owns checking the error log on a schedule, so a handful of errors from week one becomes hundreds by month three.
Best practices checklist
Ten things I check on every integration, whether I'm building it fresh or inheriting someone else's:
- Field ownership documented — one source of truth per synced property, written down somewhere both admins can see.
- Sync direction set per property, not globally toggled to two-way.
- Picklists audited for exact match, including case, across both systems.
- Lead vs. Contact conversion behaviour tested with real test records before relying on it for production pipeline.
- Lifecycle stage and Lead Status mapped deliberately, not left to connector defaults.
- Inclusion list in place — you are not syncing every contact by default.
- Salesforce validation rules checked against every mapped field the integration writes to.
- Integration user's permissions audited against the actual field and object set in the sync, not just "give it broad access and move on."
- Sync error log reviewed on a schedule — weekly at minimum — by someone who'll actually act on what they find.
- Duplicate management rules on both sides tuned with the sync in mind, not configured in isolation from each other.
Most integrations I audit are missing at least four of these. Any one of them missing is tolerable short-term. Missing five or six compounds fast.
When to get help
Everything above is doable in-house if someone has the time and the HubSpot/Salesforce admin depth to work through it properly. Most ops and marketing leaders I talk to have neither — not because they're not capable, but because this is genuinely a specialism, and it competes for time against everything else on a RevOps or marketing ops plate.
If you want a read on where your current integration actually stands before committing to a fix, that's what the Sync Health Audit is for — a scored report against your live HubSpot-Salesforce sync, plus a prioritised fix list, in about a week.
If lifecycle stages specifically are where your reporting breaks down, HubSpot Lifecycle Stages: The Quirks Everyone Hits goes deep on that one issue. And if you haven't scoped selective sync yet, HubSpot Salesforce selective sync and inclusion lists covers exactly how and when to set it up.
Frequently asked questions
How does HubSpot integrate with Salesforce?
Through a native two-way sync connector that maps HubSpot Contacts, Companies, and Deals to Salesforce Leads/Contacts, Accounts, and Opportunities. You configure field-level mappings and sync direction per property, and the connector keeps records in near-real time sync rather than doing a one-off import. It requires HubSpot Marketing Hub or Sales Hub Professional or higher, and a Salesforce edition with API access (Professional and above, with add-ons, or Enterprise and up natively).
Is the native HubSpot Salesforce connector enough, or do I need middleware?
For most standard object sync — Contacts, Companies, Deals, core properties — the native connector is enough and is the right starting point. You need middleware (Make, Zapier, or a custom layer) when you're syncing custom objects the connector doesn't support well, need conditional logic the connector can't express, or need to orchestrate multi-step workflows that span both systems. Bolt on middleware for the gap, don't replace the native connector wholesale.
Why do HubSpot and Salesforce show different numbers for the same metric?
Almost always a lifecycle stage or lead status mismatch, or a sync direction that isn't what someone assumes it is. HubSpot lifecycle stage and Salesforce Lead Status are two different concepts with two different rulesets, tracked on different objects, and nobody wrote down which one is authoritative. Marketing reports off one, sales reports off the other, and the numbers diverge quietly until someone builds a board deck.
Can I sync only some HubSpot contacts to Salesforce?
Yes, using an inclusion list — a list-based filter that controls which records are eligible to sync. This is the standard fix for API limit issues and for keeping unqualified marketing contacts out of your Salesforce org. The full mechanics are in the companion piece, HubSpot Salesforce selective sync and inclusion lists.
Does the HubSpot Salesforce integration sync historical data?
It syncs current field values, not field-level change history. If you need historical state — when a deal moved stage, when a lifecycle stage changed — you need date-stamp properties or a reporting layer that captures history independently. The connector will backfill existing records into the sync the first time you turn a mapping on, but from then on it's syncing current state, not a change log.
How long does a HubSpot Salesforce integration take to set up properly?
A basic connection with default mappings can be live in an afternoon. A properly scoped integration — field ownership decided, sync direction set per property, picklists aligned, lifecycle stage and lead status reconciled, selective sync configured — usually takes one to two weeks of focused work depending on how much custom object and picklist cleanup is needed first.
- HubSpot
- Salesforce
- CRM Integration
- RevOps
Working on something similar?
Let's talk about the workflow that's costing your team the most hours.
30-minute call. No pitch. Walk away with a build estimate either way.
