QRAnalytica

How Do I Track How Many People Scanned My QR Code?

Use a dynamic QR code with a scan counter, tag the link with UTM parameters for your web analytics, or print one code per placement. Here's how to pick.

Nookesh Karri · 9 min read
A phone scanning a QR code on a poster, with a bar chart of scan counts beside it

To track how many people scanned your QR code, print a dynamic QR code: it sends every scan through a short redirect link that counts the scan before forwarding the phone to your page. If you also want to know what those people did on your website, add UTM parameters to the destination and read them in your web analytics. And if you want to compare placements, print a separate code for each one.

Those three methods answer different questions, and they rarely show the same number.

What you need before you start

  • A dynamic QR code. A static code holds the final URL inside the pattern, so the phone opens your site directly and there’s nothing in between to count. If you’re not sure which one you printed, the dynamic vs static guide shows how to tell.
  • Your own destination page, if you want web analytics as well. You can only read UTM parameters in the analytics of the site they land on.
  • Where each code will go: the poster, the flyer, the table tent, the packaging. The third method needs this list.

Method 1: the dynamic QR code’s own scan counter

A dynamic code encodes a short link that points to a redirect server. When a phone opens that link, the server logs the scan and answers with a redirect. On the web, MDN describes a redirect as a response with a status code that starts with 3 and a Location header holding the next URL. The phone follows it and lands on your page a moment later.

The count happens at the redirect, so it doesn’t matter whether your page loads fully, whether the visitor accepts cookies, or whether your site runs analytics at all. If the phone opened the link, the scan is counted.

A scan counter usually reports:

  • Total scans. Every scan, including repeats.
  • Unique scans. An attempt to count each device once. QR tools usually count a unique scan as one device, so two scans from the same device are two total scans and one unique scan. The unique figure is only an estimate, because someone who scans again on a second phone or in a different browser counts as a new person.
  • Location. Worked out from the scanner’s IP address, not GPS. MaxMind’s accuracy page puts country-level accuracy at “exceeding 99%” but city-level accuracy at “20% to 75%”, and notes that mobile devices “typically” resolve to a broad region. Trust the country. Read the city as a rough guide.
  • Device and operating system. iPhone or Android, and roughly which browser.
  • Time. When scans happen, by day and often by hour.

It can’t tell you who scanned or what they did next. The counter stops at the redirect, so it doesn’t know whether they read the menu, booked the viewing or bought the product.

In QRAnalytica, a dynamic code’s dashboard shows scans on a map by country and city, device details, and hourly scan counts that show when each code gets scanned most. Scan data is collected without cookies or storage of personally identifiable information. If the privacy side matters for your audience, the GDPR scan analytics post covers what a redirect collects and what it shouldn’t.

UTM parameters are tags you add to the end of a URL so your analytics knows where a visit came from. Google says you should always use utm_source, utm_medium and utm_campaign, and gives this example:

https://www.example.com/?utm_source=summer-mailer&utm_medium=email&utm_campaign=summer-sale

For a QR code, use something like utm_source=window-poster&utm_medium=qr&utm_campaign=autumn-menu. Google’s Campaign URL Builder builds the link for you.

Two rules from Google’s page matter here. Values are case sensitive, so utm_source=Poster and utm_source=poster show up as two different sources; stick to lowercase. And missing parameters show up as (not set) in your reports. Tag only the source, and your campaign reports will say (not set), which is usually where people think their QR traffic vanished.

Web analytics counts visits that load the page, not scans. If the visitor gives up on a weak signal, or closes the tab before the tag fires, there’s no visit. Consent banners cut the number too. With Google’s basic consent mode, tags don’t load “until a user interacts with a consent banner”, and when someone declines, “no data is transferred to Google at all”. Expect analytics to show fewer visits than your counter shows scans. That gap is normal.

UTM tracking earns its place after the landing: how long people stayed, which pages they opened, whether they filled in the form or checked out. The GA4 report setup is its own job, written up in how to track QR code scans in Google Analytics 4.

UTM tags work on a static code too, since they’re just part of the URL. You can’t fix a typo after printing, though, and you get no count of scans that never reached the page.

