KYC · API reference

MRZ

MRZ Read

POST/v1/mrz/readmrz.read

Finds the MRZ in an image, reads it, parses every field, and validates every check digit under ICAO 9303.

**Returns**

- lines[]: the MRZ lines - warped_box: where the MRZ was - confidence[]: per-line read confidence - format: TD1, TD2, TD3 or a visa - valid: true when every check digit holds and dates are real - expired: true when the expiry date has passed - problems[]: any check that failed, and why - parsed: the fields, with check_digits

**Limits**

- Works at any orientation, up to 4K. Returns empty with a warning when no MRZ is found.

Price: 0.01 credits per successful call.

Body parameters

imagestringrequired

Document image. The image as base64 (JPEG or PNG). The SDKs also take a file path or the file bytes.

Returns

The check ran.

Show the MrzReadResponse fields
okbooleanrequired

true: the result is in data.

request_idstring
latency_msnumber

How long the check took, in milliseconds.

dataobjectrequired

The full result of MRZ Read: everything the check found. See the fields listed in the operation.

warningsarray of strings
errorany

Empty on success.

Errors

  • 400A field is missing or not valid.
  • 401No API key, or the key is not valid, expired or revoked.
  • 402Not enough credits for this call (insufficient_credits), or the key reached its spend cap. Nothing was charged.
  • 403The key may not call this API (permission, environment or IP allow-list). Nothing was charged.
  • 413The image or the request is too large.
  • 429Too many requests for this key: wait Retry-After seconds. Nothing was charged.
  • 5XXThe check could not run. Nothing was charged.
Request
curl -X POST https://verisec.dev/v1/mrz/read \
  -H "Authorization: Bearer $VERISEC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "image": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=="
  }'
Response · 200
{
  "ok": true,
  "request_id": "req_ac9bc6822e0b411bb600",
  "latency_ms": 401,
  "data": {
    "lines": [
      "P<CZESPECIMEN<<VZOR<<<<<<<<<<<<<<<<<<<<<<<<<",
      "99006000<8CZE1102299F16090641152291111<<<<24"
    ],
    "warped_box": [
      75,
      732,
      1286,
      732,
      1286,
      840,
      75,
      840
    ],
    "confidence": [
      92,
      91
    ],
    "format": "TD3",
    "valid": false,
    "expired": true,
    "problems": [
      {
        "field": "birth_date",
        "issue": "not a real date"
      }
    ],
    "parsed": {
      "doc": "P",
      "country": "CZE",
      "surname": "SPECIMEN",
      "given_name": "VZOR",
      "doc_number": "99006000",
      "nationality": "CZE",
      "birth_date": "110229",
      "sex": "F",
      "expiry": "160906",
      "personal_number": "1152291111",
      "check_digits": {
        "doc_number": {
          "digit": "8",
          "ok": true
        },
        "birth_date": {
          "digit": "9",
          "ok": true
        },
        "expiry": {
          "digit": "4",
          "ok": true
        },
        "personal_number": {
          "digit": "2",
          "ok": true
        },
        "composite": {
          "digit": "4",
          "ok": true
        }
      }
    }
  },
  "warnings": [],
  "error": null
}

MRZ Recognize

POST/v1/mrz/recognizemrz.recognize

Only the MRZ lines, where they are, and how confident the read is. No parsing.

**Returns**

- lines[]: the MRZ lines - warped_box: where the MRZ was - confidence[]: per-line read confidence

**Limits**

- Returns empty lines with a warning when no MRZ is found.

Price: 0.01 credits per successful call.

Body parameters

imagestringrequired

Document image. The image as base64 (JPEG or PNG). The SDKs also take a file path or the file bytes.

Returns

The check ran.

Show the MrzRecognizeResponse fields
okbooleanrequired

true: the result is in data.

request_idstring
latency_msnumber

How long the check took, in milliseconds.

dataobjectrequired

The answer of MRZ Recognize.

Show 3 fields
linesarray of strings
warped_boxarray of numbers
confidencearray of numbers
warningsarray of strings
errorany

Empty on success.

