How to track QR code scans for free
Updated September 2026
Paid QR platforms sell you a dynamic code mostly for the scan analytics. But if your code points at a web page, you can get a scan count — plus source, time and rough location — for free, using analytics you probably already have. Here's the setup.
How it works
A static URL QR code opens a web page. If you add UTM parameters to that URL, your website analytics (GA4, Plausible, Fathom, Matomo, Cloudflare Web Analytics) records each visit with those tags attached. Every tagged visit is, near enough, one scan.
Nothing sits between the scan and your page — no third-party redirect, no subscription, and the code never expires. You're just labelling the traffic so your existing analytics can pick it out.
Step 1 — build the tagged URL
Take the page you're linking to and add three parameters: utm_source (where the code physically is — flyer, window, menu), utm_medium (always qr), and utm_campaign (which campaign — spring_sale).
Example: https://yoursite.com/offer?utm_source=window&utm_medium=qr&utm_campaign=spring_sale. The generator's URL type has these fields built in, so you don't have to hand-write the string.
Step 2 — generate the static code
Paste the tagged URL, style it, download the SVG for print. It's free, unlimited and permanent — the UTM tags are invisible to whoever scans it, they just load the page.
Step 3 — read the numbers
In GA4: Reports → Acquisition → Traffic acquisition, then filter by session source / medium / campaign. In Plausible or Fathom: filter by the UTM values. The visit count for qr / your-campaign is your scan count, and you also get time of day, city-level location, device and new-vs-returning.
What you get, and what you don't
This method gives you most of what a paid dashboard shows:
- You get — total scans, trend over time, city-level location, device and OS, and which placement performed best
- You don't get — a live destination you can re-point after printing
- You don't get — scans that never opened the page (rare, but real if someone scans and doesn't tap)
- You don't get — a ready-made dashboard across hundreds of codes
Comparing placements
Run one campaign but give each placement its own utm_source — window, counter, flyer, receipt. Now your analytics tells you which placement actually pulls people in. To make a batch of codes that each carry a different source tag, the bulk generator takes a CSV with one tagged URL per row.
When free tracking isn't enough
Switch to a paid dynamic QR code when you need to change where a printed code points, when every scan must be logged whether or not the page loads, or when you're managing codes across many locations and need one dashboard. The static vs dynamic guide covers the trade-off in full.