Every lead used to be a manual copy-paste chore from Pify into HubSpot — with a guess at the source. Now leads land in HubSpot in under 10 seconds, with the real ad source baked in.
The Summit Rx website runs on Shopify, and we collect leads through a contact form built with Pify — a popular Shopify app that lets you put forms anywhere on a store. Pify works great for capturing the form data, but it stores submissions in its own dashboard — separate from HubSpot, the CRM where the sales team actually lives.
So every single lead was a manual chore: log into Pify → copy the lead's details → switch to HubSpot → paste them into a new contact record → guess at where the lead came from. I was the manual workaround between the two systems. A few minutes per lead, several times a day, every day.
Two problems showed up:
HubSpot has a tracking cookie that's supposed to remember which ad first brought a visitor in (using URL parameters called UTM tags — the bits like ?utm_source=google in an ad link). The catch: HubSpot only locks that in on a visitor's first session. If someone clicks a Google ad, leaves without filling the form, comes back a week later by typing the URL directly, and then fills the form — HubSpot stamps them as "Direct Traffic." The Google ad that actually brought them in gets zero credit. This is called the multi-session attribution gap, and it's how most CRMs lose track of the real source.
First obvious move: stop being the manual workaround. Pify has a built-in HubSpot integration that auto-creates a contact when someone submits the form, so I turned it on. It did sync the lead's name and email, but it doesn't carry any of the ad context (which campaign, which platform, which click). So leads now arrived in HubSpot automatically, but they all still showed up as "Direct Traffic." Faster, still useless for attribution.
Second move: layer on more UTM tagging across every ad campaign — the bits like ?utm_source=google&utm_campaign=brand-search that get added to ad URLs. I made sure every Google, Meta, and LinkedIn ad had a complete tag set, then leaned on HubSpot's first-touch cookie to remember it.
Result after two weeks: attribution moved from ~10% covered to ~18%. Still mostly broken. The issue wasn't the tagging — the tags were perfect. The issue was the session gap I described above: HubSpot kept "forgetting" the original ad the moment a visitor returned via a different path before converting.
That's when I realized: I had to own the entire pipe — the trigger, the data capture, and the source memory — not stitch together what other tools were willing to give me.
A four-piece system that captures the ad source the moment the visitor first lands, stores it durably, and hands it to HubSpot when the form fires — no matter how many sessions happen in between.
1. Capture the click identity at the front door. Every ad platform stamps a unique ID onto its ad clicks — Google calls it gclid, Meta calls it fbclid, LinkedIn calls it li_fat_id. These are tiny strings tacked onto the end of an ad URL, and each one tells you "this exact click came from this exact ad." A small JavaScript snippet now runs on every page of the Summit Rx website — when a visitor arrives with one of those IDs in the URL, it grabs the whole ad context (click ID, UTM tags, landing page, timestamp) and saves it locally in the visitor's browser using localStorage (think of it as a sticky note the browser keeps for that visitor). Even if the visitor leaves and comes back weeks later by typing the URL directly, that sticky note is still there.
2. Pify reads the sticky note on submit. I wired hidden fields into the Pify form that automatically pull from the stored ad context the moment the visitor hits Submit. So instead of just sending name + email + question, the form sends name + email + question + which ad they originally came from + which campaign + which landing page.
3. n8n receives the rich form data and decides what to do with it. n8n is an automation platform — picture a visual canvas where you connect different services (form → CRM → Slack) with rules and logic between them. It's like Zapier, but more flexible and self-hostable. The form's payload goes to an n8n "webhook" (a simple URL the form can post data to), and n8n runs the real logic:
first_touch_click_id so the original ad always stays on recordEAIaIQobChMI...4. Slack ping to sales. The moment HubSpot is updated, n8n posts a formatted message into the sales team's Slack channel with the lead's name, company, the ad they came from, and the page they landed on. Sales knows the prospect's full story before they pick up the phone — which changes how the call opens.
The day-one win was unblocking a chore that was eating my mornings. Every lead now lands in HubSpot the moment the Pify form is submitted — no human in the loop. Sales sees them in Slack within seconds, not hours.
The second-order win showed up about a month in: with real attribution flowing into HubSpot, the marketing team could finally see which channels actually converted. Two underperforming LinkedIn campaigns got paused. Google Search Brand and Meta retargeting got scaled up. Budget decisions stopped being vibes and started being data. That was the bigger compounding payoff — but it only existed because the automation got built first.
I'd store click IDs server-side from day one. localStorage is fast to ship but privacy extensions and ad-blockers wipe it aggressively on some percentage of traffic (we saw ~8% of click IDs drop off in the logs). A server-side cookie set by an edge worker on first page view would be more durable — especially for LinkedIn traffic, where the click ID has a shorter attribution window.
I'd also build a small attribution dashboard. Right now the sales team sees source context in Slack + HubSpot. Marketing has to run HubSpot reports to see channel performance. A 10-line Google Data Studio dashboard pulling from HubSpot directly would save the marketing team ~30 min a week of report-wrangling. It's on the list.
Bigger picture: if attribution matters to your business (it always does), you have to own the capture layer yourself. CRM vendors' default models are built to look okay out of the box. They're not built to be correct.
The specific endpoints in this build were Pify and HubSpot — but the architecture is invariant. It works with any web form provider and any CRM that supports API writes.
The skill isn't "knowing Pify and HubSpot." It's designing the orchestration so the data moves correctly across boundaries — that part doesn't change when the tools do.