# QR codes for product authentication — what works and what doesn't

> A shared QR code proves nothing, because counterfeiters copy it along with the artwork. Real authentication needs a unique code per unit checked against a server, ideally with scan-anomaly detection, or a cryptographically signed payload. Even then, a perfect copy of a genuine code still validates, so pair codes with physical tamper evidence.

Source: https://useqr.app/docs/ecommerce/qr-code-for-product-authentication · Last reviewed 2026-08-21 · UseQR is free forever, MIT licensed, no signup.

---

## The three tiers, honestly ranked

| Tier | How it works | What it actually proves |
|---|---|---|
| Shared static code | Every unit carries the same code linking to "this product is genuine" | Nothing — the counterfeiter photocopies it with the rest of the artwork |
| Unique code per unit | Each unit gets a serial; scanning checks it against your database | The serial exists and hasn't been seen suspiciously often |
| Signed payload | The code contains data plus a cryptographic signature your page verifies | The payload was issued by you and hasn't been altered |

The first tier is the one most brands ship, and it is security theatre. A static "scan to
verify" code costs a counterfeiter nothing to reproduce, and the reassuring page it opens
now vouches for the fake. If authentication is the goal, tier one is worse than nothing,
because it trains customers to trust a checkmark that anyone can print.

## Unique per-unit codes

The workable baseline is [serialisation](/docs/ecommerce/qr-code-for-serialized-products):
one code per unit, each containing an opaque serial —
`example.com/a/7f3k9q2m` — that your server looks up. Generate them with the
[bulk generator](/bulk) or, at manufacturing scale, `POST /api/v1/qr/batch`
(**up to 1,000 codes per request**, keyless).

What the server check adds is not "this code is real" but **statistics**. A genuine serial
scanned once in Lyon is normal. The same serial scanned 400 times across three continents
means the code was copied onto a production run of fakes, and now you know — which serial,
roughly where, and roughly when. Useful signals:

- **Scan-count anomalies** — a serial exceeding a plausible per-unit scan count.
- **Geographic spread** — one unit cannot be in Manila and Rotterdam in the same week.
- **First-scan claiming** — let the first scanner register ownership; later scanners see
  "this unit was already claimed on 3 March".
- **Void serials** — serials you never issued indicate a guessed or generated fake, which
  is why serials must be random and sparse, never sequential.

## The core weakness

State it plainly, because most vendor marketing will not: **a perfect copy of a genuine
code validates as genuine.** The counterfeiter buys one real unit, photographs its code,
and prints that code on 10,000 fakes. Your server sees a valid serial. Anomaly detection
catches this *eventually* and *statistically* — it flags the serial after the copies start
scanning — but the first customers to scan a fake see the authentic page.

Mitigations that raise the cost:

- **Tamper-evident placement** — the code under a scratch layer or inside the seal, so
  reading it means the unit was opened; see
  [tamper-evident QR labels](/docs/security/tamper-evident-qr-labels).
- **Signed payloads** — a signature stops *forged* serials cold, though not *copied* ones;
  the mechanics are on [signed QR codes](/docs/security/signed-qr-codes-and-authenticity).
- **Physical pairing** — match the code to an overt feature (hologram, engraving) the
  copier must also reproduce.

## Practical build notes

Serve the verification page from a domain you will keep for the product's lifetime — the
same [permanence rule as packaging generally](/docs/ecommerce/qr-codes-on-product-packaging).
Print at **error correction Q**, at least **2 × 2 cm**, and
[verify a sample decodes](/validate) from the final printed label, not the screen proof.
Keep the payload short: an opaque serial in a URL, everything else server-side, so the
code stays low-density and the data model can evolve without reprinting.

If your genuine concern is grey-market diversion rather than counterfeiting, the same
per-unit infrastructure answers "where is this unit surfacing" — that is often the more
realistic win.

## FAQ

### Can a QR code prove a product is genuine?
Not by itself. A shared code proves nothing, since counterfeiters copy it with the artwork. Unique per-unit codes checked against a server prove the serial exists and let you detect copying statistically, but a perfect copy of one genuine code still validates.

### How do counterfeiters defeat authentication QR codes?
They copy a genuine unit's code onto many fakes. The server sees a valid serial, so detection relies on anomalies — one serial scanned hundreds of times or in implausible locations. Scratch-off layers and first-scan claiming raise the cost of this attack.

### What should an authentication QR code contain?
An opaque, randomly generated serial inside a URL on your own domain, for example example.com/a/7f3k9q2m. Keep all product data server-side. Random sparse serials stop attackers guessing valid ones; sequential serials hand them the whole namespace.

### Is a signed QR code better than a server check?
They solve different problems. A signature proves the payload was issued by you and stops forged serials even offline. It cannot stop copying of a genuine code. Serious schemes combine signatures, server-side anomaly detection and physical tamper evidence.

## Try it

- https://useqr.app/url
- https://useqr.app/bulk
- https://useqr.app/validate
