The WiFi QR payload format

A WiFi QR code is two things stacked on top of each other. The payload is a short line of text written to a convention that a reader can parse into a network name, a security type and a password. The symbol is the matrix of dark and light modules that carries that text, produced to ISO/IEC 18004 with error correction built in. Most "my code doesn't work" problems are payload problems, so this guide is about the first layer: what the WIFI: string contains, why each piece is there, how the awkward characters are escaped, and what the string cannot tell you.

If you only want a code, the WiFi QR code generator builds one in your browser; this page explains what it is building. The symbol layer has its own pages among the guides.

The convention and where it comes from

The WiFi payload is a de-facto convention. The engine behind this site builds it to the description in the ZXing project's "Barcode Contents" wiki — the source the payload builder cites, verified against the live page on 2026-07-20. In its simplest form it reads:

WIFI:T:<auth>;S:<ssid>;P:<password>;;

Three fields, each introduced by a one-letter key and a colon and closed by a semicolon, with a second semicolon ending the record. The builder validates the inputs, escapes the values, decides whether to quote them, and joins the fields in a fixed order. For a fictional guest network it produces exactly this:

Network HarborGuest, WPA2, password tide-pool-77 (all invented) becomes:

WIFI:T:WPA;S:HarborGuest;P:tide-pool-77;;

Rendered by the same engine as the generator — version 3, 29×29 modules, error correction M. The payload is 41 characters long.

Field by field

  • WIFI: — the record-type prefix that marks the text as network credentials rather than a URL or a note.
  • T: — the authentication token. The builder emits exactly three values, WEP, WPA or nopass; the next section maps the builder's five security values, and the menu options the form offers them under, onto them.
  • S: — the SSID, escaped and, when it is all hex digits, quoted. It is the one field the builder always requires.
  • P: — the password, escaped and quoted by the same rules. It is present for WEP and the WPA family and omitted entirely — not left empty — for an open network.
  • H:true — the hidden-network flag. It appears only when you tick "Hidden network"; otherwise the field is left out rather than written as H:false.
  • ;; — the double semicolon at the end is not a typo. The first closes the last field; the second closes the record.

The security token: five values, three tokens

The builder accepts five security values — WEP, WPA, WPA2, WPA3 and nopass. The generator's security menu offers them as "WPA / WPA2 (most common)", "WPA3", "WEP (legacy)" and "None — open network", with WPA and WPA2 sharing one entry. The payload knows only three tokens. Here is what each value produces for the same fictional network, BackOffice with the password ledger-book-21:

Security value Menu option Payload
WEP WEP (legacy) WIFI:T:WEP;S:BackOffice;P:ledger-book-21;;
WPA WPA / WPA2 (most common) WIFI:T:WPA;S:BackOffice;P:ledger-book-21;;
WPA2 WPA / WPA2 (most common) WIFI:T:WPA;S:BackOffice;P:ledger-book-21;;
WPA3 WPA3 WIFI:T:WPA;S:BackOffice;P:ledger-book-21;;
nopass None — open network WIFI:T:nopass;S:BackOffice;;

WPA2 and WPA3-Personal both map to T:WPA. The builder's own note gives the reason: the joining device negotiates the strongest protocol itself, and emitting a nonstandard token such as SAE breaks parsers, so it is never produced — a rule locked in by a test. Pick the option that matches your router; the payload is the same for the whole WPA family, and that sameness is checked when this page is built: if the three strings ever differed, the build would fail rather than let this paragraph go stale.

WEP keeps its own token, and the builder's passphrase-length check applies to the WPA family only — a short WEP key is accepted. A second fictional network, OldPrinter with the key k3ypad, builds without complaint as WIFI:T:WEP;S:OldPrinter;P:k3ypad;;, although the same key would be refused for any WPA value. The option exists for legacy hardware, not as a recommendation.

Escaping: five characters and one ordering rule

Semicolons separate fields and colons separate keys from values, so a password containing either would be ambiguous to parse. The convention reserves five characters — backslash, semicolon, comma, double quote and colon — and escapes each by prefixing a backslash. The engine escapes the backslash first, then the other four, and the order matters: handled the other way round, the backslash just inserted in front of a semicolon would itself be escaped a second time.

Here is the escaping function applied to a few invented inputs:

Typed value As written into the payload
pass;word pass\;word
10:30,go 10\:30\,go
say "hi" say \"hi\"
C:\temp C\:\\temp
plain-text_42 plain-text_42

