📘

**Note**:

To utilize RiskOS™ your DocV iOS SDK integration must be on version 5 (v5) or later.

## Before you start

Make sure you have the following:

1. Configure a DocV workflow and decision logic in [RiskOS™ DocV setup](https://help.socure.com/riskos/docs/docv-riskos-setup#/). The SDK cannot generate a transaction token until DocV is set up in your workflow.
2. Get a valid API key from the [Developer Workbench > API Keys](https://riskos.socure.com/developers/api-keys) page in RiskOS™.
3. Get a valid SDK key from the [Developer Workbench > SDK Keys](https://help.socure.com/riskos/docs/integration-guide-authentication#/).  
4. (Optional) Add your IP address to the [allowlist](https://help.socure.com/riskos/docs/ip-filtering#/).

### iOS SDK integration notes

Check that your development environment meets the following requirements:

- Xcode version 15.3+
- Support for iOS 15 and later

#### iOS Device SDK and DocV SDK compatibility

When integrating the **DocV SDK** on iOS, you do not need to include both the **Device SDK** and the **DocV SDK**. The DocV SDK already includes the full functionality of the Device SDK.

We recommend removing the standalone Device SDK when using the DocV SDK to avoid duplication or version conflicts.

If you choose to include both, ensure that the Device SDK version is at least **v4.5.2** to maintain compatibility.

## Step 1: Generate a transaction token and configure the Capture App

To initiate the verification process, generate a transaction token (`docvTransactionToken`) by calling the Evaluation endpoint. We strongly recommend that customers generate this token via a server-to-server API call and then pass it to the DocV SDK to ensure the security of their API key and any data they send to Socure.

### Call the Evaluation endpoint

1. From your backend, make a `POST` request to the `/api/evaluation` endpoint specifying the following information in the `config` object:

| Parameter | Required | Description |
| --- | --- | --- |
| `language` | Optional | Determines the [language package](https://help.socure.com/riskos/docs/language-options#/) for the UI text on the Capture App.<br>**Note**: Socure can quickly add support for any new language requirement that is not listed above. For more information, contact [support@socure.com](mailto:support@socure.com). |
| `use_case_key` | Optional | Deploys a customized Capture App flow on a per-transaction basis. Replace the `customer_use_case_key` value with the name of the flow you created in [RiskOS™](https://help.socure.com/riskos/docs/capture-app#/).<br>- If this field is empty, the Capture App will use the flow marked as **Default** in RiskOS™.<br>- If the value provided is incorrect, the SDK will return an `Invalid Request` error. |

> 📘
>
> **Note**:
>
> We recommend including as much consumer PII in the body of the request as possible to return the most accurate results.

Sample API call: The Evaluation endpoint

```curl
curl --location 'https://riskos.socure.com/api/evaluation' \
  --header 'accept: application/json' \
  --header 'authorization: Bearer YOUR_API_KEY' \
  --header 'content-type: application/json' \
  --header 'X-API-Version: 2025-01-01.orion' \
  --data-raw '{
    "id": "onb-12345",
    "workflow": "consumer_onboarding",
    "timestamp": "2025-01-08T14:57:42.089Z",
    "data": {
      "individual": {
        "id": "9876543",
        "given_name": "John",
        "family_name": "Doe",
        "national_id": "000-10-0007",
        "date_of_birth": "2002-07-28",
        "email": "johndoe@gmail.com",
        "phone_number": "+447767198341",
        "docv": {
          "config": {
            "use_case_key": "customer_use_case_key",
            ...
          }
        },
        "address": {
          "line_1": "Address Line 1",
          "locality": "New York City",
          "major_admin_division": "NY",
          "country": "US",
          "postal_code": "12345"
        }
      }
    }
  }'
```

2. When you receive the API response, collect the `docvTransactionToken`. This value is required to initialize the DocV iOS SDK.

Sample API response: The Evaluation endpoint

```json
{
    "id": "Test-API-1",
    "workflow": "sc_onboarding",
    "workflow_id": "a8dff53b-74c1-411f-a43d-9597ae60e5ae",
    "workflow_version": "3.2.0",
    "eval_source": "API",
    "eval_id": "500c6b88-9f5c-4d62-9422-163a59a343fe",
    "eval_start_time": "2025-01-08T14:57:42.08985Z",
    "eval_end_time": "0001-01-01T00:00:00Z",
    "decision": "REVIEW",
    "decision_at": "2025-01-08T14:57:43.223321Z",
    "status": "ON_HOLD",
    "sub_status": "",
    "tags": null,
    "notes": "",
    "review_queues": [
        "Default Queue"
    ],
    "data_enrichments": [
        {
            "enrichment_name": "SocureDocRequest",
            "enrichment_endpoint": "https://service.socure.com/api/5.0/documents/request",
            "enrichment_provider": "SocureDocRequest",
            "status_code": 200,
            "request": {
                "city": "New York City",
                "country": "US",
                "dob": "2002-07-28",
                "firstName": "John",
                "mobileNumber": "+1234567891",
                "physicalAddress": "Address Line 1",
                "state": "NY",
                "surName": "Doe",
                "zip": "12345"
            },
            "response": {
                "data": {
                    "docvTransactionToken": "70c6a4bc-f646-4c6a-94c1-9cd428e356ef",
                    "eventId": "70c6a4bc-f646-4c6a-94c1-9cd428e356ef",
                    "qrcode": "data:image/png;base64,iVBO......K5CYII=",
                    "url": "https://verify.socure.com/#/dv/70c6a4bc-f646-4c6a-94c1-9cd428e356ef"
                },
                "referenceId": "aacdc975-0eb8-428d-9954-b42aab67f85f"
            },
            "is_source_cache": false,
            "total_attempts": 1
        }
    ],
    "eval_status": "evaluation_paused"
}
```

## Step 2: Add the DocV iOS SDK

You can use either CocoPods or Swift Package Manager to add the DocV iOS SDK to your project. Depending on the dependency manager you want to use, follow the steps in the tabs below.

To install the DocV iOS SDK using CocoaPods, add the following to your Podfile:

```undefined
pod 'SocureDocV'
```

Next, install the Pod from the terminal:

```undefined
pod install
```

> 📘
>
> **Note**:
>
> You must close the project and open the `xcworkspace` file after you install the pod for it to properly reflect in your project.

To install the DocV iOS SDK using Swift Package Manager, add the following package repository URL:

```undefined
https://github.com/socure-inc/socure-docv-sdk-ios
```

### Camera permissions

The DocV SDK requires camera permissions to capture identity documents. Upon the first invocation of the SDK, the app will request camera permission from the user. If the app does not already use the camera, you must add the following to the app’s `Info.plist file`:

| Key | Type | Value |
| --- | --- | --- |
| Privacy - Camera Usage Description | String | "This application requires use of your camera in order to capture your identity documents." |

> 📘
>
> **Note**:
>
> We recommend you check for camera permission before calling the DocV SDK launch API.

### Import SocureDocV

Add the following line to import the SocureDocV SDK into the view controller:

Swift

```swift
import SocureDocV
```

### Initialize and launch the SDK

To enable the DocV SDK functionality, add the following code to your app:

Swift

```swift
func onButtonTapped() {
    let options = SocureDocVOptions(
        publicKey: "da3e907d-c5dd-41cb-80ee-xxxxxxxxxxxx",
        docvTransactionToken: "78d1c86d-03a3-4e11-b837-71a31cb44142",
        presentingViewController: self,
        useSocureGov: false
    )

SocureDocVSDK.launch(options) {
        (result: Result<SocureDocVSuccess, SocureDocVFailure>) in

switch result {
        case .success(let success):
            print(
                "Flow succeeded: \(success)"
            )
        case .failure(let failure):
            print(
                "Flow failed due to \(failure)"
            )
        }
    }
}
```

#### `options` parameters

The following table lists the `options` parameters:

| Parameter | Type | Description |
| --- | --- | --- |
| `publicKey` | String | The unique SDK key obtained from [RiskOS™](https://riskos.socure.com/accounts/developers/sdk-keys) used to authenticate the SDK. |
| `docvTransactionToken` | String | The transaction token retrieved from the API response of the `` endpoint. Required to initiate the document verification session. |
| `presentingViewController` | UIViewController | The current view controller (referred to as `self`) that will present the SDK's user interface. |
| `useSocureGov` | Bool | A Boolean flag indicating whether to use the GovCloud environment. It defaults to `false`. This is only applicable for customers provisioned in the SocureGov environment. |

### Handle the response

Your app can receive response callbacks using a `switch` statement when the flow either completes successfully or returns with an error. The SDK handles both responses through the `SocureDocVSDK.launch(options)` function.

#### Success

If the consumer successfully completes the flow and the captured images are uploaded to Socure's servers, the `result` is `.success` and a message containing the `deviceSessionToken` is printed. This result contains a `deviceSessionToken`, a unique identifier for the session that can be used for accessing device details about the specific session.

Swift

```swift
public struct SocureDocVSuccess {
    public let deviceSessionToken: String?
}
```

#### Failure

If the consumer exits the flow without completing it or an error occurs, the `result` is `.failure` and a message is printed with the `deviceSessionToken` and specific error details.

Swift

```swift
public struct SocureDocVFailure: Error {
    public let error: SocureDocVError
    public let deviceSessionToken: String?
}
```

When the DocV SDK returns a failure, it provides a `SocureDocVError` enum with specific error cases relevant to the Capture App flow:

Swift

```swift
public enum SocureDocVError {
    case sessionInitiationFailure
    case sessionExpired
    case invalidPublicKey
    case invalidDocvTransactionToken
    case noInternetConnection
    case documentUploadFailure
    case userCanceled
    case consentDeclined
    case cameraPermissionDeclined
    case unknown
}
```

The following table lists the error values that can be returned by the `SocureDocVError` enum:

| Enum Case | Error Description |
| --- | --- |
| `sessionInitiationFailure` | Failed to initiate the session |
| `sessionExpired` | Session expired |
| `invalidPublicKey` | Invalid or missing SDK key |
| `invalidDocvTransactionToken` | Invalid transaction token |
| `noInternetConnection` | No internet connection |
| `documentUploadFailure` | Failed to upload the documents |
| `userCanceled` | Scan canceled by the user |
| `consentDeclined` | Consent declined by the user |
| `cameraPermissionDeclined` | Permissions to open the camera declined by the user |
| `unknown` | Unknown error |

> 📘
>
> **Note**:
>
> The SocureDocV SDK also returns the backend API error codes and messages as received (for example, **access denied** or **insufficient permission**).

## Step 3: Receive the verification results

After the consumer finishes the document capture and upload process with the Capture App, RiskOS™ runs the evaluation process and returns the results in the `evaluation_completed` webhook event. The DocV verification results are included in the `data_enrichments` array within the payload.

Alternatively, you can fetch the RiskOS™ results by making a `GET` request to the `[/api/evaluation](https://help.socure.com/riskos/reference/postevaluation#/)` endpoint.

Example webhook event: RiskOS™ evaluation outcome

```json
{
  "data": {
    "decision": "REVIEW",
    "decision_at": "2025-04-08T18:27:31.924196163Z",
    "environment_name": "",
    "eval_at": "2025-04-08T18:27:31.924196043Z",
    "eval_id": "8770e076-f568-48a9-8201-dca13087e592",
    "eval_source": "API",
    "evaluation_status": "evaluation_completed",
    "id": "abc-test-123",
    "notes": "Test Notes",
    "reason_codes": ["test"],
    "review_queues": ["Default Queue"],
    "status": "OPEN",
    "sub_status": "Surveillance",
    "tags": ["test"],
    "data_enrichments": [
      {
        "enrichment_name": "Socure Document Request",
        "enrichment_endpoint": "https://service.socure.com/api/5.0/documents/request",
        "enrichment_provider": "SocureDocRequest",
        "status_code": 200,
        "request": {
          "country": "US",
          "firstName": "John",
          "surName": "Smith"
        },
        "response": {
          "data": {
            "docvTransactionToken": "9979eda7-9694-476d-ab8b-e6bbc0153dc3",
            "eventId": "9979eda7-9694-476d-ab8b-e6bbc0153dc3",
            "qrCode": "data:image/png;base64,iVBO......K5CYII=",
            "url": "https://verify.socure.com/#/dv/9979eda7-9694-476d-ab8b-e6bbc0153dc3"
          },
          "referenceId": "b902702f-a07a-4180-acdd-20266f776ba3"
        },
        "is_source_cache": false,
        "total_attempts": 1
      },
      {
        "enrichment_name": "Socure Predictive Document Verification Prod",
        "enrichment_endpoint": "https://service.socure.com/api/3.0/EmailAuthScore",
        "enrichment_provider": "Socure",
        "status_code": 200,
        "request": {
          "country": "US",
          "docvTransactionToken": "9979eda7-9694-476d-ab8b-e6bbc0153dc3",
          "firstName": "John",
          "modules": ["documentverification"],
          "parentTxnId": "e3c35948-5141-4e3d-836d-31ee7fcc8b8d",
          "surName": "Smith",
          "workflow": "api_consumer_onboarding"
        },
        "response": {
          "documentVerification": {
            "decision": {
              "name": "standard",
              "value": "accept"
            },
            "documentType": {
              "country": "USA",
              "state": "WA",
              "type": "Drivers License"
            },
            "reasonCodes": [
              "I834",
              "I845",
              "I831",
              "I820",
              "I836",
              "I838",
              "R823",
              "R822"
            ]
          },
          "referenceId": "06bf2f66-7d18-47c2-b12f-4be3a30e1d49"
        },
        "is_source_cache": false,
        "total_attempts": 1
      },
      {
        "enrichment_name": "Socure Image Request Prod",
        "enrichment_endpoint": "https://upload.socure.com/api/5.0/documents/{referenceId}",
        "enrichment_provider": "SocureImageRequest",
        "status_code": 200,
        "request": {
          "referenceId": "06bf2f66-7d18-47c2-b12f-4be3a30e1d49"
        },
        "response": {
          "docId": "077bd0be-129e-4352-bb6b-cc07c9a86fdc"
        },
        "is_source_cache": false,
        "total_attempts": 1
      }
    ],
    "workflow": "api_consumer_onboarding",
    "workflow_id": "7ba6948f-502d-446e-a1e5-45d66cc50983",
    "workflow_version": "1.0.0"
  },
  "event_at": "2025-04-08T18:27:31.9244894Z",
  "event_id": "df9252b5-85c8-426e-9590-8f51b6e5b5c0",
  "event_type": "evaluation_completed"
}
```
