Guide

Dynamic QR codes: an editable destination and a scan count

A dynamic QR code holds a short link instead of your content, so you can change where it points after it has been printed — and count how many times it was scanned. That flexibility is real, and so is what it costs. This page covers both, so you can decide before the ink is dry.

Last updated

What a dynamic QR code is

Every QR code is a container for data. In a static code that data is your content — the URL itself, the Wi-Fi credentials, the contact details. The pattern is the destination.

A dynamic code puts something else in the pattern: a short address on a server we run. When someone scans it, their phone asks that address what to do, and the server answers with a redirect to your real destination. The code never changes. The answer does.

That single indirection is the whole idea, and everything a dynamic code can do — editability, scan counts, switching a campaign off — follows from it. So does everything it cannot do, which is mostly to work without us.

How the redirect works

A dynamic code from this site encodes an address of the form /r/<slug>, where the slug is eight characters drawn from a 31-symbol alphabet. Here is the path a scan takes:

How a dynamic QR code redirects a scan The printed code holds a short link on this domain. That link is looked up on our server and answered with a redirect to your current destination, so the destination can be changed without reprinting. Printed QR code the artwork never changes …/r/7k2mp9q the only thing on the paper this lookup is what you can edit Your destination changeable at any time
The scan is answered by our server rather than by the pattern itself. That is what makes the destination editable — and what makes the code depend on the redirect resolving.

Two details in that picture matter more than they look. First, the only thing printed is the short link, so the destination can be rewritten at any time without touching the artwork. Second, that rewritten answer is served with Cache-Control: no-store, so a browser or intermediary cannot cache yesterday's destination and send a scanner somewhere you have since changed.

Slugs avoid characters that are easy to confuse when read aloud or copied by hand — no 0, O, 1, l or I — and words that could be mistaken for a system path, such as api or login, are held back.

What you can change, and what you cannot

You can change the destination as often as you like. Editing is free and unlimited — it is the feature you came for, so metering it would be perverse. You can also pause a code so it stops redirecting, give it an expiry date, and see its scan history.

What you cannot do is equally worth knowing up front:

Making a link stop working on a date

By default a dynamic code has no expiry and keeps redirecting indefinitely. When you create one through the generator you can optionally set an expiry date, up to ten years out. After that moment the link stops resolving and answers 410 Gone, and it cannot be un-expired by editing the destination — the expiry is its own state, not a property of where it points.

There are two honest reasons to set one:

Do not set an expiry to feel tidy. A permanent destination with an arbitrary expiry date is a code that will one day stop working for no reason a future reader can reconstruct — and because slugs are never reused, the only fix is a reprint. If you are unsure, leave it off; you can always pause the link later, and pausing is reversible where expiry is not.

A past date is refused at creation rather than silently accepted, because a link that was born expired would look like a bug rather than a decision.

Routing by device

A dynamic link can send different scanners to different places. You add rules, and each rule names a device class and a destination:

Rule Sent to The obvious use
iOS The App Store listing iPhone and iPad visitors get the native app
Android The Play Store listing Android visitors get the same app from their store
Desktop Your website A laptop cannot install a phone app, so send it somewhere useful

This is the thing a static code structurally cannot do. One printed code, three destinations, decided when the scan happens — which is exactly what an app launch needs and what the app store type cannot express on its own.

Three properties are worth knowing, because they are choices rather than side effects:

Rules are edited on the dynamic links page. Changing a rule takes effect on the next scan; nothing about the printed code changes.

Tagging scans for your analytics

A dynamic link already knows it was reached by scanning a code. Campaign tags pass that knowledge on to your own analytics, so you can separate QR traffic from every other route to the same page — utm_source, utm_medium and utm_campaign are appended to the destination on the way through.

The rules for this are deliberately conservative:

These tags describe the campaign, not the person. They carry nothing about who scanned, and they are the same parameters any other marketing link would use.

When a dynamic code is the right choice

The honest answer is: less often than marketing suggests. A dynamic code is worth its dependency when at least one of these is true.

The destination is not final

A menu that changes monthly, a schedule, a landing page you have not built yet. Print once, edit forever.

You are printing a lot of something

Packaging, signage, vehicle livery. The cost of a reprint is the reason the indirection pays for itself.

You need to count scans

Measuring which poster or which shelf actually gets scanned is a legitimate reason, and impossible with a static code.

You may need to switch it off

A promotion with an end date, or something you might have to withdraw. A static code cannot be recalled.

Do not use one for a permanent destination you control: a homepage, a contact page, a Wi-Fi password. You would be adding a dependency in exchange for nothing. The generator produces a static code by default for exactly this reason, and the toggle that changes that is opt-in.

What the scan analytics actually measure

A dynamic code can be counted because every scan makes a request. A static code cannot be counted by anyone, because nothing is ever requested. This is a property of the mechanism, not a setting — so any tool claiming scan counts for a code that encodes its content directly is either using a redirect or guessing.

What you see What it means
Total scans Every redirect served, including repeat scans by the same person.
Unique visitor-days The number of distinct visitor/day pairs — one person scanning on three days counts three times, three people scanning the same day count once. It is the honest unit for data that is deliberately not tied to a person.
Scans over time A per-day series, kept as a permanent rollup.
Device family Mobile, tablet or desktop. Not a model, not a browser version.
Operating system iOS, Android, Windows, macOS or other — the coarse split that tells a phone from a laptop.
Country A two-letter country code, supplied by our network. Not a city, not a coordinate, and shown only where the deployment can supply one.
Referrer host The site that sent the scanner, as a hostname only.