Errors

  • 400A field is missing or not valid.
  • 401No API key, or the key is not valid, expired or revoked.
  • 402Not enough credits for this call (insufficient_credits), or the key reached its spend cap. Nothing was charged.
  • 403The key may not call this API (permission, environment or IP allow-list). Nothing was charged.
  • 413The image or the request is too large.
  • 429Too many requests for this key: wait Retry-After seconds. Nothing was charged.
  • 5XXThe check could not run. Nothing was charged.
Request
curl -X POST https://verisec.dev/v1/mrz/recognize \
  -H "Authorization: Bearer $VERISEC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "image": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=="
  }'
Response · 200
{
  "ok": true,
  "request_id": "req_eae59ec4510742eaa67c",
  "latency_ms": 337,
  "data": {
    "lines": [
      "P<CZESPECIMEN<<VZOR<<<<<<<<<<<<<<<<<<<<<<<<<",
      "99006000<8CZE1102299F16090641152291111<<<<24"
    ],
    "warped_box": [
      75,
      732,
      1286,
      732,
      1286,
      840,
      75,
      840
    ],
    "confidence": [
      92,
      91
    ]
  },
  "warnings": [],
  "error": null
}

MRZ Parse

POST/v1/mrz/parsemrz.parse

Parses MRZ lines you already have (no image): every field, every check digit recomputed, and a check that the dates are real.

**Returns**

- format: TD1, TD2, TD3 or a visa - valid: true when every check digit holds and dates are real - expired: true when the expiry date has passed - problems[]: any check that failed - parsed: the fields, with check_digits

**Limits**

- 1 to 3 lines; letters A to Z, digits, and < only. - No image and no upload, this is pure parsing.

Price: 0.002 credits per successful call.

Body parameters

linesarray of stringsrequired

MRZ lines. An ID card has 3 lines of 30 characters, a passport 2 lines of 44.

Returns

The check ran.

Show the MrzParseResponse fields
okbooleanrequired

true: the result is in data.

request_idstring
latency_msnumber

How long the check took, in milliseconds.

dataobjectrequired

The answer of MRZ Parse.

Show 5 fields
formatstring
validboolean
expiredboolean
problemsarray of anys
parsedobject
Show 11 fields
docstring
countrystring
surnamestring
given_namestring
doc_numberstring
nationalitystring
birth_datestring
sexstring
expirystring
personal_numberstring
check_digitsobject
Show 5 fields
doc_numberobject
birth_dateobject
expiryobject
personal_numberobject
compositeobject
warningsarray of strings
errorany

Empty on success.

Errors

  • 400A field is missing or not valid.
  • 401No API key, or the key is not valid, expired or revoked.
  • 402Not enough credits for this call (insufficient_credits), or the key reached its spend cap. Nothing was charged.
  • 403The key may not call this API (permission, environment or IP allow-list). Nothing was charged.
  • 413The image or the request is too large.
  • 429Too many requests for this key: wait Retry-After seconds. Nothing was charged.
  • 5XXThe check could not run. Nothing was charged.
Request
curl -X POST https://verisec.dev/v1/mrz/parse \
  -H "Authorization: Bearer $VERISEC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "lines": [
      "P<UTOERIKSSON<<ANNA<MARIA<<<<<<<<<<<<<<<<<<<",
      "L898902C36UTO7408122F1204159ZE184226B<<<<<10"
    ]
  }'
Response · 200
{
  "ok": true,
  "request_id": "req_d6db6dcaae924d908055",
  "latency_ms": 34,
  "data": {
    "format": "TD3",
    "valid": true,
    "expired": true,
    "problems": [],
    "parsed": {
      "doc": "P",
      "country": "UTO",
      "surname": "ERIKSSON",
      "given_name": "ANNA MARIA",
      "doc_number": "L898902C3",
      "nationality": "UTO",
      "birth_date": "740812",
      "sex": "F",
      "expiry": "120415",
      "personal_number": "ZE184226B",
      "check_digits": {
        "doc_number": {
          "digit": "6",
          "ok": true
        },
        "birth_date": {
          "digit": "2",
          "ok": true
        },
        "expiry": {
          "digit": "9",
          "ok": true
        },
        "personal_number": {
          "digit": "1",
          "ok": true
        },
        "composite": {
          "digit": "0",
          "ok": true
        }
      }
    }
  },
  "warnings": [],
  "error": null
}