Baby Reveal QR Code
The announcement travels inside the code, in one of two forms, and this page measures the cost of each. An offline note writes the words straight into the modules and needs no connection — but bare text carries no scheme, so an iPhone offers to copy or search it and Google Lens runs a web search rather than showing it. A reveal link carries the words in the fragment of a URL to this site, which is never sent to a server, and needs a connection when scanned; the generator opens on it. The confetti frame does the celebrating; your browser proves the code scans before you print a single copy.
Keepsake print checklist
- Keep the white margin around the code — it is the quiet zone scanners need, not empty space to crop.
- Size for the moment: 2 × 2 cm of code is the floor for cards and tags; photo-woven codes reward 4 cm or more; distant reveals want one tenth of the scanning distance.
- Matte paper over gloss — glare is the most common keepsake scan failure.
- Scan a test print with a real phone before the moment that matters.
A worked example, rendered by the real engine
Built when this page was built, by the same engine as the tool above — confetti frame, untouched code panel, and the announcement itself inside the modules. Scan it from the screen (no internet needed) and it says:
It's a girl! Welcome, baby Quinn - arriving this October.
Version 6 at 41×41 modules, error correction H — decoded directly from the artwork.
What the baby-reveal preset encodes
Read first: the guide Message keepsakes and reveal links explains the two ways a message can travel inside a code and what a phone does with each. This page applies those rules to one preset — the Baby reveal occasion — with every number computed by the engine when the page was built. The other guides are collected at /guides/.
Choosing Baby reveal in the generator preconfigures three things from the occasion registry: the style (Confetti frame), the payload type (a hidden message, rather than a link or a contact card), and the caption placeholder (“Scan when we say go!”). The frame's primary colour starts at #be123c and the heart-module toggle starts off. All of it stays editable; the preset only sets where you begin.
The worked example above is the preset's own fictional message: 57 characters of plain text, encoded exactly as typed. For that payload the engine chose version 6 — a 41×41 symbol with 810 dark modules among its 1681 cells — and with the 4-module quiet zone drawn on every side the symbol is 49 modules across. Error correction is H, as it is for every artistic example on this site.
Of those 1681 cells, 147 belong to the three finder patterns and 25 to the one alignment pattern the engine draws for version 6, centred at row 34, column 34 — its coordinate list for this version is 6 and 34, and the three corners that hold finders are skipped. 54 are timing cells, and the remaining 1455 are the data region as the engine's styling classifier counts it: every cell that is not a landmark or a timing track. The methodology's anatomy rule applies to this preset exactly as to every other: the 172 landmark cells are always drawn as classic, crisp squares, because restyling alignment patterns broke decoding in testing. Timing cells may be styled; landmarks may not.
Why the confetti frame cannot touch the code
Framed codes are the safest style by construction, and this preset starts on one. The rendered QR is nested verbatim — byte for byte — on an opaque white panel drawn above the frame art, so decoration cannot reach a module even in principle. In the composite the engine returns for this example, the frame measures 760 × 880 units and the code panel is a 460-unit square; the confetti is a fixed scatter of dots, squares and triangles kept inside the margins and never placed under the panel. Recolouring the frame — the preset's #be123c, or any other hex colour — changes the art and the caption only. The modules themselves stay black on white, which the engine measures at 21.00:1.
The quiet zone belongs to the symbol, not to the frame. The 4 clear modules around the code are drawn inside the panel, and frame art is never allowed to cover them.
A caption is set under the panel in the frame colour and wrapped to at most 4 lines; the example's reads “Scan when we say go!”. The methodology notes that a message keepsake also carries its words in ink, and on a framed keepsake that ink is the caption: with no caption of your own, the generator sets the message itself under the code as the caption, cut to 200 characters — the message as you typed it, even for an inscription, whose code carries the folded form — so it can be read by eye. A caption you type takes that place instead, as the worked example's prompt does: its ink asks for a scan and the modules hold the news.
Within the confetti frame, the one way to restyle modules is the heart-module toggle. Switch it on and every dark data and timing module is redrawn as a heart spanning 0.97 of its cell — large enough that a scanner's sampling grid still reads the cell as decisively dark — while the 172 landmark cells stay square. With hearts comes the colour gate: foreground on background must measure at least 4.5:1 by the WCAG formula, and the engine rejects a weaker pair rather than warning, because scanners binarise the image and low contrast measurably hurts decoding. Inside a frame the toggle offers no colour picker: it calls the heart renderer with no colour of its own, so the hearts take the engine's default, which the render built here used as #881337 at 9.57:1 on the white panel — the same deep rose this preset carries as its heart colour. The picker, and with it the gate's refusals, belongs to the bare heart-module style; the figures that follow demonstrate the gate as an engine rule, not a choice this preset's toggle puts in front of you. The preset's own deep rose, #881337, measures 9.57:1 on the white panel and passes. A pastel such as #f9a8d4, chosen for this page as an example of a soft shade, measures 1.81:1 — and the engine's answer, computed here, is: “Artistic styles require at least 4.5:1 contrast (got 1.81:1) — decoration already spends decode margin.”
Offline note or reveal link: what the phone will do
A QR code containing bare text carries no scheme, so a phone has nothing to act on. Apple's Camera and Google's ML Kit both recognise links, phone numbers, email addresses, contact cards, calendar events and Wi-Fi joins — and no plain-text type. Faced with bare text, an iPhone offers to copy or search it and Google Lens simply runs a web search, so the message is the one thing the reader never sees. Samsung phones and dedicated scanner apps do display it, but a keepsake cannot depend on which phone opens it. This is the whole reason a message can travel in two ways rather than one. The generator's third choice, the inscription, is not a third way: it is an offline note folded into the QR alphanumeric set — uppercase, accents flattened — a capacity feature that carries the same display caveat, covered in the message keepsakes guide.
An offline note writes the words into the code itself. The worked example is one: its payload is the 57-character message, nothing more, which is why it needs no connection and why it fits in a version-6 symbol. It accepts the display caveat above. On a framed keepsake with no caption of your own, the generator prints the message itself under the code as the caption — the message as you typed it, even for an inscription — so it can be read by eye; a caption you type, as the worked example's prompt is, takes that place instead.
A reveal link encodes a normal URL to this site's reveal page at
/m/, with the message carried in the URL's fragment — the part after the
#. Per RFC 3986 a fragment is stripped before a request is made, so it never
reaches our servers, a CDN or any log; the message is decoded entirely on the reader's device.
The same fictional message as a reveal link, built by the engine for this page, is:
https://KEEPSAKECODES.NET/M/#AJF2CO4ZAMEQGO2LSNQQSAV3FNRRW63LFFQQGEYLCPEQFC5LJNZXCALJAMFZHE2LWNFXGOIDUNBUXGICPMN2G6YTFOIXAC
That is 123 characters, of which the fragment is 94: a flag character A (A marks a payload of UTF-8 bytes; B marks raw-deflate compressed bytes), then 92 characters of unpadded uppercase base32 (RFC 4648), then one base32 checksum character — here C — computed over the payload, so a link that a scanner truncated or altered is reported rather than rendered as gibberish. The flag is A because the engine was called as the generator calls it — with no compressor — so the payload is the message's 57 UTF-8 bytes spelled in base32 as they are. Flag B is the other half of the published format: the encoder accepts a raw-deflate compressor as an optional argument and, given one, encodes both ways and keeps whichever base32 payload is shorter. Handed Node's raw deflate when this page was built, the same message went from 57 bytes to 59, no saving at all, so the engine kept the raw form even then — compression reliably loses on short messages, where the deflate header and table cost more than the redundancy they remove. The generators on this site do not pass a compressor today, so every reveal link they produce carries flag A; the reveal page parses either flag. Base32 is used instead of base64 because some scanners change the case of what they read and base32 survives that; its alphabet is also a subset of the QR alphanumeric character set, which encodes at 5.5 bits per character instead of 8. The format is published so the codes stay readable by anyone, with or without this site.
The two modes do not cost the same. The reveal-link form of this message encodes at version 11, a 61×61 symbol that is 69 modules across with its quiet zone, against the offline note's 49. The engine's comfortable limit for a printed keepsake is 65 modules, so this message is within that limit as an offline note and over it as a reveal link. The difference is the host and path every reveal link carries before the message, plus the extra characters base32 spends on the message itself.
Measured on this engine, called as the generator calls it at its default level H, with one repeated lowercase letter: an offline note stays within the comfortable limit up to 119 characters, and a reveal link — flag A, no compressor — up to 55. One setting moves every figure in this section: the generator's framed-only opt-in, “Smaller code (less error correction)”, encodes at Q instead, which the engine permits only because a frame leaves the symbol untouched — hearts and the photo halftone still refuse anything below H — and a render at either level must still pass decode verification before download. At Q the worked example encodes at version 5, 45 modules across with its quiet zone and 22.5 mm at minimum, against version 6, 49 across and 24.5 mm at H; its reveal link encodes at version 9, 61 across and 30.5 mm, against version 11, 69 across and 34.5 mm; and the repeated-letter budgets become 151 characters as an offline note and 75 as a reveal link. Without a compressor the fragment's length depends on the message's byte count alone, not on what the bytes say, so the shape of the message should not move that figure. This fictional announcement, written for this page, was measured prefix by prefix through the same path to check:
A small person is on the way and will arrive in the spring. We have a name picked out and a room half painted, and the grandparents are sworn to silence until this card is scanned at the table.
The longest prefix of it that still fits the comfortable limit as a reveal link is 55 characters — the same figure as the repeated letter. A reveal message is refused above 300 characters outright, in either form. Accented characters and emoji take several UTF-8 bytes each and shorten the reveal-link figures. Nothing stops a longer message encoding; the symbol grows a version at a time, and the minimum print size grows with it.
The published format's flag B would move those reveal-link figures, and the engine can measure by how much, but the generators on this site pass no compressor today, so what follows describes the format's reach and not the tool's. A repeated letter is pure redundancy, which is what deflate removes: with a compressor supplied when this page was built, the comfortable limit was never crossed before the 300-character refusal, while the longest prefix of the prose run that fit was 58 characters against 55 without. The gap between those two prose figures is the compressor's whole effect on ordinary sentences, measured here.
One more difference matters for a keepsake: a reveal link works for as long as this site answers, while an offline note needs nothing but a scanner. That is why every message keepsake can additionally be downloaded as a self-contained HTML file that decodes the fragment format above with no network and no website at all.
What “Verified scannable” proves on a reveal card — and what it cannot
After each render your browser rasterises the finished artwork — frame, confetti, caption and code — and runs a real decoder (jsQR) on the pixels at 3 raster sizes (800, 1200, 1600 px), comparing the decoded bytes with your exact content. The badge is earned when at least 2 of the 3 rasters decode to an exact byte match. The rule is 2-of-3 rather than all-or-nothing because a render can fail at exactly one raster size through sampling resonance and decode cleanly at the others — a measured effect, which is why no single raster is allowed to flip the verdict on its own. A render that decodes to different content is never verified, and anything short of the badge keeps the downloads locked.
For a reveal card, then, verification proves one precise thing: this artwork, at screen resolution, decodes back to exactly these words (offline note) or exactly this URL (reveal link). It does not prove the message will be shown — that is the dispatch question above, and it belongs to the phone, not the code. It cannot see your printer, your paper, or the phone that will do the scanning. And it proves nothing about secrecy: a QR code hides nothing from a camera, only from eyes.
What it does guarantee about privacy is structural. The message is encoded, drawn and verified entirely in your browser; nothing is uploaded, logged or stored, and in reveal-link mode the fragment rule means the words never reach a server even when the card is scanned.
Printing and testing the cards
The methodology's print guidance is short: print at least 2 × 2 cm for arm's-length scanning, keep the quiet zone uncropped, and scan a test print with a real phone before the moment that matters. The generator's size readout makes the first rule specific to your code. It is prescriptive, not descriptive: the engine's working minimum module is 0.5 mm, so the smallest reliable print is that figure multiplied by the symbol's total modules, quiet zone included. For the worked example that is 49 modules: print at least 24.5 mm (0.96 in) wide. The same message as a reveal link needs 34.5 mm. Both figures are the width of the code itself; the confetti frame around it is extra, so size a print by the code panel, not by the artwork.
The readout under the generator's preview is that prescriptive one: the symbol's version, module count, error-correction level and character count, followed by the minimum print width. The PNG download select offers a choice of raster sizes — not every preset the engine defines — and the generator shows no DPI figure at all. The engine does carry a descriptive counterpart that says how large a given raster comes out at 300 DPI, where a side of 300 pixels prints at one inch; run on the engine's 3 preset raster sizes when this page was built, it gives:
- A side of 512 px prints at 43.3 mm (1.71 in) at 300 DPI.
- A side of 1024 px prints at 86.7 mm (3.41 in) at 300 DPI.
- A side of 2048 px prints at 173.4 mm (6.83 in) at 300 DPI.
The misreadings that cost scans are the same few, and each has a mechanism:
- Cropping the quiet zone. Trimming a print to the dark edge of the code removes the 4 clear modules that ISO/IEC 18004 requires on every side — they are part of the symbol itself, not of the frame. On a framed card the quiet zone sits inside the panel, so cutting around the frame art is harmless and cutting into the panel is not.
- Expecting bare text to display. An offline note is bare text: an iPhone offers to copy or search it and Google Lens runs a web search, so the message is the one thing the reader never sees. The reveal link is the mode built for those phones, at the cost of a connection; on a framed keepsake with no caption of your own the generator prints the message itself under the code as the caption, so the words can be read by eye whatever the phone does with them.
- Low-contrast heart colours. Hearts need 4.5:1; the pastel tested above measured 1.81:1 and was refused before it could be rendered, let alone printed.
- A longer message than the card can carry. The example's 57 characters make a version-6 code that needs 24.5 mm; the same words as a reveal link make a version-11 code that needs 34.5 mm. Density is paid for in millimetres, and the readout says so before anything is printed.
Baby reveal code FAQ
Can someone scan the code early and spoil the reveal?
Anyone who scans it sees the message — a QR code hides nothing from a camera, it only hides it from eyes. Verification proves that the artwork decodes; it says nothing about who is holding the card. Secrecy is a property of the paper, not of the pixels.
Does the reveal need internet at the party?
Only in reveal-link mode, where the code carries a URL to this site's reveal page at /m/ with the message in the fragment, decoded on the reader's device. The offline note writes the words into the code itself and needs no connection at all — the worked example on this page is one — but it accepts a display caveat: an iPhone offers to copy or search bare text and Google Lens runs a web search, while Samsung phones and dedicated scanner apps do display it. In both modes, on a framed keepsake with no caption of your own, the generator prints the message itself under the code as the caption, so it can be read by eye; a caption you type, like the worked example's prompt, takes that place instead.
Which mode does the worked example use, and which does the tool start on?
The example is an offline note: its payload is the 57-character message itself, which the engine encoded at version 6 (41×41 modules). The generator opens on the reveal-link mode with the offline note one choice away. The same message as a reveal link encodes at version 11, because the URL's host, path and base32 fragment travel with it.
How long can the announcement be?
Measured on this engine, called as the generator calls it at its default level H — with no compressor, so every reveal link it produces carries flag A. With one repeated lowercase letter, an offline note stays within the comfortable 65-module print limit up to 119 characters and a reveal link up to 55; without a compressor the fragment grows with the message's byte count alone, so the fictional prose run quoted on this page reaches the same figure. The framed-only “Smaller code” opt-in encodes at Q instead and moves those two figures to 151 and 75. The published format also has a compressed form, flag B, which the generators do not use today; with a compressor supplied when this page was built, the prose run's figure would become 58 characters. A reveal message is refused above 300 characters outright, in either form. Accented characters and emoji take several UTF-8 bytes each and shorten the reveal-link figures. Longer messages still encode — the symbol simply grows, and its minimum print size grows with it.
Is the message uploaded anywhere before the party?
No. The message is encoded, drawn and decode-verified entirely in your browser — nothing is transmitted, stored or posted. In reveal-link mode the words travel in the URL fragment, which per RFC 3986 is stripped before any request is made, so even a scan at the party never sends them to our servers, a CDN or a log.
Can I recolour the confetti pink or blue, or make the modules hearts?
The frame colour recolours the art only; the code stays black on white at 21.00:1, because the composite nests the rendered code untouched on an opaque panel above the confetti. Heart-shaped modules are a separate toggle; inside a frame it uses the engine's default heart colour, #881337, and the colour picker belongs to the bare heart-module style. The hearts bring the contrast gate: the engine requires at least 4.5:1 and rejects weaker pairs rather than warning. Demonstrated here as an engine rule, the preset's deep rose #881337 measures 9.57:1 and passes; the pastel #f9a8d4 measures 1.81:1 and is refused.
What does "Verified scannable" prove on a reveal card?
That this exact artwork, rasterised at 800, 1200, 1600 px and decoded with jsQR, came back as your exact bytes at 2 or more of those 3 sizes. It cannot see your printer, your paper or the phone that will scan, so print at least 2 × 2 cm, keep the quiet zone uncropped, and scan one test print with a real phone before the moment itself.
Will the code still work years after the party?
An offline note needs nothing but a scanner, since the words are in the code itself — and, on a framed keepsake with no caption of your own, in the ink under it too. A reveal link needs this site to still answer, which is why every message keepsake can also be downloaded as a self-contained HTML file that decodes the published fragment format with no network and no website at all.
More scan-to-reveal ideas: make the boy-or-girl moment itself a gender reveal code (even you can stay surprised), run the whole party as a QR treasure hunt ending at the reveal, put a message-in-code gift tag on the grandparents' announcement box, or weave the first ultrasound photo into a photo keepsake code.