# SDK Response

The response of the SDK will return in the following delegate

```swift
func onOCRResult(result: VIDVOCRResponse)
```

It will return an enum result of type `VIDVOCRResponse`&#x20;

### `VIDVOCRResponse` Cases

`Success` : Process finished successfully

`CapturedImages`: Images captured are returned in real-time

{% hint style="info" %}
Note: For the`CapturedImages`instance, images are not processed yet
{% endhint %}

`UserExit` : Process terminated by the user with no errors

`ServiceFailure` : Process finished with the user's failure to pass the service requirements

`BuilderError` : Process terminated due to an error in the builder

#### Example

```swift
switch result {
case .success(let data):
    // data of type VIDVOCRResult
case .builderError(let code, let message):
    // builder error code & error message
case .serviceFailure(let code, let message, let data):
    // service faluire error code & error message & data of type VIDVOCRResult
case .userExit(let step, let data):
    // last step in the SDK & data of type VIDVOCRResult
case .capturedImages(capturedImageData: let capturedImageData):
    // capturedImageData of type CapturedImageData
    
}
```

### Document verification plus - Case Handling

When using `VIDVOCRResult.getData()`, the returned `ocrResult` may include a `documentVerificationPlus`object.\
This object contains validation flags and quality signals that help you determine whether the document should be accepted, reviewed, recaptured, or rejected.

***

#### Fields Returned Under `documentVerificationPlus`

| Field               | Type          | Meaning                                                                           |
| ------------------- | ------------- | --------------------------------------------------------------------------------- |
| `frontDataValidity` | boolean       | Overall validity of the front side based on greyscale flags + invalid fields list |
| `backDataValidity`  | boolean       | Overall validity of the back side based on greyscale flags + invalid fields list  |
| `isFrontGreyscale`  | boolean       | Indicates whether the front side is greyscale                                     |
| `isBackGreyscale`   | boolean       | Indicates whether the back side is greyscale                                      |
| `expired`           | boolean       | Whether the document is recognized as expired                                     |
| `reviewRequired`    | List\<String> | Fields that require attention (e.g. Nid, gender, expirydate…)                     |

***

#### How to Read These Values

* `frontDataValidity` and `backDataValidity` act as **parent flags**\
  → You can take action directly based on them if you want a simple validation flow.
* For more control, you can check detailed signals:
  * use greyscale flags if you want to **reject black-and-white copies**
  * use `reviewRequired`to apply different logic per field\
    e.g. reject if nid is invalid but allow if *gender* is inconsistent

This allows fully customizable decision logic depending on your business rules.

#### **Example Handling Logic**

```swift
//Note that all decisions taken in this code are just an example of how you can handle
//the logic and that you can take the preferred action according to your business needs
if let flags = result.data?.ocrResult?.documentVerificationPlus {

    // --------------------- GENERIC VALIDATION RESULTS --------------------- //

    // Quick validation using global parent flags
    if flags.frontDataValidity == false || flags.backDataValidity == false {
        showRetryDialog(
            title: "Document failed validation checks.",
            message: "Please try again."
        ) { 
            startOCR()  // Developer function — implement your restart flow
        }
    }

    // Greyscale document detection
    else if flags.isFrontGreyscale == true || flags.isBackGreyscale == true {
        requestRecapture(reason: "Document appears to be black & white.")
        // requestRecapture() is an example recapture function — implement your flow
    }

    // Document expired
    else if flags.isExpired == true {
        showRetryDialog(
            title: "OCR",
            message: "Expired ID, please try again with your recent National ID."
        ) {
            startOCR()  // Custom restart logic
        }
    }

    // One or more fields require review
    else if !(flags.reviewRequired?.isEmpty ?? true) {
        showError("Some fields require manual review.")
        // showError() is a custom function — for UI alerts/log display
    }


    // --------------------- FIELD-LEVEL REVIEW CASES --------------------- //

    if let review = flags.reviewRequired {

        if review.contains("serial_number") {
            showRetryDialog(
                title: "OCR",
                message: "Serial number is incorrect. Please try again."
            ) { startOCR() }
        }

        if review.contains("back_nid") || review.contains("front_nid") {
            requestRecapture(reason: "NID Mismatch")  // Example recapture action
        }

        if review.contains("date_of_birth") { showError("Date of birth could not be verified.") }
        if review.contains("street") { showError("Street address is empty.") }
        if review.contains("police_station") { showError("Police station field needs review.") }
        if review.contains("governorate") { showError("Governorate value could not be verified.") }
        if review.contains("birth_governorate") { showError("Birth governorate requires review.") }
        if review.contains("expiry_date") { showError("Expiry date is missing or invalid.") }
        if review.contains("release_date") { showError("Release date did not pass validation.") }
    }
    
    else {
        // Default Case — No flags triggered
        // Document is valid and accepted
    }
}

```

### Advance confidence  - Case Handling

When using `VIDVOCRResult.getData()`, the returned `ocrResult` may include a `advancedConfidence` object.\
This object contains manipulation flags that help you determine whether the document should be accepted, reviewed, recaptured, or rejected.

***

#### Fields Returned Under `advanceConfidence`

| Field                      | Type | Meaning                                                          |
| -------------------------- | ---- | ---------------------------------------------------------------- |
| fraudDetectionZone         | int  | Parent zone flag → Result of face + image manipulation combined  |
| faceFraudZone              | int  | Fraud confidence specifically related to face physical tampering |
| frontImageManipulationZone | int  | Indicates signs of front image physical manpulation              |

#### Zone Meaning

| Value | Color  | Meaning                                   |
| ----- | ------ | ----------------------------------------- |
| 0     | Green  | No manipulation detected                  |
| 1     | Yellow | Requires human review (suspicious)        |
| 2     | Red    | Strong indicators of fraud / manipulation |