Bot traffic is recorded so it can be excluded: crawlers are counted internally but never added to the number a person reads, and an empty user-agent is treated as a bot because that is far more often a script than a human.

What we deliberately do not store

Scan analytics is where QR services usually collect far more than they need, so it is worth being specific about the limits here.

Raw scan rows are pruned after 90 days. The daily totals are written as scans arrive and kept, so a chart of last year still works even though the individual rows behind it are gone. You can also hide the Visits column entirely, which is remembered per browser — useful if you are showing the dashboard to someone else. The Privacy Policy covers this in full.

Printing an editable code

A dynamic code has more data in it than the URL it stands for is short, so it is denser than you might expect. Everything in the QR code guide applies, with three additions.

  1. Settle the short link before you print. The printed address is the one thing you cannot edit, so plan it as carefully as you would a domain name.
  2. Give it more room than a static code. A denser pattern means smaller modules at the same printed size. When in doubt, go up a size — the size calculator will do the arithmetic for the distance you have in mind.
  3. Test the redirect, not just the scan. Confirm the code reaches the right page after you change the destination, on a phone that has never seen the site before.

What happens if a code stops working

This is the part a static code never makes you think about, so it deserves a straight answer. A dynamic code works only while the redirect service answers.

That is the trade in one sentence. If the thought of it is unacceptable for a given code, use a static one — the destination may be fixed forever, but so is the code's ability to work.

How destinations are vetted

A redirect service is an open redirect unless it is constrained, and an open redirect on a well-known domain is a phishing tool. Every destination is therefore checked when it is created and again whenever it is edited — at the point where a mistake can still be reported to a person rather than discovered by a victim.

The redirect also sends Referrer-Policy: no-referrer, so your short link does not turn up in the destination site's logs along with every visitor who arrived through it.

Dynamic vs static, side by side

Static Dynamic
What is printed Your content, encoded directly A short link to our redirect
Edit the destination No — reprint required Yes, as often as you like
Scan counts Impossible for anyone Scans, visitor-days, device, operating system, country, referrer host
Route by device Not possible — one address iOS, Android and desktop can each go somewhere different
Works offline Yes No
Depends on a service No Yes — us
Account needed No Yes
Cost here Free, three without an account Counts against the same allowance; editing is free

To create one, use the generator, choose a website link and turn on “Make this link editable after printing”. Codes you have made are managed, edited and measured on the dynamic links page.

Frequently asked questions

Can I change where a QR code points after printing it?

Only if it is a dynamic code. A static code has its destination encoded in the pattern, so changing where it points means printing a new code. A dynamic code holds a short link, so the destination behind it can be rewritten at any time without touching the printed artwork.

Do dynamic QR codes expire?

Not by default. A dynamic code keeps redirecting for as long as the service resolves it, and editing the destination is free for that whole time. You can optionally set an expiry date when you create one — up to ten years out — after which it stops working and answers 410 Gone. Either way it depends on the redirect service staying online, which is the risk a static code does not carry.

Can a static QR code track scans?

No, and it is worth being sceptical of anything that claims otherwise. A static code contains its content, so a scan is decoded by the phone and never contacts a server. There is no request to count. Scan tracking requires a redirect, which means a dynamic code.

What do you store about the people who scan my code?

A salted one-way hash of the IP address, the referring hostname, a coarse device family, and whether the request looked like a bot. No IP addresses, no full referrer URLs, no user-agent strings, and no way to identify a person. Raw rows are deleted after 90 days; daily totals are kept.

What is a "unique visitor-day"?

One distinct combination of visitor and calendar day. One person scanning on three separate days counts as three; three people scanning on the same day counts as one. It is a deliberate compromise: telling unique people apart would require holding a per-person identifier over all history, and this measurement is not worth that.

Why does a deleted dynamic code return 410 and not 404?

Because the address was real. 410 Gone tells a browser and a search engine that the link existed and has been retired permanently, where 404 suggests a typo. Slugs are never reused, so a retired link can never be pointed somewhere new.

Can I use a dynamic code for free?

Creating one requires an account, and it counts against the same free allowance as any other code. Editing the destination afterwards is free and unlimited, because editing is the feature. See the Terms of Service for the current limits.

Can one QR code send iPhone and Android users to different places?

Yes, with a dynamic link and device rules. You can send iOS to the App Store, Android to Google Play and everything else to a web page, all from the same printed code. A static code cannot do this — it carries one address, so every scanner goes to the same place. Rules are set on the dynamic links page and can be changed at any time without reprinting.

What happens if no device rule matches a scan?

The scan goes to your primary destination. That is deliberate: a printed code cannot be recalled, so a redirect that fails would leave the visitor with nothing. An unrecognised device, an old browser, a crawler and an empty user-agent all fall back to the primary destination rather than showing an error.

Can I add campaign tags to a dynamic link?

Yes. utm_source, utm_medium and utm_campaign can be appended automatically, so your own analytics can tell QR traffic apart from other routes to the same page. If the destination already carries a tag you set yourself, yours is kept and nothing is duplicated.

Should I use dynamic or static for a business card?

Static. A business card points at something you control and expect to keep, and a card is cheap to reprint. The dependency of a dynamic code buys you nothing there. Use dynamic for the cases where the destination genuinely may change or the print run is expensive.

Make an editable code

Choose a website link in the generator and switch on “Make this link editable after printing”. You can rewrite the destination whenever you need to.

Open the QR code generator