Tracking QR code scans for free

You do not need a dynamic-code subscription to know which flyer or poster brought people to your site. Tag the link before you make the code, and the analytics you already have will do the counting.

Short answerAdd UTM parameters to your URL before generating the code — for example ?utm_source=flyer&utm_medium=qr&utm_campaign=spring-sale — and every visit from that code appears under that source and campaign in Google Analytics or any other analytics tool. It is free and works with static codes, but it counts page visits, not scans.

How UTM parameters work

UTM parameters are labels added to the end of a URL. Your website ignores them, but analytics tools read them and file the visit under the source, medium, and campaign you named. A visitor who scans a code sees the same page as anyone else.

The three UTM parameters worth using
ParameterWhat it recordsExample
utm_sourceWhere the code isflyer, poster, menu, packaging
utm_mediumThe type of channelqr
utm_campaignWhat it is forspring-sale, open-day-2026
utm_content (optional)Which variantwindow, counter, a5

Use lower case, hyphens instead of spaces, and the same spelling every time. Analytics tools treat Flyer and flyer as two different sources.

Setting it up

  1. Start from the page you want people to land on, e.g. https://example.com/offers/.
  2. Add the parameters after a question mark, joined with ampersands: https://example.com/offers/?utm_source=flyer&utm_medium=qr&utm_campaign=spring-sale. If the URL already has a question mark, join them with an ampersand instead.
  3. Paste the full URL into a browser and check the page still loads normally.
  4. Paste it into the generator and download the code.
  5. Scan the printed proof once, then check the visit shows up in your analytics real-time report.

One URL per print run

The tracking is only as detailed as your tagging. If the same code goes on a poster and a flyer, you will see them as one source. Give each placement you want to compare its own utm_source or utm_content value, and therefore its own code. Keep a short list of which code went where; months later, “a5” will mean nothing.

Static codes cannot be edited after printing, so check the tags before you print. A typo in a UTM value still sends people to the right page, but files their visits under the misspelt name.

Where the visits show up

In Google Analytics 4, open the Traffic acquisition report under Acquisition. Set the primary dimension to Session source / medium to see flyer / qr, or to Session campaign to see spring-sale. Add a comparison or filter for medium qr to see every code at once.

Other analytics tools — Matomo, Plausible, and most others — read the same parameters, usually under campaigns or sources. Shop and newsletter platforms often show UTM data on orders and sign-ups too, which lets you go from “visits from the flyer” to “sales from the flyer”.

What this does not tell you

  • It counts page visits, not scans. Someone who scans but does not open the link, or who has no signal, is not counted. Someone who visits twice may be counted twice.
  • Some visits are not recorded. Visitors who block analytics or decline cookies may not appear, so treat the numbers as a minimum.
  • The tags can travel. If someone copies the tagged URL and shares it, those visits are credited to your flyer too.
  • Longer URLs make denser codes. Each parameter adds characters, which can push the code up a version and shrink its modules. Check the version shown under the code against QR code size for printing.

A shorter alternative: a redirect on your own domain

If the tagged URL makes the code too dense, create a short address on your own site — example.com/flyer — that sends a 301 redirect to the full UTM URL. The code stays coarse, the tags still reach your analytics, and you can change where /flyer points later without reprinting. Most website builders and hosts let you add redirects without code.

Compared with dynamic-code scan statistics

Dynamic QR services count scans on their own redirect server before passing the visitor on. That records scans even when your page fails to load, and can include rough location and device. The cost is a subscription, and a code that stops working if the subscription or the service ends — see do QR codes expire?.

UTM-tagged static codes vs dynamic codes
FeatureStatic code with UTM tagsDynamic code
CostFreeUsually a subscription
What is countedVisits in your own analyticsScans on the provider’s server
Who holds the dataYouThe provider, then you
Change destination laterOnly via a redirect on your domainYes, in the provider’s dashboard
Keeps working if you stop payingYesOften not

For most flyers, menus, and posters, visit counts from your own analytics answer the real question — did this bring people in? Static vs dynamic QR codes covers the wider trade-off, and QR codes for flyers and posters covers placement. Codes made here are static and this site does not count scans; the tracking happens in your analytics.

Paste your tagged URL and download the code:Convert a URL to a QR code

Related questions

Not the scans themselves, but you can track the visits they produce. Add UTM parameters to the URL before generating the code, and your analytics will record each visit under the source and campaign you chose.

Tag the destination URL with utm_source, utm_medium, and utm_campaign, generate a static code from that URL, and read the results in Google Analytics or your existing analytics tool. No paid QR service is needed.

In Acquisition, under the Traffic acquisition report. Set the dimension to Session source / medium or Session campaign to see the values from your UTM tags.

No. The page ignores them and loads normally. They do make the URL longer, which makes the code denser, so check it still scans at the size you plan to print.

It measures something different: visits that reached your site, rather than scans. It misses visitors who block analytics, so treat the numbers as a minimum, but it costs nothing and the data stays with you.