# 2️⃣ Read MRZ

The Machine Readable Zone - MRZ contains the information that acts as "[proof of authorization](https://www.icao.int/Security/FAL/PKD/BVRT/Pages/Document-readers.aspx)" to access the chip content. If machine-reading of the MRZ is not possible the information can be entered manually.

### Api Signature

{% tabs %}
{% tab title="Android" %}

```kotlin
    fun readMRZ(onCompletion: (DocumentResult<MRZDocument>) -> Unit)
```

{% endtab %}

{% tab title="iOS" %}

```swift
 public static func readMRZ(
        completion: @escaping (Result<MrzDocument, KeylessDocument.DocumentError>) -> Void
    )
```

{% endtab %}

{% tab title="Flutter" %}

```dart
Future<DocumentResult<MRZDocument>> readMRZ()
```

{% endtab %}
{% endtabs %}

### Returned result

If the Keyless Document SDK can read the MRZ it will return an instance of `MRZDocument` containing the data read.

{% tabs %}
{% tab title="Android" %}

```kotlin
data class MRZDocument(
    val documentNumber: String,
    val dateOfBirth: String,//Format as yy-MM-dd
    val dateOfExpiration: String,//Format as yy-MM-dd
    val personalNumber: String? = null,
    val firstName: String? = null,
    val lastName: String? = null,
    val nationality: String? = null,
    val issuingState: String? = null,
    val documentType: String? = null,
    var gender: String? = null
)
```

{% endtab %}

{% tab title="iOS" %}

```swift
public struct MrzDocument {
    public let documentNumber: String
    public let birthdate: String
    public let expirationDate: String
}
```

{% endtab %}

{% tab title="Flutter" %}

```dart
class MRZDocument {
  final String documentNumber;
  final String dateOfBirth; // Format: yy-MM-dd (e.g., 23-05-15)
  final String dateOfExpiration; // Format: yy-MM-dd (e.g., 23-05-15)
  final String? personalNumber;
  final String? firstName;
  final String? lastName;
  final String? nationality;
  final String? issuingState;
  final String? documentType;
  final String? gender;
}
```

{% endtab %}
{% endtabs %}

### Errors

In case of errors the Keyless Document SDK will return the following errors:

{% tabs %}
{% tab title="Android" %}

```kotlin
public sealed class DocumentError(
    public open val code: Int,
    public open val message: String,
) 

// errors launching the MrzCameraActivity
public data class InternalError(override val code: Int) : DocumentError(code, "Internal error")

public data object UserCancelled : DocumentError(
	code = 5000,
    message = "User cancelled the operation."
)

public data object LauncherNotInitialized : DocumentError(
    code = 5002,
    message = "Launcher is null or not initialized"
)

public data object PermissionDenied : DocumentError(
    code = 7001,
    message = "Permission denied."
)

public data class UnknownError( override val message: String) : DocumentError(
    code = 9999,
    message = message
)
```

{% endtab %}

{% tab title="iOS" %}

```swift
public enum DocumentError: Error {

        case userCancelled
        case cannotCalculateMRZKey
        case cameraUnavailable
        case cameraPermissionDenied
        case unknownError(message: String)

       public var code: Int {
            switch self {
                case .userCancelled: return 5000
                case .cameraUnavailable: return 6001
                case .cannotCalculateMRZKey: return 6002
                case .cameraPermissionDenied: return 6004
                case .unknownError: return 9999
            }
        }

        public var message: String {
            switch self {
                case .userCancelled: return "User cancelled the operation"
                case .cannotCalculateMRZKey: return "Failed to calculate MRZ key"
                case .cameraUnavailable: return "Camera is unavailable"
                case .cameraPermissionDenied: return "Permission denied"
                case .unknownError(let message): return message
            }
        }
}
```

{% endtab %}

{% tab title="Flutter" %}

```dart
enum DocumentError {
  internalError,
  userCancelled,
  launcherNotInitialized,
  permissionDenied,
  cannotCalculateMRZKey,
  cameraUnavailable,
  cameraPermissionDenied,
  unknownError;
```

{% endtab %}
{% endtabs %}

### Example usage

{% tabs %}
{% tab title="Android" %}

```kotlin
KeylessDocument.readMRZ {
    when (it) {
        is DocumentResult.Success -> {
            Log.d(TAG, "MRZ data ${it.value}")
 		}
    	is DocumentResult.Failure -> {
            Log.d(TAG, "MRZ error ${it.error}")
        }
}
```

{% endtab %}

{% tab title="iOS" %}

```swift
KeylessDocument.readMRZ { result in
    switch result {
    case .success(let document):
        print("MRZ data: \(document)")
    case .failure(let error):
        print("MRZ error: \(error)")
    }
}
```

{% endtab %}

{% tab title="Flutter" %}

```dart
DocumentResult<MRZDocument> documentResult = await KeylessDocument.instance.readMRZ();

switch (documentResult) {
    case DocumentSuccess<MRZDocument>(data: final mrz):
        String mrzData = 'MRZ: ${mrz.documentNumber}, ${mrz.dateOfBirth} ${mrz.dateOfExpiration}';
        break;
    case DocumentFailure(message: final error, code: final code, errorType: final type):
        String error = 'MRZ Error: $error $code ($type)';
        break;
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.keyless.io/mobile-document-sdk/mobile-document-sdk-guide/2-read-mrz.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
