Back to blog
Research-backed growth article

How to Track QR Code Scans with Analytics

Most QR codes are blind — they send people to a URL and capture nothing. This guide covers how dynamic QR codes, UTM parameters, and GA4 combine to give you full scan analytics including device, location, and conversion data.

Rabi Narayan PradhanProduct & Growth Research12 min read
Why readers save this article
130M+ QR code scans happen every month globally — yet most marketers can't see a single one in their analytics.
Static QR codes encode a URL directly — there is no server in the middle, so zero scan data is captured.
Dynamic QR codes route every scan through a redirect server, capturing device type, OS, city, country, and timestamp before forwarding.
GA4 cannot detect QR traffic on its own. UTM parameters are the only way to separate QR scans from Direct traffic.
The correct UTM structure for QR codes: utm_source=qr_code, utm_medium=print (or 'offline'), utm_campaign=name_YYMMDD.
The best workflow: tag the destination URL with UTMs, shorten it with a dynamic link tool, then generate the QR code from the short link.
Two-layer attribution gives you both platform scan data (volume, device, geo) and GA4 conversion data (behavior, goals, revenue) from the same scan.

QR code usage has grown 211.5% since 2024. Over 130 million people scan QR codes every month worldwide, and 102.6 million US smartphone users will scan at least one QR code in 2026. Eighty-six percent of marketers say they are increasing QR usage in campaigns.

Despite this surge, most QR codes are analytically invisible. They land traffic in the Direct bucket of GA4 — indistinguishable from someone who typed your URL. You have no idea which placement drove the scan, which city it came from, or what device was used.

This guide covers exactly how to fix that: which QR code type captures scan data, how UTM parameters bridge QR analytics to GA4, and the step-by-step workflow that makes every future scan fully attributed.

Can you actually track who scans a QR code?

Not by identity — QR codes do not know who the person is. There is no login, no cookie, and no fingerprint collected at the point of scan. What a tracking-enabled QR code does capture is behavioral and contextual: how many times it was scanned, when, from which device type and operating system, and which city and country the scan came from.

For most marketing use cases, this is more than enough. You can answer whether your conference booth QR got more scans in the morning or afternoon, whether iPhone or Android users dominate your audience, and whether the QR on page 3 of the brochure outperformed the one on the back cover.

The catch is that this data is only available from dynamic QR codes routed through a redirect server. Static QR codes — the most common type — produce no data at all.

Why static QR codes produce zero scan data

A static QR code is a visual encoding of a URL. The entire destination address is baked into the black-and-white pattern at the time of creation. When someone scans it, their phone reads the pattern, extracts the URL, and opens it directly. Nothing contacts your server until the destination page loads.

Because there is no intermediary, there is no moment where scan metadata can be captured. The QR code generator has no idea a scan happened. GA4 sees the session come in, but it has no referrer information — so it classifies the visit as Direct.

This is why printing a QR code that points straight to your homepage, product page, or PDF is analytically useless. The traffic reaches you but cannot be attributed to the QR placement, the campaign, or even the channel.

Static QR codes cannot be changed after printing. If you need to update the destination — say the landing page URL changes — you must reprint the physical material with a new code.

No server request at scan time — device reads the URL from the pattern and opens it directly.
No referrer sent to the destination — GA4 sees Direct traffic with no campaign context.
Cannot be edited after creation — destination URL is permanently encoded.
Still useful for non-marketing uses: Wi-Fi passwords, vCards, app store deep links where tracking is not the goal.

How dynamic QR code tracking works behind the scenes

A dynamic QR code encodes a short redirect URL — typically something like lnk.bio/abc123 or link.example.com/s/abc. The actual destination is stored in a database on the link platform, not in the QR pattern itself.

When a phone scans the code, it contacts the redirect server. At that moment — before the forwarding happens — the server captures the HTTP request metadata: the IP address (converted to approximate city and country), the User-Agent header (device type, OS, browser), and the timestamp.

The server logs the scan event, then issues a 301 or 302 redirect to the real destination URL. From the user's perspective this is instant. From your analytics perspective, every scan is now a logged event with device, location, and time data.

Because the destination is stored in the database, you can change it at any time without reprinting. The QR pattern stays the same — only the forwarding target changes. This is why dynamic QR codes are standard for any printed material that may need updating.

Scan contacts redirect server first — HTTP metadata captured before forwarding.
IP-to-geo lookup converts the scanner's IP to approximate city and country.
User-Agent parsing identifies device type (mobile/desktop/tablet), OS (iOS/Android), and browser.
Destination URL is editable at any time — the QR pattern never needs to change.
Unique scan counting uses IP + User-Agent + time window to deduplicate repeat scans from the same device.

The two-layer tracking approach: platform data plus GA4

Dynamic QR platforms give you scan-level data: total scans, unique scanners, device breakdown, geographic heat map, and scan-over-time chart. This is the first layer of attribution. It tells you how the QR code performed as a physical touchpoint.

