16 October 2026 · 8 min read

GA4 Lead Generation and Your CRM: Closing the Loop from Form Fill to Won Deal

A B2B client's monthly report showed 412 leads in GA4 and 96 in the CRM. Both numbers were correct. GA4 counted the users who triggered a form submission event. The CRM counted the contacts the marketing team decided were worth a sales call. Nobody had ever connected the two, and the client had spent a quarter arguing about which number was lying.

This is the most common measurement failure in lead generation, and it is not a tracking bug. It is a definition gap between two systems that were built for different jobs. Fixing it means deciding which system answers which question, then building one bridge between them.

What GA4 counts, and what it does not

Google recommends six events for the lead generation funnel: generate_lead, qualify_lead, disqualify_lead, working_lead, close_convert_lead and close_unconvert_lead. The triggers are specific. generate_lead fires when a user submits a form online or submits information offline. qualify_lead fires when a lead is marked as fitting the criteria to become qualified. working_lead fires when a lead contacts or is contacted by a representative. close_convert_lead fires when a lead becomes a customer.

Send those events and the Lead acquisition report populates, at Reports, then Acquisition, then Lead acquisition (or under Business objectives, Generate leads, then Lead acquisition). The metrics are worth reading closely, because they define the whole argument:

Two details in that list decide whether your report survives contact with a client. First, the metrics count unique users, not submissions. If one person fills in your form twice in a month, the report shows one new lead. Second, the dimensions are user-scoped channel groups, so the report answers "which channel brought this person to us first", not "which click produced the form fill". A client comparing this report to a CRM view filtered by campaign will see two different rankings of the same channels.

A companion report exists for the losses. The Lead disqualification and loss report carries two dimensions that only populate if you send the parameters with them: Disqualified lead reason, filled from the disqualified_lead_reason parameter on the disqualify_lead event, and Lost lead reason, filled from the unconvert_lead_reason parameter on the close_unconvert_lead event. Send the events without those parameters and the report is a count of nothing in particular.

Where the chain breaks

Look at those six events again. Only the first is a website event in the ordinary case. The other five describe decisions taken after the form has been submitted, sometimes weeks later, by a person reading it and forming a judgement. A tag manager has no opinion about whether a lead was qualified.

The CRM does hold that judgement. HubSpot, for example, keeps a lifecycle stage on every contact: Subscriber, then Lead, then Marketing Qualified Lead, then Sales Qualified Lead, then Opportunity, then Customer, with Evangelist and Other after that. The sequence matters in practice, because the default automatic updates only move a contact forward. A contact moved to Customer by a closed deal will not slide back to Lead when the deal is reopened, and HubSpot's own tools, including imports, form submissions, the API and workflows, cannot set an earlier value until the field is cleared first. Whatever you read out of the CRM has to respect that ordering.

So the loop closes only when something carries the qualification decision back to the system that did the reporting. There are two upload routes, they go to two different destinations, and they need two different identifiers. This is where most implementations quietly fail.

Two routes, two identifiers

The first route sends data back into GA4 through Data Import, on the import events path. Uploaded events are processed as though they had been collected by the SDKs, and they take the timestamp you give them or the timestamp of the upload if you give none. The required fields are one of client_id or app_instance_id, one of measurement_id or firebase_app_id, the matching pair between them, and event_name. The timestamp is optional, but the event must fall within the previous two calendar days plus today. user_id is optional and recommended where available. Consent signals are optional and, in Google's wording, highly recommended where available. Personally identifiable information is not allowed in an event import at all, and deleting a data source afterwards does not delete what you already uploaded.

The second route sends data back to Google Ads through enhanced conversions for leads. That route takes hashed first-party data, such as an email address from the lead form, and matches it against data collected by your own tag and against signed-in Google accounts. Google's note on identifiers is blunt: include GCLIDs with your uploaded events whenever possible, and they are required if you are not using a tag to collect user-provided data.

There is a deadline in the past that catches people out. Since 15 June 2026, offline conversion import and enhanced conversions for leads uploads have moved to the Data Manager API and are blocked in the Google Ads API. Developer tokens that sent no request between January and June 2026 were not allowlisted for legacy access. If a client's pipeline still depends on the old upload, it is already broken, and the fix is an API migration rather than a tag change.