Applied to a whole record, an SSID and password built from awkward punctuation come out like this:

Network Pier 9: Lounge, password rope;knot,sail"\ (invented, and deliberately hostile) becomes:

WIFI:T:WPA;S:Pier 9\: Lounge;P:rope\;knot\,sail\"\\;;

Every reserved character has gained a backslash; nothing else has changed. Version 4, 33×33 modules, error correction M, 53 characters.

Characters outside those five pass through untouched, including spaces and accented letters, which the QR byte segment carries as UTF-8. A network named Café Ñandú encodes as WIFI:T:WPA;S:Café Ñandú;P:tide-pool-77;;. The password itself is stored as readable text: the symbol does not hide it, it carries it.

The hex-only quoting rule

The same source carries a second, less obvious rule. An SSID or password consisting entirely of hexadecimal digits must be enclosed in double quotes, so readers take it as literal ASCII rather than hex-encoded bytes. The builder tests the raw value — digits and the letters A to F in either case — and wraps the escaped value in literal quotes when it matches. The quotes are added after escaping and never escaped themselves; a value that needed escaping is by definition not all-hex and is never quoted.

Network DEC0DE, password FACE1234 — both all-hex, both invented — becomes:

WIFI:T:WPA;S:"DEC0DE";P:"FACE1234";;

Version 3, 29×29 modules, error correction M. Add one non-hex character to each value — DEC0DEZ and FACE1234x — and the quotes disappear: WIFI:T:WPA;S:DEC0DEZ;P:FACE1234x;;.

It is easy to trip without noticing: a password made of digits alone is all-hex even though nobody chose it to be.

Open networks and hidden networks

For an open network the T: token is nopass and the P: field is absent — the record goes straight from the SSID terminator to the record terminator:

WIFI:T:nopass;S:LobbyOpen;;

The builder refuses a password supplied alongside "None" rather than silently dropping it: "An open network (nopass) has no password."

Ticking "Hidden network" appends H:true as the last field before the closing ;; — after the password for a secured network, after the SSID for an open one, which has no password field. A WPA3 network that is not broadcast produces:

WIFI:T:WPA;S:BackOffice;P:ledger-book-21;H:true;;

Note the T:WPA token despite the WPA3 choice. The same fictional open network as above, with the box ticked, produces WIFI:T:nopass;S:LobbyOpen;H:true;;. The flag is a separate field, present or absent, and changes nothing else in the record; what to expect from a hidden SSID in practice is on the WiFi generator page.

What the builder refuses

Validation runs before any escaping. Each refusal names the field it belongs to, so the generator can highlight the input instead of showing a generic error. The messages below are the builder's own, produced at build time by handing it bad input:

  • Nothing entered: "Enter the network name (SSID). Enter the network password."
  • A WPA-family passphrase that is too short: "A WPA passphrase is 8–63 characters."
  • An SSID that is too long: "An SSID is at most 32 characters."
  • A password on an open network: "An open network (nopass) has no password."

One refusal comes from the encoder rather than the builder. The builder caps the SSID but puts no upper limit on a WEP key, so a 3000-character key passes every check above and yields a payload longer than any QR symbol can hold. The encoder then declines it with its own message:

  • A payload too long for any symbol: "This content is too long for a QR code. Shorten it or lower the error correction level."

Everything that passes the builder's checks encodes, up to that capacity limit — a narrower guarantee than it sounds.

Reading the symbol facts

Under every worked example this site prints a line of symbol facts. They describe the second layer — the matrix — and come straight from the encoder, which is a vendored copy of Project Nayuki's qrcodegen kept byte-comparable with upstream. For the examples on this page:

Example Characters Version Modules EC level
HarborGuest (WPA2) 41 3 29×29 M
Pier 9: Lounge (punctuation escaped) 53 4 33×33 M
DEC0DE (hex-quoted) 36 3 29×29 M
LobbyOpen (open network) 27 3 29×29 Q
BackOffice (WPA3, hidden) 49 4 33×33 M
  • Version is chosen by the encoder as the smallest that holds the payload at the requested error-correction level; a longer payload needs a higher version. The size in modules follows from the version.
  • EC level is the level actually encoded: never lower than requested, but possibly higher, because the reference encoder raises the level when doing so does not increase the version. The worked examples request M; a logo overlay would force H.
  • The quiet zone is not in the module count. Every download adds the 4-module border on all four sides, so the HarborGuest symbol is 37×37 modules edge to edge, and that border is part of the code.
  • Print size is a readout, not a rule. The smallest PNG preset, 512 pixels square, prints at 1.71 in × 1.71 in (43.3 mm × 43.3 mm) at 300 DPI — pixels divided by 300. The quiet zone and print size guide covers every preset, and how a QR code encodes data covers versions and levels.

