Provable privacy - don't take our word for it
Every QR generator says "we respect your privacy." That sentence is unverifiable marketing. This page shows you how to verify ours in your own browser, in under a minute.
The architecture
QR Code Zebra is a static website. There is no application server, no API, and no database. When you open a tool page, your browser downloads HTML, CSS, and JavaScript - and from that point on, QR generation runs entirely on your device using the Canvas and SVG capabilities built into your browser.
Your WiFi password, contact details, wallet address, or any other content you type is never transmitted, because there is nothing to transmit it to. This is a structural property, not a policy: we could not collect your data even if we wanted to.
Verify it yourself (60 seconds)
- Open any tool, e.g. the WiFi QR generator.
- Open your browser's developer tools (F12 or Cmd+Option+I) and switch to the Network tab.
- Clear the network log, then type your WiFi details and generate the code.
- Watch the network log while you type and adjust colors: zero requests. Your data stayed on your device the entire time.
- Download the PNG. You'll now see exactly one request:
POST /api/count. That's the anonymous download counter described below - open it in DevTools and you'll see its full body is{"event":"download_png","n":1}. No WiFi password, no contact details, no wallet address - because none of that ever left your device to begin with. There is nothing in the request for it to be.
Enforced by the browser, not by trust
We serve a Content-Security-Policy header that instructs your browser to refuse outbound connections to anything except this site. Even if our code were compromised, the browser itself would block an attempt to send your data elsewhere:
default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https://*.tile.openstreetmap.org https://unpkg.com; connect-src 'self'; font-src 'self' data:; object-src 'none'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'
connect-src 'self' is the load-bearing directive: scripts on this page cannot make network requests to any third-party origin. You can confirm the header with curl -I https://qrcodezebra.com/.
Honest exceptions
A claim is only provable if its exceptions are listed:
- The location tool loads map tiles. The map-based location picker fetches map imagery from OpenStreetMap's tile servers and marker icons from unpkg.com - that's what the two extra
img-srcentries above allow. The tile server sees which map area you viewed (as it does for any map site); the coordinates you encode into the QR are still processed only on your device. - Standard hosting logs exist. The static files are served by Cloudflare, which (like any host) processes requests at the network level. What it never receives is the content you type into the tools - that content produces no requests.
- Some designers remember your last design. The business card designer (and, over time, more tools) autosaves what you type to your browser's
localStorage- on your device only, never sent anywhere - so closing the tab doesn't lose your work. The "Copy link to this design" button encodes the same design into the URL fragment (the part after#), which browsers never send to a server either - that's what makes a share link work without an account or a database. Uploaded logos stay inlocalStorageonly; they are never included in a share link.
The one exception: an anonymous download counter. When you download a QR code, your browser sends a same-origin request - POST /api/count - with a body of exactly two fields: which kind of download it was (download_png, download_svg, or bulk_download) and, for bulk downloads, how many codes were in the batch. That's the entire payload. The request carries no IP logging we read, no cookies, no user agent fingerprinting, no URL parameters, and nothing you typed into any tool - the counter has no field to put that in even if it wanted to. This is how we can honestly say "X codes generated" without tracking who generated them.
Don't want to be counted, even anonymously? Block requests to /api/count in your browser or an extension, or run this in your browser console once per device: localStorage.setItem('qrz-no-count', '1'). Either way, every tool keeps working exactly the same - downloads never wait on this request, and nothing checks whether it succeeded.
What this means for your codes
- Codes never expire - they encode your destination directly, with no redirect service that could shut down or start charging.
- No scan tracking - nobody (including us) sees who scans your codes, ever.
- No account to breach - we can't leak data we never had.
Questions about this page? Contact us. See also the privacy policy.