RevOps Playbook: Campaigns, UTMs, and Multi‑Touch Attribution Between HubSpot and Salesforce

Attribution breaks when campaigns and UTMs don’t traverse systems intact. Marketing sees one story. Sales sees another. Finance can’t reconcile sourced vs. influenced. This playbook provides a pragmatic design to make HubSpot and Salesforce tell the same attribution story by standardizing UTM capture, campaign structure, and membership sync.

The guidance assumes Salesforce is the durable ledger for Campaigns and Campaign Members, while HubSpot is the system of action for channels, UTMs, and nurture. If you’ve historically created campaigns in HubSpot, we’ll show how to transition without losing history.

Operating Assumptions

We’ll assume a simple, scalable policy:

  1. UTMs are captured and normalized in HubSpot at the session and form‑submission level. First/last touch rollups live on the Contact and are mirrored to Salesforce.
  2. Salesforce owns campaign taxonomy (programs, child tactics) and Campaign Members. HubSpot references the same campaigns via shared keys.
  3. Multi‑touch attribution (MTA) is computed either in HubSpot, Salesforce, or your warehouse, but the underlying membership data is consistent in both systems.

Campaign Taxonomy That Survives Scale

Adopt a hierarchy that your teams can actually maintain:

Shared Keys and Creation Policy

Pick one creation source and stick to it. The durable pattern:

  1. Create every new campaign in Salesforce with an external key (External_Campaign_Key__c).
  2. Store that key in HubSpot (Campaign external ID) and in any orchestration tools. If HubSpot needs to create a campaign, it must call a Salesforce‑first path or write the external key back after Salesforce creation.
  3. When HubSpot runs a program (email, form, ad), it adds or updates Campaign Members in Salesforce for the tactic campaign using the Contact/Lead ID.

UTM Capture and Contact Rollups

Capture UTMs in HubSpot with strict normalization:

  1. At session level: capture raw UTMs for analytics; do not mirror these into Salesforce.
  2. At conversion level: stamp UTMs at the moment of a qualifying event (form submit, trial start). Map these into “First Touch” and “Latest Touch” rollups.
  3. Mirror rollups to Salesforce on Contact/Lead and also to the Campaign Member when the member is created. Once set, avoid overwriting first touch; allow latest touch to update.

Recommended HubSpot properties:

Mirror to Salesforce custom fields on Lead/Contact with identical names (or your naming standard). For campaign alignment, include utm_campaign and a Touch_Type__c field on Campaign Member when created.

Member Status and Progression

Define a status model that works for all digital campaigns:

In HubSpot, configure workflows to set the appropriate status when the qualifying action occurs. Writes must target the Salesforce Campaign Member via external campaign ID and Salesforce record ID to avoid duplicates.

Multi‑Touch Attribution Models

Pick one MTA model per dashboard; document its rules and stick to it for a quarter. The simplest options:

Where to compute:

Opportunity Association and Influence

For any MTA model that includes revenue, ensure Opportunities are associated to relevant Campaign Members. The durable policy is:

  1. When a Salesforce Opportunity is created, copy the primary Contact and recent Campaign Members to the Opportunity via native influence or a light automation. Do not mass‑associate thousands of members; it inflates influence and slows reports.
  2. When HubSpot creates or updates a Deal that mirrors an Opportunity, ensure the external key is present so influence automations can resolve the Opportunity correctly.

Cost Capture and ROI

If Finance needs net ROI, capture actual cost at the tactic campaign. For recurring programs, post costs monthly as separate child tactics or via a cost ledger related to the campaign. Keep planned cost on the parent program for budget variance reporting.

Data Quality Guardrails

Defend your attribution integrity with these habits:

  1. Normalize UTM parameters (lowercase, trimmed, whitelisted values). Store raw values separately if you need them for diagnostics.
  2. Block non‑human traffic (bots) and filter internal IP ranges.
  3. For direct traffic without UTMs, apply a last non‑direct rule so you don’t attribute “Direct” excessively.
  4. Disallow overwriting first‑touch fields. If an admin must correct them, stamp a First_Touch_Manual_Override__c flag.

Transitioning from HubSpot‑First Campaigns

If you historically created campaigns in HubSpot, migrate to Salesforce‑first with a pragmatic backfill:

  1. Export HubSpot Campaigns with their IDs and key metadata.
  2. Create matching campaigns in Salesforce; write the Salesforce external key back into HubSpot.
  3. Reconcile membership by matching email/record IDs; avoid re‑adding members to prevent fake “new” responses.

Reporting Patterns That Hold Up

Provide a canonical set of dashboards that are consistent in both systems:

Anti‑Patterns

Avoid the following practices:

FAQ

Should we put UTMs on Campaign Members or on Contacts?

Do both, but differently: store normalized first/last touch on the Contact for funnel reporting; stamp UTM context onto Campaign Members at the moment of membership. Contacts give you lifecycle context; members give you tactic‑level context.

How do we credit meetings booked from SDR outbound?

Treat outbound sequences as Salesforce Campaigns with explicit “Meeting Booked” statuses. Attribute in your model alongside marketing touches; don’t let them overwrite first‑touch attribution.

Can we rely on first‑touch if we do a lot of retargeting?

First‑touch alone underweights retargeting, content syndication, and community. Use W‑shaped or linear for executive reporting, and keep first‑touch for budget allocation sanity checks.

Where should we compute MTA if we plan to add product usage?

In your warehouse. Use HubSpot for capture and early insights, Salesforce for operational views, and a single warehouse model for mixed marketing + product attribution that feeds BI.

How do we avoid duplicate Campaign Members from HubSpot workflows?

Always reference the Salesforce campaign via external key and the record by Salesforce Id. Use “upsert” semantics and check for existing membership before adding. The official integration and light iPaaS flows can both do this safely.

More RevOps Playbooks from Bles Software