What the payload cannot tell you

The builder validates format, not truth. It cannot know whether the password is correct, whether the router is switched on, or whether the SSID you typed is the SSID the router broadcasts. A mistyped passphrase encodes just as cleanly as the right one:

WIFI:T:WPA;S:HarborGuest;P:tide-pool-78;;

That string is as well-formed as the HarborGuest example above; only the router knows which of the two is right. A network renamed after printing is the same story: the payload still says what it said.

The code is also static. The credentials live in the image itself, with no redirect through any server, which is why the code never expires and cannot be held hostage — and why it cannot be edited after printing and scans cannot be counted. Change the password and you print a new code. The trade-offs are laid out in the static vs dynamic guide.

Error correction helps a damaged code scan, but print size and contrast still matter. Treat a freshly generated code as untested until a real device has scanned it.

Common misreadings

  • Cropping the quiet zone. The white border looks like empty margin and gets trimmed in layout. It is part of the symbol; cropping it is the most common self-inflicted scan failure.
  • Inverting the colours. Light modules on a dark background look like a design choice; the renderer warns for it separately, because many scanners reject inverted codes, and warns whenever the computed contrast ratio drops below 4.5:1. The contrast guide shows the computation.
  • Retyping the payload by hand. Copying a WIFI: string into another tool invites the mistakes the builder exists to prevent: a dropped backslash, an unquoted all-hex password, an invented T:WPA3 token.
  • Taking a successful scan as proof. A scan proves the payload parsed. It does not prove the password was right — see the mistyped example above.

WiFi payload FAQ

My router uses WPA3. Why does the payload say T:WPA?

Because WPA2 and WPA3-Personal both map to the T:WPA token. The builder's own note gives the reason: the joining device negotiates the strongest protocol itself, and emitting a nonstandard token such as SAE breaks parsers, so it is never produced. Choosing "WPA / WPA2 (most common)" or "WPA3" in the form yields the same string: WIFI:T:WPA;S:BackOffice;P:ledger-book-21;;

Why did my network name or password come out wrapped in double quotes?

Because it consists entirely of hexadecimal digits (0-9 and A-F in either case). The ZXing Barcode Contents convention requires such values to be enclosed in double quotes so readers take them as literal ASCII rather than hex-encoded bytes. The quotes are part of the payload, added after escaping and never escaped themselves: WIFI:T:WPA;S:"DEC0DE";P:"FACE1234";;

Can the generator check that my password is correct?

No. The builder validates format, not truth: it checks that the fields are present, within length limits and correctly escaped, but it cannot know whether the password matches the router. A mistyped passphrase encodes just as cleanly: WIFI:T:WPA;S:HarborGuest;P:tide-pool-78;; is as well-formed as WIFI:T:WPA;S:HarborGuest;P:tide-pool-77;;. Treat a freshly generated code as untested until a real device has scanned it.

If I change the WiFi password, does the code update?

No. The password is plain text inside the payload, and the payload lives in the image itself with no redirect through any server. That is what makes the code static: it never expires and cannot be held hostage, but it also cannot be edited after printing. A changed password needs a new code.

Can I remove the white border around the code?

No, and you should not want to. The 4-module quiet zone on every side is required by ISO/IEC 18004; the renderer always includes it in downloads and it cannot be disabled. Cropping it is the most common self-inflicted scan failure. The 29×29-module HarborGuest symbol is therefore 37×37 modules edge to edge.

Can I print light modules on a dark background?

The style panel will let you, but it warns separately for light-on-dark (inverted) codes, which many scanners reject, and it warns whenever the computed WCAG contrast ratio of your colour pair drops below 4.5:1. Dark modules on a light background is the form the warnings are steering you towards.

Build a real one on the WiFi QR code generator — encoding runs in your browser and nothing you type is sent to a server — or browse the other guides. How the encoding is built and verified is on the methodology page.