***

#### **Example Handling Logic**

```kotlin
//Note that all decisions taken in this code are just an example of how you can handle
//the logic and that you can take the preferred action according to your business needs
if let fraud = result.data?.ocrResult?.advancedConfidence {

    // Parent Fraud Status
    switch fraud.fraudDetectionZone {
    case 1: showWarning("Suspicious document — review needed") // Replace with custom handling
    case 2: requestRecapture(reason: "Fraud suspected — please retry with a valid ID") // Replace with custom handling
    default: break
    }

    // Detailed Breakdown
    if fraud.faceFraudZone > 0 {
        showError("Face region manipulation detected") // Replace with custom handling
    }

    if fraud.frontImageManipulationZone > 0 {
        showError("Possible document editing found") // Replace with custom handling
    }
}
}
```

### Primary Response Object

`VIDVOCRResult`&#x20;

{% hint style="info" %}
Note: This is the first-level object that contains all the second-level objects
{% endhint %}

### Object Body

* `sessionID` \<string>

<details>

<summary><code>ocrResult</code> &#x3C;sub-object></summary>

* `firstName` \<string>

* `fullName` \<string>

* `religion` \<string>

* `gender` \<string>

* `dateOfBirth` \<string>

* `age` \<int>

* `maritalStatus` \<string>

* `husbandName` \<string>

* `street` \<string>

* `birthGovernorate` \<string>

* `policeStation` \<string>

* `governorate` \<string>

* `profession` \<string>

* `releaseDate` \<string>

* `expiryDate` \<string>

* `serialNumber` \<string>

* `frontNid` \<string>

* `backNid` \<string>

* `isRootOfTrustCompatible` \<boolean>

* `transactionIdFront` \<string>

* `transactionIdBack` \<string>

* `combinationID` \<string>

* `documentVerificationPlus` \<object>

  * `frontDataValidity` \<boolean>
  * `backDataValidity` \<boolean>
  * `frontConfidence` \<int>
  * `backConfidence` \<int>
  * `expired` \<boolean>

* advanced\_confidence \<object>
  * fraud\_detection\_zone \<int>
  * fraud\_detection\_details \<object>
    * is\_cracked \<boolean>
    * is\_cracked\_confidence \<float>
    * face\_fraud\_zone \<int>
    * face\_fraud\_confidence \<float>
    * front\_image\_manipulation\_zone \<int>
    * front\_image\_manipulation\_confidence \<float>
  * anomaly\_detection\_zone \<int>
  * anomaly\_detection\_details \<object>
    * front\_image\_anomaly\_zone \<int> (Detects any anomaly or obstruction on the front NID)
    * front\_image\_anomaly\_confidence \<float>
    * front\_text\_manipulation \<boolean> (Detects any anomaly or obstruction affecting the **text** of the front NID)
    * back\_image\_anomaly\_zone \<int> (Detects any anomaly or obstruction on the back NID)
    * back\_image\_anomaly\_confidence \<float>
    * back\_text\_manipulation \<boolean> (Detects any anomaly or obstruction affecting the **text** of the front NID)

</details>

<details>

<summary><code>documentVerificationResult</code> &#x3C;sub-object></summary>

* `success` \<boolean>

</details>

<details>

<summary><code>captures</code> &#x3C;sub-object></summary>

* `nationalIdFront` \<base64-string>
* `nationalIdBack` \<base64-string>

</details>

<details>

<summary><code>hmacDataList</code> &#x3C;list></summary>

* `serviceID`: ocr
* `hmacDigest` \<string>
* `rawResponse` \<string>

</details>

<details>

<summary><code>decryptionKeys</code> &#x3C;sub-object></summary>

* &#x20;`nationalIdFrontRequestKey` \[UInt8]
* `nationalIdBackRequestKey` \[UInt8]
* `combineResponseKey` \[UInt8]

</details>

{% hint style="info" %}
The raw response in `hmacDataList` should be mapped to the result object as per the [HMAC Validation Documentation ](https://valify.gitbook.io/documentation/response-data-validation)
{% endhint %}

### SDK Event Logs Response

{% hint style="info" %}
Note: If the associated delegate is confirmed, event logs will be received through the two objects below
{% endhint %}

<details>

<summary><code>VIDVEvent</code> &#x3C;object></summary>

* `key` \<string>
* `Screen` \<string>
* `type`: \<string>
* `sessionId`: \<string>
* `payload` \<string>
* `timestamp` \<int64>
* `date` \<date><br>

</details>

<details>

<summary><code>VIDVError</code> &#x3C;object></summary>

* `code` \<int16>
* `message` \<string>
* `screen` \<string>
* `type` \<string>
* `sessionId`: \<string>
* `timestamp` \<int64>
* `date` \<date><br>

</details>

### Instance Responses

<mark style="color:blue;">`Success`</mark>

* `VIDVOCRResult` \<object>&#x20;

<mark style="color:blue;">`CapturedImages`</mark>&#x20;

<details>

<summary><code>CapturedImageData</code> &#x3C;object></summary>

* `nationalIDLabel` \<string>
* `nationalIdImage` \<base64-string>

</details>

<mark style="color:blue;">`UserExit`</mark>

* `VIDVOCRResult` \<object>
* `step` \<string>

{% hint style="info" %}
Note: step \<string> identifies the point where the user chose to exit the SDK
{% endhint %}

<mark style="color:red;">`ServiceFailure`</mark>

* `VIDVOCRResult` \<object>
* `code` \<string>
* `message` \<string>

<mark style="color:red;">`BuilderError`</mark>

* `code` \<string>
* `message` \<string>
