Tutorial

How Do You Tag Every Deal With Its First Campaign in HubSpot?

Written by
Pravin Kumar
Published on
Oct 12, 2026

How do you tag every deal with its first campaign in HubSpot?

Store the first campaign on the contact in a custom property, then create a deal property with HubSpot's property sync field type that copies that value from the associated contact. Choose which contact wins when a deal has several. Then build a report on the deal property. Sync properties need a Professional or Enterprise subscription.

This tutorial is for a small revenue team on HubSpot that can see where contacts came from but cannot answer a simpler question: which campaign created the deals that closed? The answer usually sits on the contact record, while the revenue sits on the deal. Reports that try to join them get messy fast.

Putting the first campaign directly on the deal fixes that. Every deal carries its own origin, and a deal report can group revenue by campaign without any extra joins. Here is how I set it up.

Why does a deal need its own first-campaign field?

A deal needs its own field because revenue lives on the deal while source data lives on the contact. When the value sits on the deal, you can report pipeline and closed revenue by campaign in one simple deal report. It also keeps the original value intact even if contacts change or get removed from the deal later.

It also makes the data visible to sales. A rep opening a deal can see which campaign started it, which helps them tailor the conversation. A buyer who came from a webinar on pricing needs a different first call than one who came from a cold email about integrations.

Keep the definition tight. "First campaign" means the campaign attached to the contact's first known visit or form submission, not the most recent one. Last-touch data has its place, but mixing the two in one field ruins both.

What do you need in place before you start?

You need consistent UTM tagging on your campaigns, a contact property that stores the first campaign value, forms or tracking that fill that property, and a HubSpot subscription at Professional or Enterprise for sync properties or workflows. Without clean UTMs, this setup will faithfully copy messy data onto every deal.

Clean naming is the foundation. If one campaign shows up as "spring-webinar," "Spring Webinar," and "webinar_spring," your report will split it into three. Agree on a naming convention first. I covered how in UTM discipline so your reporting stops lying.

I use a custom property rather than HubSpot's built-in source properties for this. A custom property gives you full control over what gets stored and when, and you can confirm it works as a sync source in your own account.

How do you capture the first campaign on the contact?

Create two single-line text contact properties: "Latest campaign" and "First campaign." Send the utm_campaign value into "Latest campaign" through a hidden form field. Then build a contact workflow that copies "Latest campaign" into "First campaign" only when "First campaign" is empty, so the original value never gets overwritten.

The "only when empty" rule is the heart of first-touch data. Hidden form fields usually write their value on every submission, so a single property would drift into last-touch data. The two-property pattern keeps both views. Test it by submitting a form twice with different UTMs and checking that "First campaign" keeps the first one.

If your site runs on Webflow, I wrote a step-by-step guide on capturing first-touch UTMs in a Webflow form. Another option on any site is to store the first value in the browser and always send that stored value, which keeps the form itself first-touch.

How do you copy the first campaign onto the deal with a sync property?

In HubSpot, go to Settings, then Properties, and click Create property. Choose Deal as the object, pick the property sync field type, select Contact as the source record type, and select your "First campaign" contact property as the source. HubSpot says sync properties update automatically when the source value changes on an associated record.

HubSpot says the sync should usually happen in under five seconds, though large data volumes can take longer. Sync property values are read only on the deal, which is what you want for an origin field. Nobody should edit it by hand.

Know the limits before you rely on it. HubSpot notes that an association must exist between the records, that sync does not work in both directions, that properties with restricted access cannot be used as a source, and that your subscription limits how many sync properties you can create.

What if you cannot use sync properties?

Use a deal-based workflow with the Edit record action instead. Enroll deals when they are created, copy the value from the associated contact's "First campaign" property into a deal property, and add a branch first that checks the contact value is not empty. HubSpot recommends that check, because an empty source can leave the target empty.

HubSpot also notes that the source and target properties must be compatible, so use the same field type on both sides. A single-line text property on the contact should map to a single-line text property on the deal.

The workflow route gives you more control, such as copying the value only once at deal creation. The tradeoff is more moving parts to maintain. If sync properties are available on your plan, they are usually the simpler choice.

Which contact should the deal take its campaign from?

When a deal has several contacts, you must choose which one supplies the value. HubSpot's sync properties let you pick the first created or the most recently created associated record. For first-campaign data, choose the first created contact, because that person usually started the conversation that became the deal.

This rule is not perfect. Sometimes a later contact, such as a buyer brought in by the champion, came from the campaign that mattered. But a consistent rule beats a perfect one applied by hand. You can always review edge cases in your top deals manually.

Write the rule down where your team will see it, such as in the property description. When someone asks why a deal shows a certain campaign, the answer should be one sentence away.

How do you check it works and report on it?

Create a test contact with a known first campaign, create a deal, associate the contact, and confirm the deal property fills. Then check a handful of real recent deals. Once it looks right, build a deal report grouped by first campaign, showing deal count, pipeline value, and closed-won revenue.

Older deals created before you set this up may stay blank until the sync or workflow runs for them. Decide whether to backfill them. For a sync property, check how existing associations are handled in your account. For a workflow, you can enroll existing deals once.

Review the report monthly. Look for campaigns that produce many deals but little revenue, and the reverse. That is where this setup earns its keep: it shows which campaigns bring revenue, not just leads.

What should you do next?

Create the "First campaign" contact property this week and make sure your forms fill it only when empty. Then add the deal sync property, test it with one contact and one deal, and build the report. After a month of data, review which campaigns actually created revenue with your sales and marketing leads.

Start simple, with one field and one report. You can add first-touch medium, source, or content later, once the first field proves reliable.

I build websites and the automations behind them for lead generation, and connecting campaigns to revenue is one of the most useful things a small team can set up. If you want help wiring this into your HubSpot account, reach out and let's chat.

Get found, cited and the back office automated

Let's make your site the source AI engines quote and wire up the systems behind it.

Contact

Let's get your website found and cited by AI

Tell me what you're working on, whether AI search is skipping your product, your back office is buried in manual work, or you need a build that does both.

Got it, thanks. I read every message personally and reply within 1-2 business days.
Oops! Something went wrong while submitting the form.