Method 3: a separate code for each placement

One code on everything gives you one number. You’ll know the campaign got scanned, but not which poster, table or flyer did it.

So print a different dynamic code for each placement and name it after where it goes. Take a café that puts the same menu link on its front window and on every table. With one code, the counter just says “the menu got scans”. With a “window” code and a “tables” code, the café can see whether passers-by are scanning from the street or seated guests are scanning at the table, and how that changes across the day. A restaurant can go further and give each table its own code, which is how table-level menu tracking works.

This stacks on the other two methods: each code gets its own counter and can carry its own utm_content value, so analytics splits the visits the same way.

How to check it’s working

  • Scan each code yourself before printing. Then open the dashboard and confirm the scan shows up against the right code.
  • Check the landing URL. After the redirect, look at the address bar on your phone. The UTM parameters should be there, spelled exactly as you set them.
  • Open your analytics’ real-time view right after that test scan. If nothing shows up, the tag isn’t firing on that page, or your own consent choice blocked it.
  • Test on both iPhone and Android. The built-in camera apps handle links slightly differently, and you want to see the same result on both.

What goes wrong

  • Counting a static code. No redirect, no counter. The only fix is a new, dynamic code.
  • Comparing numbers across tools. Each tool counts unique scans its own way, and analytics counts page loads instead. Compare a code with itself over time, or two codes in the same dashboard, never the counter against GA4.
  • Mixed-case or missing UTM values. These split one campaign into several rows, or show up as (not set).
  • Reading too much into the city. A mobile scan from the next town over can show up under a different city. Base decisions on country and on totals per code.
  • A code that stops redirecting. No redirect means no scans and no count. Why QR codes stop working lists the usual causes, like an ended trial or a deleted destination page.

Picking a method

  • How many people scanned: a dynamic code’s scan counter. Nothing else counts scans that never load the page.
  • What scanners did on your site: UTM parameters read in your analytics, alongside the counter.
  • Which placement worked: one dynamic code per placement.

My take: use one dynamic code per placement and add UTM tags from day one. It costs nothing extra at design time, and it’s the only setup that answers “how many”, “where from” and “what did they do next” without reprinting. For small campaigns, ignore unique scans and watch total scans per code week to week. The trend tells you more than an estimate of people.

The limitation: a dynamic code is only as reliable as its provider’s redirect service. QRAnalytica’s dynamic codes run through QRAnalytica’s redirect servers. That’s what makes editing and scan counts possible, and it also means that if the service goes down, your printed codes go down with it. If a trial or subscription ends, existing codes keep working and aren’t deleted; the account drops to the free plan. QRAnalytica can also add UTM parameters to the redirect automatically, so you don’t have to build each tagged link by hand. If you want to try it, the dynamic QR code generator makes a trackable dynamic code you can edit after printing.

FAQ

Can I track scans on a static QR code?

No. A static code holds your destination URL directly, so the phone goes straight to your site and nobody in between counts the scan. The closest you can get is UTM parameters on the encoded URL, which your web analytics counts only when the page loads and the tag runs.

What is the difference between total scans and unique scans?

Total scans counts every scan. Unique scans tries to count each device once, so one person scanning twice on the same phone is two total scans and one unique scan. Unique counts are an estimate, because a second phone or a different browser looks like a new person.

Why does my scan counter show more visits than Google Analytics?

The scan counter logs the scan at the redirect, before the page loads. Your analytics only sees visits where the page loads and the tag fires, so people who close the page early or decline cookies on a site using basic consent mode never reach your reports.

How accurate is the city shown for each scan?

It comes from the IP address, not GPS. MaxMind, a major IP location database, puts country-level accuracy above 99% but city-level accuracy at 20% to 75%, and mobile scans often resolve only to a broad region.

Should I use one QR code or several for the same campaign?

Several, one per placement. Each code then has its own counter, so you can see whether the window poster or the table tents did the work without any analytics setup.

Sources

Track your dynamic campaigns. 7-day trial, no credit card.
Generate Dynamic QR