The second layer — what happened after the scan — requires UTM parameters. When you append UTMs to your destination URL before generating the QR code, GA4 picks them up on arrival and ties the session to your campaign. This is the only way to see whether QR scanners converted, how long they stayed, and which revenue or goal events they triggered.

Without UTMs, GA4 still receives the traffic. It just files it under Direct / (none) because QR scans do not pass a referrer header. Direct traffic hides your QR attribution inside the same bucket as bookmark clicks and dark social visits.

The two layers are complementary, not redundant. Platform scan data tells you scan volume and audience profile. GA4 tells you what those people did after landing. You need both to run QR code campaigns intelligently.

The right UTM structure for QR code campaigns

UTM parameters are appended to your destination URL as query string values. GA4 reads them on arrival and attributes the session accordingly. For QR codes used in physical and offline contexts, the conventions differ slightly from digital campaign UTMs.

Use utm_source=qr_code to identify the traffic source. This is a clear, searchable value that immediately distinguishes QR scans from web, email, or paid traffic in GA4 reports. Some teams use the placement name as the source instead, but this makes it harder to filter all QR traffic in aggregate.

Use utm_medium=print for physical materials — posters, flyers, packaging, business cards, event banners. Use utm_medium=offline for non-print physical contexts like screen-displayed QR codes at events. Avoid utm_medium=qr — GA4 groups mediums into channel definitions, and an unrecognised medium will land in Unassigned rather than a meaningful channel bucket.

Use utm_campaign to identify the specific initiative and include a date suffix in YYMMDD format so you can filter by date range in reports. Example: utm_campaign=spring_sale_260515. If running multiple QR placements for the same campaign, add utm_content to distinguish them: utm_content=window_decal vs utm_content=receipt_print.

utm_source=qr_code — identifies the channel; consistent across all QR campaigns.
utm_medium=print — for physical printed materials (poster, flyer, packaging, business card).
utm_medium=offline — for non-print physical contexts (event screen, digital display, TV).
utm_campaign=initiative_name_YYMMDD — campaign plus date suffix for time-based filtering.
utm_content=placement_description — optional; differentiates multiple QR codes in the same campaign.
Full example: https://linklab.in/landing?utm_source=qr_code&utm_medium=print&utm_campaign=product_launch_260520&utm_content=packaging_insert

Step-by-step: building a fully trackable QR code

The workflow has four steps. Each step is simple but the order matters — skipping or reordering them is the most common source of untracked QR traffic.

Step 1: Build your tagged destination URL. Start with the page you want to send scanners to. Append UTM parameters using a UTM builder or manually. Double-check that utm_source and utm_medium are lowercase with underscores — GA4 is case-sensitive and mixed-case values create duplicate channel rows in reports.

Step 2: Shorten the tagged URL with a dynamic link tool. Paste the full UTM-tagged URL into LinkLab or your preferred dynamic link platform. The shortener creates a redirect at a clean short URL. This is the URL that will be encoded into the QR pattern. Do not skip this step — encoding a long UTM-tagged URL directly creates a dense, error-prone QR pattern that fails in low-light conditions and at small print sizes.

Step 3: Generate the QR code from the short link. Use your link platform's built-in QR generator so the scan event is logged to the same analytics dashboard as the link click data. Download at the highest available resolution — SVG is ideal for print, PNG at 1000px or larger for digital.

Step 4: Test before printing. Scan the QR code with two devices — one iOS, one Android — and confirm the correct page loads. Then open GA4 and verify the session appears under the correct campaign in the Traffic Acquisition report. Only print after both checks pass.

What the scan data actually tells you

Scan volume over time shows whether a placement is still active and performing. A poster that drove scans for three days and then stopped may have been covered, damaged, or removed. A steady drip of scans from old packaging suggests ongoing product usage.

Device and OS breakdown tells you what your offline audience looks like on mobile. If 70% of scans come from iOS users, your landing page mobile experience should be optimised for Safari. If a surprising share comes from Android, check that your page renders correctly on Chrome for Android.

Geographic data validates whether your physical distribution matched your intended audience. A restaurant placing QR codes on takeaway bags can see whether scans come from the local area or from further afield — which would suggest the bags are being shared or distributed beyond expected range.

GA4 post-scan behaviour shows what QR scanners do after arriving. Compare the conversion rate, session duration, and pages-per-session of qr_code / print traffic against your other channels. In most cases QR traffic has higher intent than social traffic — people who scan a physical code are actively interested. If conversion rates are low, the landing page is likely the problem, not the QR placement.

Unique vs total scans helps distinguish reach from engagement. A campaign with 1,000 total scans and 950 unique scans has broad reach. A campaign with 1,000 total scans and 200 unique scans has a small but highly engaged group scanning repeatedly — common for QR codes placed at fixed locations like store counters or transit stops.

Frequently asked questions

Start in under 60 seconds

Your URL shortener should do more than shorten
better links, QR codes, and analytics

Join teams using LinkLab to shorten URLs, create branded links, track campaign clicks, manage custom domains, and scale link workflows without switching platforms.

No credit card required
Free forever plan
5-minute setup