The identifier your CRM probably already holds

The GA4 import route needs client_id, which is a value the Google tag writes into the browser. Most CRMs do not store it, which is the usual reason a team tries imports for a fortnight, sees nothing arrive, and concludes that offline data cannot be joined to Analytics at all.

The Ads route needs less. HubSpot sets a Google Click ID contact property automatically, based on a GCLID provided by Google Ads, and that property sits on the contact record from the moment the form is submitted. It survives the session, the device change and the fortnight the lead sits in the pipeline.

That asymmetry is worth stating plainly to a client. If the CRM can hand over the GCLID or a hashed email, you can send qualification back to Google Ads and bid on leads that salespeople accepted. If nobody can produce a client_id, the GA4 funnel report stops at generate_lead, and the rest of the funnel lives in the CRM's own reporting. Both are honest answers. Promising a full-funnel GA4 report without an identifier to hang it on is not.

HubSpot's GA4 integration, and what it does not do

The native connection is narrower than people expect. You can add a GA4 measurement ID to HubSpot settings, either per domain or for all domains, or you can place the GA4 tracking code in a domain's site header HTML, which needs Marketing Hub Professional or Enterprise. Accounts on Marketing Hub Starter without Content Hub can only use the measurement ID. If you use the measurement ID, HubSpot also adds GA4 tracking to its payment checkout page, covering payment links and quotes, and you can switch that off in payments settings.

One condition matters for UK clients. If you use HubSpot's data privacy settings or a cookie consent banner that requires opt-in, the GA4 script only runs for visitors who opt in. Visitors who decline are simply absent from the property, which is correct behaviour and also the reason your GA4 traffic will always sit below HubSpot's own visitor count.

What the integration does not do is close the loop. It sends website activity into GA4. It does not push lifecycle stages back, does not send qualification events, and does not give GA4 a way to recognise a contact record. A healthy page view stream says the tag is installed. It says nothing about whether the deal data reaches the advertising platforms.

Marking the events so they count

Any event you collect can be marked as a key event, and generate_lead should be one. Once it is, you can create a Google Ads conversion from the GA4 key event and manage it from either interface, which gives the same conversion count in both places and reduces the discrepancy between them. Google's own note in the key events documentation is the part clients keep discovering the hard way: Google Ads conversions do not appear in standard Google Analytics reports. Two screens, two numbers, both correct.

The bigger risk sits in what you send to bidding. If the Google Ads conversion is built on generate_lead, the campaign optimises for form fills, and the cheapest form fills are rarely the best leads. Building the conversion on imported qualification data instead changes what the algorithm is trying to find. That single choice usually moves cost per qualified lead more than any bid strategy adjustment.

Consent, and the part that is not negotiable

GA4's event import forbids personally identifiable information. The Ads route is deliberately different, because matching relies on hashed email and phone data. Hashing is pseudonymisation, not anonymisation, and under UK GDPR a hashed email stays personal data for as long as the source list exists.

Consent signals are optional in a GA4 import and the upload still lands without them, which makes it tempting to skip. Google recommends including them, and the advertising side depends on them. The ICO's guidance on storage and access technologies, finalised in April 2026, is clear that online advertising needs consent, that advertising measurement rides on that consent rather than requiring a separate one, and that nothing non-essential should run before the visitor has made a choice. A lead form that collects an email for a sales conversation and a form that feeds it into Ads measurement are asking two different questions, and the wording on the form should say which one the visitor is answering.

Before you send the next lead report

The gap between 412 and 96 is not a defect in either platform. It is the distance between a form submission and a sales judgement, and closing it is a plumbing decision rather than a reporting one. Pick the bridge, document which identifier carries it, and tell the client which number answers which question. The reconciliation arguments stop after that.

Leads Not Matching Between GA4 and Your CRM?

North Digital maps lead funnels across GA4, GTM and the CRM, implements the qualification events and the feedback upload, and documents which identifier carries the loop so the numbers can be explained rather than argued about.

Talk to North Digital