MRZ reference

The machine-readable zone (MRZ) is the block of upper-case letters, digits and < fillers printed at the bottom of a passport data page. An identity card carries it on the back. It is the one part of a document a caller can re-verify without trusting this service, and it is published verbatim for that reason.

Where it appears

Key Carries
mrz.status passed, failed or absent
mrz.reason One sentence naming what did not check out
mrz.lines The lines in order, or null
mrz.text The lines run together, one unbroken string, or null
fields[] entry mrz The zone's text as a field of the report

lines

The zone's lines in order, exactly as read. Two lines for a TD3 passport, three for a TD1 card.

Nothing is reconstructed. The lines come from the one field the recognition engine reports the zone in, never from the parsed values. A caller re-running the check digits over a reconstructed zone would be checking this service's arithmetic rather than the document's.

The filler < is kept. It carries the padding the check digits are computed over, so trimming it would make the digits fail.

What is removed is whitespace, which the zone's alphabet does not contain. A space or a tab inside a line is the reading equipment, not the document.

text

The same lines run together with nothing between them: no newline, no space, one unbroken string.

{
  "lines": [
    "P<GRCPARADEIGMA<<ELENI<SOFIA<<<<<<<<<<<<<<<<",
    "AM73045184GRC9403084F3203101PN48291630<<<<72"
  ],
  "text": "P<GRCPARADEIGMA<<ELENI<SOFIA<<<<<<<<<<<<<<<<AM73045184GRC9403084F3203101PN48291630<<<<72"
}

The zone's alphabet is A-Z, 0-9 and <, so joining the lines loses nothing: no separator can be confused with content, and none needs to be chosen. A checksum routine or a border-control library takes the value unchanged, and lines is there for anything that needs the rows one at a time.

The three formats

Format Lines Characters per line Where it is met
TD1 3 30 Identity cards, residence permits
TD2 2 36 Older identity cards and some travel documents
TD3 2 44 Passport booklets

Whichever format it is, the zone fills the same values once it is read.

The personal number comes from the zone's optional-data field, which TD2 does not carry.

No format encodes a date of issue. The issue_date field is therefore always a reading of the printed page. It is absent on a document whose visual zone was not read, even when every check digit passed.

How the check digits are reported

A zone carries a check digit over each of the fields it protects, and a final digit over the composite of them. Every one of them is verified, and the outcome is published as one verdict with a sentence.

status Meaning
passed A zone is present, every check digit validated, and nothing in it contradicts the printed page
failed A zone is present and something did not check out
absent The document carries no zone, or none was read

reason is null unless the status is failed. When it is failed, the sentence names what went wrong, and it is assembled from two clauses.

Clause Sentence
A digit failed, and the field it protects is known Check digit failed for: document number, date of birth
The aggregate failed with no field to blame MRZ check digits did not validate
The zone disagrees with the printed page MRZ does not match the visual zone for: surname

Both clauses can appear at once, joined by ; . A verdict a caller cannot act on is worth no more than none, so failed always names a subject where one exists.

The per-digit outcomes are not published. They are the zone's own plumbing. A caller that wants to see them re-runs the digits over text, which is published verbatim for that purpose.

The zone as a field

The zone is also one entry of fields. A reader looking at the field table therefore sees the part of the page that can be re-checked by hand.

Key Value
id mrz@0
name mrz
label MRZ
category document
language null
value The same string as mrz.text
confidence Always high

language is null because the zone is defined over a restricted Latin alphabet and has no language of its own.

confidence is always high, and it is not a measurement. The zone either read or it did not; the recognition engine reports no probability for the lines as a whole. What says whether to trust them is the check-digit verdict, not a band here.

The entry is absent when the document carries no zone.

Cross-zone comparison

A passport prints the same facts twice: once for a person to read and once for a machine. The verdict covers both the digits and the agreement between the two zones. That is why failed can name a field whose check digits were fine.

A disagreement is usually a misread character rather than a forged document. Where the two zones read a field differently, the reason names that field instead of leaving the caller to compare them.

When there is no zone

A driving licence, most national identity documents outside the travel-document formats, and any document photographed from the wrong side carry no readable zone.

mrz.status is absent, and reason, lines and text are all null. The group itself is always present.

absent is an outcome, not a failure. A document that never had a zone is recognized normally, and status on the scan itself stays recognized.