What a QR code actually encodes
A QR code is just a bitmap. The black-and-white modules aren't a mystery — they're a specific binary encoding defined by ISO/IEC 18004 that any scanner reads back into whatever you put in. There's no server call, no API, no account — a QR code is literally a visual representation of the text it contains.
That means two things worth internalising:
- The data is in the image. If the image still exists, the data still exists. There's nothing to "go down" like a shortened URL service — as long as the PNG is scannable, it will still decode to the same text.
- Every QR code is editable by whoever controls the source. If you encode a URL, the page at that URL can change. The QR code is permanent, but what it points to isn't. This is the trap that makes "dynamic QR" services charge monthly fees — they sit a redirect in front of the URL.
What you can encode: plain text, URLs, Wi-Fi credentials (WIFI:T:WPA;S:NetworkName;P:password;;), vCards, email addresses (mailto:), phone numbers (tel:), SMS bodies, and GPS coordinates (geo:). Modern phone cameras recognise all of these and prompt the right action.
Error correction levels, in plain English
QR codes have four error-correction levels, each trading data capacity for damage tolerance. The letter is the level, the percentage is how much of the code can be missing or obscured and still decode correctly:
- L (Low, ~7%) — maximum data capacity, minimum damage tolerance. Use only for clean, digital display (on-screen, never printed).
- M (Medium, ~15%) — the sensible default. Good for most printed materials where nothing obstructs the code.
- Q (Quartile, ~25%) — for codes that will get dirty, scratched, or printed at small sizes. Business cards, sticker labels.
- H (High, ~30%) — maximum damage tolerance. Required if you're overlaying a logo in the middle of the code (the logo is the damage, and level H has enough redundancy to survive it).
The trade-off: higher correction means fewer usable bits for your payload. A level-H code holds roughly half as much data as a level-L code at the same physical size. For a URL of 30 characters this doesn't matter; for a 500-character vCard it might mean jumping to a larger QR version with more modules.
Print size and scan distance
The most common real-world failure mode isn't a technical one — it's a QR code that's too small to scan from where people actually stand. A rule of thumb that works for almost every use case:
Minimum side length = scan distance ÷ 10.
- Business card (scanned at ~20 cm) — 2 cm minimum side. 2.5 cm is safer.
- Restaurant table tent (scanned at ~40 cm) — 4 cm minimum.
- Retail poster (scanned at 2 m) — 20 cm minimum.
- Billboard (scanned at 20 m) — 2 m minimum. Yes, really.
Add a quiet zone — the empty margin around the code — of at least four modules (roughly 10% of the total side length). Scanners use the quiet zone to detect the code's edges. If you crop it out, the code becomes unreliable even when the data area is intact.
Colors and contrast
QR codes don't have to be black on white — but contrast matters far more than most people assume. Scanners treat the code as a 1-bit image: each module is either "dark" or "light", and the camera decides which based on local luminance. If the contrast is low, the decision gets noisy and the code fails to decode.
- The "dark" color must be genuinely dark. Yellow, light blue, and most pastels on white don't have enough luminance contrast to scan reliably. Measure contrast with a WCAG checker if you're unsure — 4.5:1 is the floor, 7:1 is safer.
- Inverted codes (light modules on a dark background) are risky. The QR spec doesn't require scanners to support them, and many older scanners refuse. If your brand is dark-on-dark, print the code in a light-colored box.
- Gradients break things. A dark-to-light gradient across the code means some modules cross the threshold at different points in the camera's view. Use solid colors.
- Transparent backgrounds are a trap. If you export a PNG with transparency and paste it over a photo, whatever shows through the "empty" modules becomes part of the code. Export with a solid background.
What not to encode
Because a QR code is public by definition, a short list of things never to put in one:
- Passwords or API keys. Anyone with a phone camera gets them.
- Personal information for someone who hasn't consented. Full names, phone numbers, addresses — fine for your own business card, not for third parties.
- Internal-only URLs. If a URL is on a poster, assume it's public. Intranet links and staging environments don't belong in a QR code.
- Trackable URLs without disclosure. You can redirect a QR code through an analytics service, but users have no way to inspect the URL before scanning it. Don't use that to surveil them without their knowledge.
One more: if the QR code is printed somewhere public and points to a URL you control, keep that page accessible. A dead link on a billboard lives forever.
Related tools on CodeBoxTools
- URL Parser — verify a URL before encoding it, especially one with long query strings.
- URL Encode / Decode — for percent-encoding special characters before they go into a URL QR.
- Slug Generator — turn a title into a clean URL slug to keep QR payloads short.
- Base64 — for encoded data URIs or basic-auth tokens.
- Color Converter — check your QR foreground/background contrast across HEX, RGB, and HSL.