Most Indian SMBs advertising on Google have a measurement hole shaped like the physical world. The ad is online; the customer walks in, calls, or scans a code at a counter. Google Ads never hears about it, Smart Bidding optimises for the wrong thing, and the monthly report says the campaign "isn't converting" when it is — just not on a web page.
QR codes are a way to close that hole, if you carry the right piece of data through. This is how we did it for QRCodeStack, a dynamic-QR SaaS whose own customers are exactly those offline businesses, and what changed once the ad account could see the scans.
The two loops
There are actually two distinct loops here, and it helps to keep them apart.
Loop 1 — QRCodeStack's customers. A restaurant runs a Google Ads campaign for "best biryani in Jayanagar", a person clicks, then walks in and scans the menu QR. The restaurant wants to know: did the ad cause the scan?
Loop 2 — QRCodeStack itself. QRCodeStack runs Google Ads for "dynamic qr code generator", a business owner clicks, signs up, and over the next weeks their codes get scanned. QRCodeStack wants to know: which ad campaign brought the customers who actually use the product?
Loop 2 is a standard offline-conversion problem with a twist (the conversion is a stream of events, not a single purchase). Loop 1 is harder and we'll come back to it.
Loop 2: sign-up → scans → back into Google Ads
Google Ads offline conversion import works like this: when someone clicks an ad, the landing URL carries a gclid parameter. If you store that click id against the account they create, you can later send Google an event — "this gclid converted, on this date, worth this much" — and Google will attribute it to the campaign, keyword and ad that earned the click.
What we built:
- Capture the GCLID on sign-up. A tiny script on the marketing site copies
gclidfrom the URL into a first-party cookie (90 days), and the sign-up form posts it along with the email. It lands on theaccountsrow. - Define "activation". A sign-up is cheap. A customer whose codes have been scanned 50 times in their first 14 days is real. We defined
activated_atas the moment an account crossed 50 scans, computed nightly by the same roll-up job that powers the dashboard. - Push activation as an offline conversion. Every night, for every account that activated in the last 24 hours and has a stored gclid, call the Google Ads API
UploadClickConversionswith the conversion action "Activated account", the timestamp, and a value (we used the plan's first-month price). - Demote sign-up to secondary. This was the important part. Once "Activated" existed as a primary conversion action, "Sign-up" became secondary. Smart Bidding now optimises for people who will use the product, not people who will fill in a form.
The whole pipeline is about 200 lines of Python and one cron entry.
What it changed
This is where Admiral comes in. With activation flowing into the account, we connected it to Admiral read-only and ran the audit. The first sync found:
- ₹19,640 of the previous month on search terms with zero conversions — "qr code generator free", "qr code scanner app", "what is a qr code"
- Search Partners and Display still ticked on two of three campaigns — 9% of spend, one conversion
- Three primary conversion actions, one of which was a page view of /pricing
Priced together: ₹34,800 of an ₹87,049 month — 40% — going where it could not produce an activated account.
The founder approved five of nine proposed fixes over two evenings (and declined one, for brand reasons — which is his call, and the log records it). Four weeks later: the same monthly budget, 3% less spend, 86 verified activations instead of 53, and cost per verified activation from ₹1,642 to ₹980. Admiral wrote it up with the full before/after table: How QRCodeStack cut Google Ads waste by 40%.
The activation signal is what made the audit actionable rather than just interesting. Without it, "cut the free-tool search terms" is a guess. With it, it is arithmetic.
Loop 1: the restaurant's problem
Now the hard one. The restaurant's customer clicked an ad on their own phone, walked in, and scanned a code with the same phone. Can we connect them?
Honestly: not reliably, and anyone who tells you otherwise is selling something. The ad click and the scan are separate sessions, often days apart, with no shared identifier. Three things work partially:
Unique codes per campaign. Print a different QR on the poster that goes up where the ad audience is, vs. the one on the counter. Scans on the "ad poster" are a proxy for ad-driven foot traffic. Crude, but it is what QRCodeStack's dashboard was built to show — per-code, per-city, per-hour.
Landing-page-to-scan deep links. If the ad landing page has a "save this offer" button that generates a personal QR (encoding the gclid), and the customer shows that code at the counter, the scan carries the click id. This works for offers and vouchers. It does not work for "just walk in".
Store visits, the Google way. Google's own store-visit conversions use location history from opted-in users. It needs a Google Business Profile, a volume threshold most single-location SMBs never hit, and you don't control it. Worth switching on; don't build on it.
We shipped the first two. The third is a checkbox.
The bit people skip
None of this matters if the conversion actions in the ad account are wrong. Before you build any pipe, open Goals → Conversions → Summary and look at what is marked Primary. If a page view is there, every number you have ever been shown about the account is inflated, and Smart Bidding has been optimising for people who looked at a page. Fix that first. It is free.
Then, if you'd rather not do the rest by hand, Admiral's audit runs the tag check, the goal check, and 24 others on connect, before you pay anything. Every change it proposes is a receipt with a one-click undo, and — because we think software touching your ad money should be accountable to a third party — the sequence is also recorded on Auditant, where an outsider can verify nothing was edited after the fact.
We build measurement that closes loops at 4UGUSTA. The dashboard half of this project is written up here.