# Overview

Welcome to Preventor ID! This documentation will show you how to integrate Preventor into your website, app, and backend and verify your customers.

![Preventor](/files/-MhPBG7Hg8BHboPPsh_i)

#### What is Preventor?

Preventor is a suite of customizable identification tools including liveness detection, document verification, facial recognition, and more. These tools are combined to estimate the authenticity of a user's true identity.&#x20;

#### **How it works**

A **User** submits a video selfie and valid identifying **Resources** during a **Verification** guided by the Preventor client-side integration. Once all the necessary **Resources** are submitted, **Data points** are extracted, digitized, and authenticated. These **Data points** then become part of the **User's Identity**. The **User** then consents to share **Resources** and/or **Data points** from their **Identity** with you. This information is passed to you and can be used to make decisions about a **User** (e.g. activate account).&#x20;

This table below explains our terminology further.

| Term                 | Description                                                                                                                                                                                                                                                                               |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Identity**         | A set of **Data points** and **Resources** related to and owned by one single **User**. This data can be accessed by you through a **Verification**                                                                                                                                       |
| **Resource**         | A source document used to generate the **Data points** for a **User** (E.g. Passport).                                                                                                                                                                                                    |
| **Data point**       | Any data about a **User** extracted from a **Resource** (E.g. Passport Number, or Age).                                                                                                                                                                                                   |
| **User**             | The owner of an **Identity.**                                                                                                                                                                                                                                                             |
| **Verification**     | A transaction through which a **User** consents to share **Data points** with you. If the **Data points** you request are not already available in the **User**'s **Identity**, the Preventor client will ask the **User** to submit the necessary **Resource** required to extract them. |
| **Client-side SDKs** | Language specific packages you can use to integrate Preventor into your website or app (E.g.Android, Web-component) .                                                                                                                                                                     |

{% hint style="info" %}

#### You can find a full list of Data points by checking out [our full API specification here](https://api-reference.preventor.com).

{% endhint %}


# HTML + Javascript

Steps to integrate the Web SDK into HTML and JavaScript application.

## 1. Installation

To install the Preventor Web SDK, add the following to your project:

Add `https://sdk.preventor.com/pvtid/verifyme/verifyme.esm.js` as a script.

```html
<script
    type="module"
    src="https://sdk.preventor.com/pvtid/verifyme/verifyme.esm.js"
></script>
```

{% hint style="success" %}
You have successfully installed the Preventor Web SDK!
{% endhint %}

## 2. Choose how you would like to integrate the verifyme

{% tabs %}
{% tab title="Built-in button UI (pvt-button)" %}
Integrating with verifyme through pvt-button is the easiest way to integrate.

1. Add `pvt-button` tag in your HTML.

<pre class="language-html"><code class="lang-html"><strong>&#x3C;pvt-button>&#x3C;/pvt-button>
</strong></code></pre>

2. Set your [configuration](#3.-prefilling-configs)

```javascript
window.PvtVerifymeConfig = YOUR_CONFIGURATION;
```

3. A complete `HTML`file should look similar to the example below.

```html
<!DOCTYPE html>
<html lang="en">
  <body>
    <pvt-button></pvt-button>

    <script
        type="module"
        src="https://sdk.preventor.com/pvtid/verifyme/verifyme.esm.js"
    ></script>
    <script>
      // Your configuration
      // For more details refer to the "Prefilling configs" section
      window.PvtVerifymeConfig = {
        credentials: {
          apiKey: 'YOUR_API_KEY',
          clientSecret: 'YOUR_CLIENT_SECRET',
          tenant: 'YOUR_TENANT',
          banknu: 'YOUR_BANKNU',
          env: 'YOUR_ENV',
        },
      };
    </script>
  </body>
</html>
```

<img src="/files/paCN1VKcFysPJr11wk0p" alt="" data-size="original">
{% endtab %}

{% tab title="pvt-verifyme" %}
Integrating with verifyme through pvt-verifyme is the most customizable option.

You can initiate the verification process by executing the open() function from any HTML tag. For example, you can start the process from a sidebar icon or a custom button.

> It is recommended to provide a visual indicator to the user that the component has been loaded, and you can use the 'loaded' event for this purpose.

1. Add `pvt-verifyme` tag in your HTML.

<pre class="language-html"><code class="lang-html"><strong>&#x3C;pvt-verifyme>&#x3C;/pvt-verifyme>
</strong></code></pre>

2. Set your [configuration](#3.-prefilling-configs)

```javascript
window.PvtVerifymeConfig = YOUR_CONFIGURATION;
```

3. Call the `open()` method to open the component

```javascript
const pvtVerifyme = document.querySelector('pvt-verifyme');
pvtVerifyme.open();
```

4. `pvt-verifyme` provides a loaded event that can be utilized to indicate when the component is being loaded. This event can be helpful, for instance, to enable a button or any other element that will open the component when clicked.&#x20;

```javascript
const button = document.querySelector('button');
button.addEventListener('click', () => pvtVerifyme.open())

pvtVerifyme.addEventListener('loaded', () => {
  button.disabled = false;
});

```

5. A complete `HTML`file should look similar to the example below.

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta charset="utf-8" />
    <title>Preventor, Remote digital identity platform for brokers</title>
  </head>

  <body>
    <button disabled>Click me</button>
    <pvt-verifyme></pvt-verifyme>

    <script
      type="module"
      src="https://sdk.preventor.com/pvtid/verifyme/verifyme.esm.js"
    ></script>
    <script>
      // Your configuration
      // For more details refer to the "Prefilling configs" section
      window.PvtVerifymeConfig = {
        credentials: {
          apiKey: 'YOUR_API_KEY',
          clientSecret: 'YOUR_CLIENT_SECRET',
          tenant: 'YOUR_TENANT',
          banknu: 'YOUR_BANKNU',
          env: 'YOUR_ENV',
        },
      };

      const verifyme= document.querySelector('pvt-verifyme');
      const button = document.querySelector('button');
  
      button.addEventListener('click', () => verifyme.open())

      pvtVerifyme.addEventListener('loaded', () => {
        button.disabled = false;
      });
    </script>
  </body>
</html>
```

{% endtab %}
{% endtabs %}

You can find your credentials on the [Preventor platform](https://sandbox.preventor.com/)

<div align="left"><figure><img src="/files/Er7IFJJSM7emtyWpIGxC" alt="" width="303"><figcaption><p>Go to settings / integration keys</p></figcaption></figure></div>

<div align="left"><figure><img src="/files/k1lnAVUvrp0cKDaTI55x" alt="" width="375"><figcaption><p>Integration keys</p></figcaption></figure></div>

{% hint style="success" %}
You have successfully Preventor SDK!
{% endhint %}

## 3. Prefilling configs

### Prefill Flowtype

{% hint style="danger" %}
The flow type defines the biometric process so you must select a flow type.
{% endhint %}

```javascript
const YOUR_CONFIGURATION = {
   // SET THE FLOW TYPE
   flowType: 'YOUR_FLOW_TYPE'
};
```

You must assign the flow type code. If it is blank, it will take the flow type by default.

### Prefill Credentials

{% hint style="danger" %}
You must set all credentials values ​​to correctly consume our services.
{% endhint %}

```javascript
const YOUR_CONFIGURATION = {
   flowType: 'YOUR_FLOW_TYPE',
   // SET THE CREDENTIALS
   credentials: {
      apiKey: 'YOUR_API_KEY',
      clientSecret: 'YOUR_CLIENT_SECRET',
      tenant: 'YOUR_TENANT',
      banknu: 'YOUR_BANKNU',
      env: 'YOUR_ENV'
   }
};
```

### Prefill Cif Code

The Cifcode is the unique customer profile code.&#x20;

{% hint style="info" %}
If the Cifcode is empty, a unique code is assigned.
{% endhint %}

```javascript
const YOUR_CONFIGURATION = {
   flowType: 'YOUR_FLOW_TYPE',
   credentials: {
      apiKey: 'YOUR_API_KEY',
      clientSecret: 'YOUR_CLIENT_SECRET',
      tenant: 'YOUR_TENANT',
      banknu: 'YOUR_BANKNU',
      env: 'YOUR_ENV'
   },
   // SET THE CIF CODE
   currentUserInfo: {
      cifCode: 'YOUR_CIFCODE'
   },
};
```

### Prefill Desk Verification Enabled

The skipStartPage skips the start page. It's false by default

```javascript
const YOUR_CONFIGURATION = {
   flowType: 'YOUR_FLOW_TYPE',
   credentials: {
      apiKey: 'YOUR_API_KEY',
      clientSecret: 'YOUR_CLIENT_SECRET',
      tenant: 'YOUR_TENANT',
      banknu: 'YOUR_BANKNU',
      env: 'YOUR_ENV'
   },
   currentUserInfo: {
      cifCode: 'YOUR_CIFCODE'
   },
   // 4. SET SKIP START PAGE ENABLED
   skipStartPage: true
};
```

### Prefill Broker ID

Broker ID to be used in verification.

```javascript
const YOUR_CONFIGURATION = {
   flowType: 'YOUR_FLOW_TYPE',
   credentials: {
      apiKey: 'YOUR_API_KEY',
      clientSecret: 'YOUR_CLIENT_SECRET',
      tenant: 'YOUR_TENANT',
      banknu: 'YOUR_BANKNU',
      env: 'YOUR_ENV'
   },
   currentUserInfo: {
      cifCode: 'YOUR_CIFCODE'
   },
   skipStartPage: true,
   // SET BROKER ID
   brokerId: 'YOUR_BROKER_ID'
};
```

### Prefill Events

It is an object that allows you to pass some callbacks to handle events of Preventor SDK.

```javascript
const YOUR_CONFIGURATION = {
   flowType: 'YOUR_FLOW_TYPE',
   credentials: {
      apiKey: 'YOUR_API_KEY',
      clientSecret: 'YOUR_CLIENT_SECRET',
      tenant: 'YOUR_TENANT',
      banknu: 'YOUR_BANKNU',
      env: 'YOUR_ENV'
   },
   currentUserInfo: {
      cifCode: 'YOUR_CIFCODE'
   },
   skipStartPage: true,
   brokerId: 'YOUR_BROKER_ID',
   // SET EVENTS LISTENER
   events: {
      onStart: () => console.log('onStart'),
      onSubmitted: (data) => console.log('onSubmitted', data),
      onFinish: (data) => console.log('onFinish', data),
      onError: code => console.log('onError', code),
   }
};
```

## Handling Verifications

To find out if a user has completed the verification process, canceled it or there was an error. To do this, you can implement the following callback methods:

| Method        | Description                                                                                                                                                                                                                 |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `onStart`     | This callback method is triggered once a user starts the verification flow.                                                                                                                                                 |
| `onSubmitted` | Method that is being called once verification data is submitted to Preventor. This event emits the following data: cifCode, ticketId, [flowStatus](#flow-status-codes), and [dispositionStatus](#disposition-status-codes). |
| `onFinish`    | Method that is being called once a user clicks the "Finish" button. This event emits the same data as the `onSubmitted` event.                                                                                              |
| `onError`     | This callback method fires when a user canceled the verification flow, the verification ended with an error, or the user performed an incorrect process. You can use this to find out the reason for the error.             |

## Codes

### Error codes

| Code                              | Description                                                                                        |
| --------------------------------- | -------------------------------------------------------------------------------------------------- |
| CANCELLED\_BY\_USER               | The user cancelled the process before completion.                                                  |
| BIOMETRIC\_AUTHENTICATION\_FAILED | The user's biometric authentication failed.                                                        |
| SESSION\_EXPIRED                  | The user's session timed out before completion.                                                    |
| BAD\_STEP\_BY\_USER               | The user made an error or incorrect input during the process.                                      |
| MISSING\_PARAMETERS               | Required parameters were missing from the request or input.                                        |
| CLIENT\_NOT\_FOUND                | The client did not complete the enrollment process before performing the biometric authentication. |
| TIME\_OUT                         | The request or process timed out before completion.                                                |

### Disposition status codes

| Code             | Description                                                    |
| ---------------- | -------------------------------------------------------------- |
| PASSED           | Verification process passed successfully.                      |
| FAILED           | Verification process failed.                                   |
| PENDING          | Verification process is still pending.                         |
| RETRY            | Verification process failed and can be retried.                |
| PROCESSING       | Verification process is being processed by a server operation. |
| NEED\_REVIEW     | Verification process is awaiting manual review by a user.      |
| TIMEOUT          | Verification process timed out.                                |
| LOGGED\_OUT      | User logged out during the verification process.               |
| LOST\_CONNECTION | Connection to server lost during the verification process.     |
| QUIT             | User quit the verification process.                            |

<br>

### Flow status codes

| Code         | Description                                                                                            |
| ------------ | ------------------------------------------------------------------------------------------------------ |
| IN\_PROGRESS | Verification process is in progress.                                                                   |
| ACCEPTED     | Verification process has been accepted.                                                                |
| REJECTED     | Verification process has been rejected.                                                                |
| ABANDONED    | Verification process has been abandoned (not completed due to some reason, such as user dropping off). |


# Angular

Steps to integrate the Web SDK into Angular application.

## 1. Installation

To install the Preventor Web SDK,  add the following to your project’s:

1. &#x20;Install the latest version from NPM.

```shell
npm i @preventor/ngx-pvt-button
```

2\. Import the `NgxPvtButtonModule` module.

```typescript
import { NgxPvtButtonModule } from '@preventor/ngx-pvt-button';

@NgModule({
  imports: [
    // ...
    NgxPvtButtonModule
  ]
})
export class MyModule {}

```

3\. Add `ngx-pvt-button` tag in your HTML

```html
<ngx-pvt-button [config]="YOUR_CONFIGURATION"></ngx-pvt-button>
```

{% hint style="success" %}
You have successfully installed the Preventor Web SDK!
{% endhint %}


# React

Steps to integrate the Web SDK into React application.

## 1. Installation

To install the Preventor Web SDK,  add the following to your project’s:

1. Add `https://sdk.preventor.com/pvtid/verifyme/verifyme.esm.js` in your `public/index.html`.

```html
<script
    type="module"
    src="https://sdk.preventor.com/pvtid/verifyme/verifyme.esm.js"
></script>
```

2\. Setup the button in your component file

```tsx
import React, { useEffect, useRef } from "react";

export default function App() {
  const pvtButtonRef = useRef(null);
  useEffect(() => {
    window.PvtVerifymeConfig = YOUR_CONFIGURATION;
  }, []);

  return <pvt-button ref={pvtButtonRef}></pvt-button>;
}
```

{% hint style="success" %}
You have successfully installed the Preventor Web SDK!
{% endhint %}


# Vue.js

Steps to integrate the Web SDK into Vue application.

## 1. Installation

To install the Preventor Web SDK, add the following to your project’s:

1. &#x20;Add `https://sdk.preventor.com/pvtid/verifyme/verifyme.esm.js` in your `public/index.html`.

```html
<script
    type="module"
    src="https://sdk.preventor.com/pvtid/verifyme/verifyme.esm.js"
></script>
```

2\. Ignore the custom tag `pvt-button` in your `main.js` file

```typescript
Vue.config.ignoredElements = [/pvt-button/]; // ignore the pvt-button tag

new Vue({
  render: h => h(App)
}).$mount("#app");
```

3\. Setup the button in your component file

```html
<template>
  <div id="app">
    <pvt-button></pvt-button>
  </div>
</template>

<script>
export default {
  name: "App",
  mounted: function () {
    window.PvtVerifymeConfig = YOUR_CONFIGURATION;
  },
};
</script>
```

{% hint style="success" %}
You have successfully installed the Preventor Web SDK!
{% endhint %}


# iOS

## 1. Installation

How to install Preventor iOS SDK

* [Requirements](#parte2)
* [Install via CocoaPods](#install-via-cocoapods)
* [Install via Swift Package Manager](#install-via-swift-package-manager)

### **Requirements**

The latest stable version of [Xcode](https://developer.apple.com/xcode/), since the SDK is written in Swift 5.7.1

Minimum target: iOS 13.0.

### Install via CocoaPods

To always use the latest release, add the following to your Podfile:

```objectivec
pod 'PreventorSDK'
```

Alternatively, pin to a specific version (e.g. 0.2.2):

```objectivec
pod 'PreventorSDK', '2.1.0'
```

And then [run](https://guides.cocoapods.org/using/pod-install-vs-update.html):&#x20;

```shell
pod install
```

### Install via Swift Package Manager

```swift
import PackageDescription

let package = Package(
  name: "YourTestProject",
  platforms: [
       .iOS(.v13),
  ],
  dependencies: [
    .package(name: "PreventorSDK", url: "https://github.com/preventorid/button-ios-sdk.git", from: "2.1.0)
  ],
  targets: [
    .target(name: "YourTestProject", dependencies: ["PreventorSDK"])
  ]
)
```

#### **Adding it to an existent iOS Project via Swift Package Manager**

1. Using Xcode go to File > Swift Packages > Add Package Dependency
2. Paste the project URL: <https://github.com/preventorid/button-ios-sdk.git>
3. Click on next and select the project target
4. Don't forget to set `DEAD_CODE_STRIPPING = NO` in your `Build Settings` (<https://bugs.swift.org/plugins/servlet/mobile#issue/SR-11564>)

## 2. Initialize SDK

For integration, you need to configure the pre-padding shown below. You must first implement the `PSDKConfig` structure.

### Credential prefill

```swift
self.config = PSDKConfig(flowID: "YOUR_FLOW_ID",
                         cifCode: "YOUR_CIFCODE",
                         apiKey: "YOUR_API_KEY",
                         tenant: "YOUR_TENANT",
                         env: "YOUR_ENV",
                         banknu: "YOUR_BANKNU",
                         secret: "YOUR_CLIENT_SECRET",
                         invitation: "YOUR_INVITATION_ID",
                         broker: "YOUR_BROKER")
```

{% hint style="info" %}
If the cifCode is empty or nil, a unique code is assigned.
{% endhint %}

<table><thead><tr><th>Value</th><th>Description</th><th data-hidden></th></tr></thead><tbody><tr><td>YOUR_FLOW_ID</td><td>Defines the biometric process</td><td></td></tr><tr><td>UNIQUE_CUSTOMER_CODE</td><td>Is the unique customer profile code.</td><td></td></tr><tr><td>YOUR_API_KEY</td><td>Your provided apikey.</td><td></td></tr><tr><td>YOUR_CLIENT_SECRET</td><td>Your provided clientsecret.</td><td></td></tr><tr><td>YOUR_TENANT</td><td>Your provided tenant.</td><td></td></tr><tr><td>YOUR_BANKNU</td><td>Your provided banknu.</td><td></td></tr><tr><td>YOUR_ENV</td><td>Your provided env.</td><td></td></tr><tr><td>YOUR_INVITATION_ID</td><td>Your invitation ID</td><td></td></tr><tr><td>YOUR_BROKER</td><td>Your broker</td><td></td></tr></tbody></table>

To initialize the SDK, you need to call the initialize(config: PSDKConfig) method:

```swift
self.config = PSDKConfig(flowID: "YOUR_FLOW_ID",
                         cifCode: "YOUR_CIFCODE",
                         apiKey: "YOUR_API_KEY",
                         tenant: "YOUR_TENANT",
                         env: "YOUR_ENV",
                         banknu: "YOUR_BANKNU",
                         secret: "YOUR_CLIENT_SECRET",
                         invitation: "YOUR_INVITATION_ID",
                         broker: "YOUR_BROKER")
PSDK.shared.initialize(config: config)
```

## &#x20;3. Start the Verification

To start a new verification, you first need to create the `PreventorButton`

### Add Button via Storyboard

Two simple steps to get the button running:

1. Drag a new button on your storyboard and give it your desired constraints.
2. Subclass the button as `PreventorButton`. Ensure that the module also says `PreventorSDK` below the class.

![](/files/JKhbwQhrXbdGVReClxVO)

### Add PreventorButton in your project programmatically

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

```swift
import SwiftUI
import PreventorSDK

struct ContentView: View {
    
    @ObservedObject var store: ContentViewModel
    let config: PSDKConfig
    
    var body: some View {
        PreventorButton()
    }
    
    init() {
        self.config = PSDKConfig(flowID: "YOUR_FLOW_ID",
                                 cifCode: "YOUR_CIFCODE",
                                 apiKey: "YOUR_API_KEY",
                                 tenant: "YOUR_TENANT",
                                 env: "YOUR_ENV",
                                 banknu: "YOUR_BANKNU",
                                 secret: "YOUR_CLIENT_SECRET",
                                 invitation: "YOUR_INVITATION_ID",
                                 broker: "YOUR_BROKER")
        PSDK.shared.initialize(config: config) { isSuccessful in
             //your code
        }
    }
}

class ContentViewModel: ObservableObject, PSDKDelegate {
    //YOUR IMPLEMENTATION
    func updatePreventorSDKDelegate() {
        PSDK.shared.delegate = self
    }

    func onStart() {
        print("onStart")
    }
    
    func onFinish(result: PSDKResult) {
        print("onFinish")
    }
    
    func onError(error: PSDKErrorCode) {
        print("error:", error.rawValue)
    }
    
    func onSubmitted(result: PSDKResult) {
        print("onSubmitted")
    }
    
}
```

{% endtab %}

{% tab title="Swift" %}

```swift
import UIKit
import PreventorSDK

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Add the button with dimensions
        let button = UIPreventorButton(frame: CGRect(x: 40, y: 90, width: 300, height: 60))
        self.view.addSubview(button)
        
        // Or Add button with autolayout support
        let button = UIPreventorButton(frame: .zero)
        button.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(button)
        let buttonConstraints = [
                button.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 50.0),
                button.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -50.0),
                button.topAnchor.constraint(lessThanOrEqualTo: self.view.topAnchor, constant: 60.0),
                button.heightAnchor.constraint(equalToConstant: 40),
        ]
        NSLayoutConstraint.activate(buttonConstraints)
        updatePreventorSDKDelegate()
    }
    
}

extension ViewController: PSDKDelegate {
    //YOUR IMPLEMENTATION
    func updatePreventorSDKDelegate() {
        PSDK.shared.delegate = self
    }

    func onStart() {
        print("onStart")
    }
    
    func onFinish(result: PSDKResult) {
        print("onFinish")
    }
    
    func onError(error: PSDKErrorCode) {
        print("error:", error.rawValue)
    }
    
    func onSubmitted(result: PSDKResult) {
        print("onSubmitted")
    }
    
}
```

{% endtab %}
{% endtabs %}

### Start Verification

To start a check, just click the PreventorButton

### Adjust Your App's Permissions

<figure><img src="/files/yZ47H9Y0heZiRFe0THyc" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
If you made it until here, you've successfully installed the Preventor SDK for iOS. Now let's adjust your last settings and start your first verification.
{% endhint %}

Please add the following permissions to your app's `Info.plist`, so that the Preventor iOS SDK can access a user's camera to run a verification. You can do this in the property list view or by code.

Right-click somewhere outside the table and select `Add Row`. Now add the entries like below.

Or if you prefer to do this step with code, right-click on `Info.plist` and select Open As -> Source Code. Add the lines below somewhere inside the `<dict>   </dict>`

```xml
<!-- permission strings to be include in info.plist -->
<key>NSCameraUsageDescription</key>
<string>Please give us access to your camera, to complete the verification.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Please give us access to your location to complete the verification.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Please give us access to your location to complete the verification.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Please give us access to your photo library to verify you.</string>
<key>NFCReaderUsageDescription</key>
<string>Give us NFC access to complete verification.</string>
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
	<string>TAG</string>
</array>
<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
<array>
	<string>A0000002471001</string>
	<string>E80704007F00070302</string>
	<string>A000000167455349474E</string>
	<string>A0000002480100</string>
	<string>A0000002480200</string>
	<string>A0000002480300</string>
	<string>A00000045645444C2D3031</string>
</array>
```

{% hint style="success" %}
You have successfully finished setting up the `Preventor` iOS SDK! 🎉
{% endhint %}

### Customization

If you want to add your own customization you can use the following methods

<table><thead><tr><th>Method</th><th>Description</th></tr></thead><tbody><tr><td><pre><code>setNavigationTitle
</code></pre></td><td>Use this method to change the navigation title of the SDK.</td></tr></tbody></table>

## 4. Handling Verifications

To find out if a user started, completed, canceled or failed the verification process, you can implement the following delegate methods:

<table><thead><tr><th>Method</th><th width="179">Description</th><th data-hidden></th></tr></thead><tbody><tr><td><code>onStart</code></td><td>This callback method is triggered once a user starts the verification flow. </td><td></td></tr><tr><td><code>onSubmitted</code></td><td>Method that is being called once verification data is submitted to Preventor.</td><td></td></tr><tr><td><code>onFinish</code></td><td>Method that is being called once a user clicks the "Finish" button.</td><td></td></tr><tr><td><code>onError</code></td><td><p>This callback method fires when a user canceled the verification flow, the verification ended with an error, or the user performed an incorrect process. You can use this to find out the reason for the error.</p><p>Error codes: </p><p><code>CANCELLED_BY_USER</code></p><p><code>BIOMETRIC_AUTHENTICATION_FAILED</code></p><p><code>BAD_STEP_BY_USER MISSING_PARAMETERS</code></p></td><td></td></tr><tr><td><code>onNextStep</code></td><td>This callback method is called when the SDK is ready to move on to the next check.</td><td></td></tr></tbody></table>

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

```swift
import SwiftUI
import PreventorSDK


struct ContentView: View {
    
    @ObservedObject var store: ContentViewModel
    let config: PSDKConfig
    
    var body: some View {
        PreventorButton()
    }
    
    init() {
        self.config = PSDKConfig(flowID: "YOUR_FLOW_ID",
                                 cifCode: "YOUR_CIFCODE",
                                 apiKey: "YOUR_API_KEY",
                                 tenant: "YOUR_TENANT",
                                 env: "YOUR_ENV",
                                 banknu: "YOUR_BANKNU",
                                 secret: "YOUR_CLIENT_SECRET",
                                 invitation: "YOUR_INVITATION_ID",
                                 broker: "YOUR_BROKER")
        PSDK.shared.initialize(config: config) { isSuccessful in
             //your code
        }
    }
}

class ContentViewModel: ObservableObject, PSDKDelegate {
    //YOUR IMPLEMENTATION
    func updatePreventorSDKDelegate() {
        PSDK.shared.delegate = self
    }

    func onStart() {
        print("onStart")
    }
    
    func onFinish(result: PSDKResult) {
        print("onFinish")
    }
    
    func onError(error: PSDKErrorCode) {
        print("error:", error.rawValue)
    }
    
    func onSubmitted(result: PSDKResult) {
        print("onSubmitted")
    }
    
}

```

{% endtab %}

{% tab title="Swift" %}

```swift
import UIKit
import PreventorSDK

class ViewController: UIViewController{
    
    @IBOutlet weak var PreventorButton: UIPreventorButton!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Add the button with dimensions
        let button = UIPreventorButton(frame: CGRect(x: 40, y: 90, width: 300, height: 60))
        self.view.addSubview(button)
        
        // Or Add button with autolayout support
        let button = UIPreventorButton(frame: .zero)
        button.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(button)
        let buttonConstraints = [
                button.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 50.0),
                button.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -50.0),
                button.topAnchor.constraint(lessThanOrEqualTo: self.view.topAnchor, constant: 60.0),
                button.heightAnchor.constraint(equalToConstant: 40),
        ]
        NSLayoutConstraint.activate(buttonConstraints)
        
        let config = PSDKConfig(flowID: "YOUR_FLOW_TYPE",
                                 cifCode: "YOUR_CIFCODE",
                                 apiKey: "YOUR_API_KEY",
                                 tenant: "YOUR_TENANT",
                                 env: "YOUR_ENV",
                                 banknu: "YOUR_BANKNU",
                                 secret: "YOUR_CLIENT_SECRET")
        updatePreventorSDKDelegate()
        PSDK.shared.initialize(config: config)
    }
    
}

extension ViewController: PSDKDelegate {
    //YOUR IMPLEMENTATION
    func updatePreventorSDKDelegate() {
        PSDK.shared.delegate = self
    }

    func onStart() {
        print("onStart")
    }
    
    func onFinish(result: PSDKResult) {
        print("onFinish")
    }
    
    func onError(error: PSDKErrorCode) {
        print("error:", error.rawValue)
    }
    
    func onSubmitted(result: PSDKResult) {
        print("onSubmitted")
    }
    
}
```

{% endtab %}
{% endtabs %}


# Android

## 1. Install the Gradle Plugin

To install the Preventor Android SDK,  add the following to your project’s `build.gradle` file:

1. Use minSdkVersion 23 in your `build.gradle (Module:app)`
2. Add implementation `'com.preventor:preventor_sdk:2.0.73-alpha'` to your dependencies.
3. Add repository depencencies in your `build.gradle (Project Settings)`
4. In your `build.gradle (Project: app)`. Make sure you have the same version or higher `"org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10"` plugin.&#x20;
5. In your `gradle.properties (Project Properties)` add this line `android.enableJetifier=true`

A complete `build.gradle`file should look similar to the example below.

```groovy
android {
    // 1. Ensure you have hat least minSdkVersion 23
    compileSdkVersion 32
    defaultConfig {
        applicationId "com.preventor.example"
        minSdkVersion 23
        targetSdkVersion 32
        versionCode 1
        versionName "1.0.0"
    }
}

dependencies {
  ... 
  // 2. Add line here  
  implementation 'com.preventor:preventor_sdk:2.0.10-alpha'
}
```

```groovy
// 3.
    repositories {
        jcenter()
        maven { url "https://jitpack.io" }
        maven { url 'https://button.preventor.com/__android/v2'}
    }
```

{% hint style="success" %}
You have successfully installed the Preventor SDK!
{% endhint %}

## 2. Initialize the SDK

Initialize the SDK. See the coding example below:

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

```kotlin
package com.preventor.example

// 1. Add import of Preventor SDK
import com.preventor.pvtidentityverification.PreventorSDK


class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        // 2. Set the context to parameters "activity" and "ViewModelStoreOwner"
        val preventorSDK = PreventorSDK(this, this)
    }
}
```

{% endtab %}

{% tab title="Java" %}

```java
package com.preventor.example;

// 1. Add import of Preventor SDK
import com.preventor.pvtidentityverification.PreventorSDK;


public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        // 2. Set the context to parameters "activity" and "ViewModelStoreOwner"
        PreventorSDK preventorSDK = new PreventorSDK(this,this);
    }
}
```

{% endtab %}
{% endtabs %}

{% hint style="success" %}
You have successfully initialize the Preventor SDK!
{% endhint %}

## 3. Prefilling configs

To continue with the integration you need to set the prefill shown below. First you must obtain the config object by calling `getConfig()` method.

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

```kotlin
package com.preventor.example

import com.preventor.pvtidentityverification.PreventorSDK

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        val preventorSDK = PreventorSDK(this, this)

        // 1. GET CONFIG OBJECT 
         val config = preventorSDK.getConfig()
    }
}
```

{% endtab %}

{% tab title="Java" %}

```java
package com.preventor.example;

import com.preventor.pvtidentityverification.PreventorSDK;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        PreventorSDK preventorSDK = new PreventorSDK(this,this);
        
          // 1. GET CONFIG OBJECT 
          Config config = preventorSDK.getConfig();
    }
}
```

{% endtab %}
{% endtabs %}

### Prefill Flowtype

{% hint style="danger" %}
The flow type defines the biometric process so you must select a flow type.
{% endhint %}

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

```kotlin
package com.preventor.example

import com.preventor.pvtidentityverification.PreventorSDK

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        preventorSDK = PreventorSDK(this, this)

                
         val config = preventorSDK.getConfig()

        // 1. SET THE FLOW TYPE
        config.flowId = "YOUR_FLOW_ID"
    }
}
```

{% endtab %}

{% tab title="Java" %}

```java
package com.preventor.example;

import com.preventor.pvtidentityverification.PreventorSDK;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        PreventorSDK preventorSDK = new PreventorSDK(this,this);
         
         
         Config config = preventorSDK.getConfig();
         
          // 1. SET THE FLOW TYPE
        config.setFlowId("YOUR_FLOW_ID");
    }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
You must assign the flow type code. If it is blank, it will take the flow type by default.
{% endhint %}

### Prefill Credentials

{% hint style="danger" %}
You must set all credentials values ​​to correctly consume our services.
{% endhint %}

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

```kotlin
package com.preventor.example

import com.preventor.pvtidentityverification.PreventorSDK

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        preventorSDK = PreventorSDK(this, this)

                
         val config = preventorSDK.getConfig()

        
         config.flowId= "YOUR_FLOW_ID"
        
        // 2. SET THE CREDENTIALS    
        config.credentials.apiKey = "YOUR_API_KEY"
        config.credentials.clientSecret = "YOUR_CLIENT_SECRET"
        config.credentials.tenant = "YOUR_TENANT"
        config.credentials.banknu = "YOUR_BANKNU"
        config.credentials.env = "YOUR_ENV"
    }
}
```

{% endtab %}

{% tab title="Java" %}

```java
package com.preventor.example;

import com.preventor.pvtidentityverification.PreventorSDK;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        PreventorSDK preventorSDK = new PreventorSDK(this,this);
         
         
         Config config = preventorSDK.getConfig();
         
          
        config.setFlowId("YOUR_FLOW_ID");
        
        // 2. SET THE CREDENTIALS
        config.getCredentials().setApiKey("YOUR_API_KEY");
        config.getCredentials().setClientSecret("YOUR_CLIENT_SECRET");
        config.getCredentials().setTenant("YOUR_TENANT");
        config.getCredentials().setBanknu("YOUR_BANKNU");
        config.getCredentials().setEnv("YOUR_ENV");
    }
}
```

{% endtab %}
{% endtabs %}

| Value                | Description                 |
| -------------------- | --------------------------- |
| YOUR\_API\_KEY       | your provided apikey.       |
| YOUR\_CLIENT\_SECRET | your provided clientsecret. |
| YOUR\_TENANT         | your provided tenant.       |
| YOUR\_BANKNU         | your provided banknu.       |
| YOUR\_ENV            | your provided env.          |

### Prefill Cif Code

The Cifcode is the unique customer profile code.&#x20;

&#x20;

{% hint style="info" %}
If the Cifcode is empty, a unique code is assigned.
{% endhint %}

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

```kotlin
package com.preventor.example

import com.preventor.pvtidentityverification.PreventorSDK

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        preventorSDK = PreventorSDK(this, this)

                
         val config = preventorSDK.getConfig()

        
        config.flowId= "YOUR_FLOW_ID"
           
        config.credentials.apiKey = "YOUR_API_KEY"
        config.credentials.clientSecret = "YOUR_CLIENT_SECRET"
        config.credentials.tenant = "YOUR_TENANT"
        config.credentials.banknu = "YOUR_BANKNU"
        config.credentials.env = "YOUR_ENV"
        
        // 3. SET THE CIF CODE
        config.currentUserInfo.cifCode = "YOUR_CIFCODE"
    }
}
```

{% endtab %}

{% tab title="Java" %}

```java
package com.preventor.example;

import com.preventor.pvtidentityverification.PreventorSDK;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        PreventorSDK preventorSDK = new PreventorSDK(this,this);
         
         
         Config config = preventorSDK.getConfig();
         
          
        config.setFlowId("YOUR_FLOW_ID");

        config.getCredentials().setApiKey("YOUR_API_KEY");
        config.getCredentials().setClientSecret("YOUR_CLIENT_SECRET");
        config.getCredentials().setTenant("YOUR_TENANT");
        config.getCredentials().setBanknu("YOUR_BANKNU");
        config.getCredentials().setEnv("YOUR_ENV");
        
        // 3. SET THE CIF CODE
        config.getCurrentUserInfo().setCifCode("YOUR_CIFCODE");
    }
}
```

{% endtab %}
{% endtabs %}

### Prefill Title App Bar

Define an app title that indicates the process to be performed.

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

```kotlin
preventorSDK.setTitleAppBar("YOUR_TITLE_APP_BAR")
```

{% endtab %}

{% tab title="Java" %}

```java
preventorSDK.setTitleAppBar("YOUR_TITLE_APP_BAR")
```

{% endtab %}
{% endtabs %}

## 4. Start the Verification

To start a new verification, you first need to create the preventor verification button.

### Add Button in your XML

```xml
 <com.preventor.pvtidentityverification.widgets.PreventorButton
        android:id="@+id/identityVerificationButton"
        android:layout_width="161dp"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />
```

### Start Verification

To start a verification, prepare the following:

1. Add the reference to verification button.
2. Call `initialize()` method to start the preventorSDK.
3. Call `validateApiKey()` method to start the verification.

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

```kotlin
// 1. Add verification button reference.

val identityVerificationButton = findViewById<PreventorButton>(R.id.identityVerificationButton)

// 2. Call initialize() method.
preventorSDK.initialize()

// 3. Call validateApiKey() method.
identityVerificationButton.setOnClickListener {
    preventorSDK.validateApiKey()
}
```

{% endtab %}

{% tab title="Java" %}

```java
// 1. Add verification button reference.
PreventorButton identityVerificationButton = findViewById(R.id.identityVerificationButton);

// 2. Call initialize() method.
preventorSDK.initialize();

// 3. Call validateApiKey() method.
identityVerificationButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        preventorSDK.validateApiKey();
    }
});
```

{% endtab %}
{% endtabs %}

To start verification you can also use this call `validateApiKey()` anywhere in your code when all necessary resources have already been completed.

## 5. Handling Verifications

To find out if a user has completed the verification process, canceled it or there was an error. To do this, you can implement the following delegate / callback methods:

| Method        | Description                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `onStart`     | This callback method is triggered once a user starts the verification flow.                                                                                                                                                                                                                                                                                                                                                                        |
| `onSubmitted` | Method that is being called once verification data is submitted to Preventor.                                                                                                                                                                                                                                                                                                                                                                      |
| `onFinish`    | Method that is being called once a user clicks the "Finish" button.                                                                                                                                                                                                                                                                                                                                                                                |
| `onError`     | <p>This callback method fires when a user canceled the verification flow, the verification ended with an error, or the user performed an incorrect process. You can use this to find out the reason for the error.</p><p>Error codes: </p><p><code>CANCELLED\_BY\_USER</code></p><p><code>BIOMETRIC\_AUTHENTICATION\_FAILED</code></p><p><code>BAD\_STEP\_BY\_USER</code> </p><p><code>MISSING\_PARAMETERS</code></p><p><code>TIME\_OUT</code></p> |
| `onNextStep`  | This callback indicates that it is possible to proceed to the next verification                                                                                                                                                                                                                                                                                                                                                                    |
| `onComplete`  | This callback indicates that all necessary resources have already been completed                                                                                                                                                                                                                                                                                                                                                                   |

Should look similar to the example below.

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

```kotlin
preventorSDK.callback(object : PreventorSDKListener {
            override fun onStart() {
                println("MainActivity onStart");
            }

            override fun onFinish(ticked: Ticked) {
                println("MainActivity onFinish");
            }

            override fun onError(error: String) {
                println("MainActivity onError: $error");
            }

            override fun onSubmitted(ticked: Ticked) {
                println("MainActivity onSubmitted");
            }
            override fun onNextStep() {
            println("MainActivity onNextStep");
            }
            
            override fun onComplete() {
            println("MainActivity onComplete");
            }

        })
```

{% endtab %}

{% tab title="Java" %}

```java
preventorSDK.callback(new PreventorSDKListener() {
            @Override
            public void onStart() {
                System.out.println("MainActivity onStart");
            }

            @Override
            public void onFinish(Ticked ticked) {
                System.out.println("MainActivity onFinish");
            }

            @Override
            public void onError(@NonNull String error) {
                System.out.println("MainActivity onError: " + error);
            }

            @Override
            public void onSubmitted(Ticked ticked) {
                System.out.println("MainActivity onSubmitted");
            }
            
            @Override
            public void onNextStep(Ticked ticked) {
                System.out.println("MainActivity onNextStep");
            }
            
            @Override
            public void onComplete(Ticked ticked) {
                System.out.println("MainActivity onComplete");
            }
        });
```

{% endtab %}
{% endtabs %}

When the verification is finished it will return a ticked object in which you can see the results of the verification. Within them take as reference cifcode, ticketId, flowStatus, dispositionStatus.

| Result            | Value                                                                                                                                                          |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| cifcode           | The cifcode is the unique customer profile code.                                                                                                               |
| ticketId          | The ticketId is the unique code of the verification.                                                                                                           |
| flowStatus        | <p>Indicates the general status of the ticket.</p><p>See the following codes:</p><p>ACCEPTED, IN\_PROGRESS, REJECTED, ABANDONED.</p>                           |
| dispositionStatus | <p>Indicates the current disposition of the ticket.</p><p>See the following codes:</p><p>PASSED, NEED\_REVIEW, RETRY, FAILED, PROCESSING, LOST\_CONECCTION</p> |

When the ticket ends in the following combinations, flowStatus and dispositionStatus respectively:

| Status                       | Description                                                                               |
| ---------------------------- | ----------------------------------------------------------------------------------------- |
| ACCEPTED - PASSED            | Verification completed successfully.                                                      |
| IN\_PROGRESS - NEED\_REVIEW  | Verification is complete but there is information to review.                              |
| IN\_PROGRESS - RETRY         | Verification did not complete and requires retry.                                         |
| IN\_PROGRESS -  PASSED       | One step of verification has been completed and you can move on to the next.              |
| REJECTED - FAILED            | Verification has been refused due to negative results.                                    |
| ABANDONED - LOST\_CONECCTION | The verification has failed due to some unhandled error and the connection has been lost. |
| ABANDONED - TIME\_OUT        | Verification failed due to user inactivity.                                               |

## 6. Example project

See the example project below:&#x20;

<https://github.com/preventorid/button-android-sdk-app/tree/main>


# API Reference


# Security

Here you will find all security related APIs

{% openapi src="/files/jPkbdeSW2MEEZRaobF6y" path="/id/v1/identity/auth/token" method="post" %}
[invitations.json](https://1648610820-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MQD7wU34mG7rs7Bz7vm-887967055%2Fuploads%2FRV590VNpExBppVIwbksS%2Finvitations.json?alt=media\&token=e9ac318d-8ee0-4696-87c1-84752a34706e)
{% endopenapi %}


# Invitations link

Integration via identity verification API using invite links

In this document, you will learn how to seamlessly integrate Preventor ID with your system by using invite links for your customers to perform self-service identity verification.

(0) The following flow indicates as a zero step that you should use the configuration platform to configure and customize Preventor ID according to your workflows and business cases.

(1) The first step is tokenized authentication using your credentials.

(2) Then you must register the invitation with the necessary attributes to be able to send the invitation in the shipping method you choose and make the verification link with your client.

(3) Sending the invitation is optional and you can choose to use the link and paste it in your processes or send it through your own channels.

(4) Once the invite link has reached your client, this process should continue with the self-service identity verification process following the instructions of the web-sdk. Preferably on a responsive device, however this is also up to you and can be configured on the platform.

(5) To know when the client is done with the identity verification, you can choose to set up a notification webhook or you can check the invitation status via the API periodically.

(5.1) If the validity time of the invitation expires or you want to make changes to an invitation or delete it, you can do so using the Resend, Edit and Delete APIs

(6) When you have been able to determine that the invitation and identity verification have finished, either by the webhook or by the API query, you will be able to get the results of the identity verification and images using the IDV ticket id, which is part of the results of the invitation.

(7) At this point, you can continue with your business flow and/or you can update your KYC system using the data obtained from the result of the identity verification ticket and the information of your client's identity document.

(8) Finally, Preventor's identity management platform allows you to manage invitations, IDV tickets, and analytics dashboard queries.

<figure><img src="/files/R2B4FDBA3y6mVFqMSOMM" alt=""><figcaption><p>Invitation flow</p></figcaption></figure>

{% openapi src="/files/V8dV4BfiscDmWAg6hA4C" path="/id/v1/identity/invitations/users/register" method="post" %}
[invitations.json](https://1648610820-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MQD7wU34mG7rs7Bz7vm-887967055%2Fuploads%2FzQ8uA64JEfXP6q3wVoRf%2Finvitations.json?alt=media\&token=e1981c3e-3038-4e57-b78b-fbae81f4a04b)
{% endopenapi %}

{% openapi src="/files/V8dV4BfiscDmWAg6hA4C" path="/id/v1/identity/notifications/invitation/{recipient}/send" method="post" %}
[invitations.json](https://1648610820-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MQD7wU34mG7rs7Bz7vm-887967055%2Fuploads%2FzQ8uA64JEfXP6q3wVoRf%2Finvitations.json?alt=media\&token=e1981c3e-3038-4e57-b78b-fbae81f4a04b)
{% endopenapi %}

{% openapi src="/files/V8dV4BfiscDmWAg6hA4C" path="/id/v1/identity/invitations/users/{recipient}" method="delete" %}
[invitations.json](https://1648610820-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MQD7wU34mG7rs7Bz7vm-887967055%2Fuploads%2FzQ8uA64JEfXP6q3wVoRf%2Finvitations.json?alt=media\&token=e1981c3e-3038-4e57-b78b-fbae81f4a04b)
{% endopenapi %}

{% openapi src="/files/V8dV4BfiscDmWAg6hA4C" path="/id/v1/identity/invitations/users/{recipient}" method="patch" %}
[invitations.json](https://1648610820-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MQD7wU34mG7rs7Bz7vm-887967055%2Fuploads%2FzQ8uA64JEfXP6q3wVoRf%2Finvitations.json?alt=media\&token=e1981c3e-3038-4e57-b78b-fbae81f4a04b)
{% endopenapi %}

{% openapi src="/files/V8dV4BfiscDmWAg6hA4C" path="/id/v1/identity/invitations/logs/{invitation\_id}/activities" method="get" %}
[invitations.json](https://1648610820-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MQD7wU34mG7rs7Bz7vm-887967055%2Fuploads%2FzQ8uA64JEfXP6q3wVoRf%2Finvitations.json?alt=media\&token=e1981c3e-3038-4e57-b78b-fbae81f4a04b)
{% endopenapi %}


# IDV Tickets

{% openapi src="/files/jPkbdeSW2MEEZRaobF6y" path="/id/v1/identity/transactions/{ticket}" method="get" %}
[invitations.json](https://1648610820-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MQD7wU34mG7rs7Bz7vm-887967055%2Fuploads%2FRV590VNpExBppVIwbksS%2Finvitations.json?alt=media\&token=e9ac318d-8ee0-4696-87c1-84752a34706e)
{% endopenapi %}

{% openapi src="/files/jPkbdeSW2MEEZRaobF6y" path="/id/v1/identity/transactions/{ticket}/images" method="get" %}
[invitations.json](https://1648610820-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MQD7wU34mG7rs7Bz7vm-887967055%2Fuploads%2FRV590VNpExBppVIwbksS%2Finvitations.json?alt=media\&token=e9ac318d-8ee0-4696-87c1-84752a34706e)
{% endopenapi %}


# Webhooks

This section shows you how our webhook service works, what it delivers and explains its messages.

## Pre-requisites

To properly receive incoming webhooks, your server should provide an endpoint supporting:

* **POST** requests are either **raw** in **text/plain** if message was encrypted by your configured secret or **application/json** if no secret was set&#x20;

You can use a service like e.g. <https://webhook.site/> to test receiving webhooks from your  developer dashboard.

## Security / Encryption

Webhooks are a crucial node to ensure the functionality of your integration, as such, they can be the target of a malicious user aiming to disrupt the service. In order to protect your application from these threats, you must include a **32 bytes-long secret** in your webhook configuration, which will be used to encrypt the request body.

When you enable Encryption, the Webhook message is sent as **text/plain**. Below you'll find an example of how to decipher an incoming webhook request. The cipher initialization vector will be sent over as a **16 bytes** metadata (header) of the response.

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

```typescript
import * as crypto from 'crypto';

export class Decipher {
  decipherAES_256_CBC(request: any) {
    const CIPHER_KEY = 'YOUR-PLAIN-KEY';
    const BASE64_PLAIN_IV = request.headers['x-pvt-cipher-iv'];
    const BASE64_CIPHERED_MESSAGE = request.body;

    const BUFFER_KEY = Buffer.from(CIPHER_KEY);
    const BUFFER_IV = Buffer.from(BASE64_PLAIN_IV, 'base64');
    const BUFFER_CIPHERED_MESSAGE = Buffer.from(BASE64_CIPHERED_MESSAGE, 'base64');

    const DECIPHER = crypto.createDecipheriv('aes-256-cbc', BUFFER_KEY, BUFFER_IV);
    DECIPHER.setAutoPadding(true);

    let deciphered_message = DECIPHER.update(BUFFER_CIPHERED_MESSAGE, 'hex', 'utf8');

    deciphered_message += DECIPHER.final('utf-8');

    return deciphered_message.toString();
  }
}
```

{% endtab %}
{% endtabs %}


# IDV Tickets

<figure><img src="/files/yFcASDAkfdXNHM7vi13L" alt=""><figcaption><p>Ticket webhook trigger</p></figcaption></figure>

## 1. Event Types

Our webhook service supports two **events,** which describe the status of a *flow.* Those are:&#x20;

* **ticket.verification.in\_progress**: your flow has completed a number of steps (subprocesses) and is waiting for user's intervention to continue to next steps or to retry previous failed one.
* **ticket.verification.completed**: your flow has completed its processing. It has been either `ACCEPTED` or `REJECTED`.

## **1.1 Verification - In Progress event**

The *ticket.verification.in\_progress* event is triggered when a *Verification* has completed a number of steps (subprocesses) and it's waiting for user-intervention to continue if it's appropriate. Notification payload specifies a set of properties as shown on following JSON. It will contain its ticket, so it can be tracked by your processes. Also, it holds its **event**, and its **sub\_event,** which will be explained later. The property **flow\_status** determines ticket's current state. The value of the **disposition** property can either be `PASSED` , `FAILED` or `RETRY`, which determines last executed subprocess' state. It also specifies how many attempts can be done on property **remaining\_attempts** if **disposition** has been set as `RETRY`. Property **data** contains suprocesses results, which we'll take a look afterwards.

```json
{
  "ticket": "762ebbda-0edb-4e48-86bc-11a280273601",
  "event": "ticket.verification.in_progress",
  "sub_event": "verification.liveness",
  "flow_status": "IN_PROGRESS",
  "disposition": "PASSED",
  "remaining_attempts": 3,
  "data": { ... }
}
```

#### In Progress Event disposition statuses

* `PASSED:` all subprocesses were executed correctly and their results have been considered as OK.
* `RETRY`: this status is set when an exception has been raised, or any subprocess' result has been considered as unacceptable and has retries to attempt, ***eg.*** ***liveness detection*** process.
* `FAILED`, this status is set when an exception has been raised, or any subprocess' result has been considered as unacceptable and no more retries can be atempted, ***eg.*** ***liveness detection*** process.

#### Subevents

In this property, we will receive one of both values: `verification.liveness` and `verification.id_proofing`

#### verification.liveness subevent

This subevent is triggered when biometrical subprocesses were executed, which consist of `Facial analysis` and `Liveness detection`. In this subevent, property **data** contains biometrical subprocesses' results. An example is shown bellow:

```json
{
  "ticket": "762ebbda-0edb-4e48-86bc-11a280273601",
  "event": "ticket.verification.in_progress",
  "sub_event": "verification.liveness",
  "flow_status": "IN_PROGRESS",
  "disposition": "PASSED",
  "remaining_attempts": 3,
  "data": {
    "facial_analysis": {
      "status": true,
      "confidence_score": "100",
      "age_range": "22-30"
    },
    "liveness_detection": {
      "status": true,
      "validation_messages": [
        "Liveness detected"
      ]
    }
  }
}
```

#### verification.id\_proofing subevent

This subevent is triggered when Identity verification subprocesses were executed, which consist of `Document detection`, `Id proofing` and `Photo matching`. In this subevent, property **data** contains identity verification subprocesses' results. An example is shown bellow:

```json
{
  "ticket": "762ebbda-0edb-4e48-86bc-11a280273601",
  "event": "ticket.verification.in_progress",
  "sub_event": "verification.id_proofing",
  "flow_status": "IN_PROGRESS",
  "disposition": "PASSED",
  "remaining_attempts": 3,
  "data": {
    "document_detection": {
      "status": true
    },
    "id_proofing": {
      "status": true,
      "validations": {
        "recognized_document_type": "VALID",
        "image_quality": "VALID",
        "document_expiry": "VALID",
        "mrz": "VALID",
        "rfid": "NON_VALIDATED_OR_ABSENT",
        "readability": "VALID",
        "security": "VALID",
        "general_status": "VALID",
        "barcode": "VALID",
        "authenticity": "NON_VALIDATED_OR_ABSENT",
        "minimum_required_fields_read": "VALID"
      }
    },
    "photo_matching": {
      "status": true,
      "similarity_score": "99.94"
    }
  }
}
```

## 1.2 Verification - Completed event

The *ticket.verification.completed* event is triggered when a *Verification* has completed all of its subprocesses, or an error has been raised and there are no more retries to attempt. Notification payload specifies a set of properties as shown on following JSON. It will contain its ticket, so it can be tracked by your processes. Also, it holds its **event**. The **flow\_status** specified ticket's current state, which can be either `ACCEPTED` or `REJECTED` , this value depends on **confidence\_score** property. The value of the **disposition** property can be either `PASSED` or `FAILED` which determines last executed subprocess' state. It also gives final results of entire flow, such as **risk\_code** and **confidence\_score**.

```json
{
  "ticket": "72b89940-607f-4841-8521-5e641211917e",
  "clientId": "CLIENT-ID",
  "invitation": "a9e70162-97ae-4be0-8c53-caaaf6e99ba1",
  "event": "ticket.verification.completed",
  "flow_status": "ACCEPTED",
  "disposition": "PASSED",
  "risk_code": "LOW",
  "confidence_score": 98.15,
  "remaining_attempts": 0
}
```

#### Completed Event flow\_status statuses

* `ACCEPTED`: all flow's subprocesses were executed correctly and **confidence\_score** has got to *`ACCEPTED`* scoring threshold.
* `REJECTED`: this status is set when an exception has been raised, or any subprocess' result has been considered as unacceptable and no more retries can be atempted and **confidence\_score** has got to *`REJECTED`* scoring threshold.

#### Completed Event disposition statuses

* `PASSED:` all flow's subprocesses were executed correctly and their results have been considered as OK, so ticket is set to COMPLETED state.
* `FAILED`, this status is set when an exception has been raised, or any subprocess' result has been considered as unacceptable and no more retries can be atempted, ***eg.*** ***liveness detection*** process.

Here you find a further description of the response values below, it represents **both event responses** as these share the same response structure:

| Key                  | Data type | Description                                                                                                                                                                                                                                                           |
| -------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ticket`             | `string`  | The UUID of the *Identity Verification* which triggered this webhook. This will help you query our backend API for the details of the *Identity Verification*.                                                                                                        |
| `invitation`         | `string`  | The UUID of the *Identity Verification* *Invitation* related to this ticket.                                                                                                                                                                                          |
| `event`              | `string`  | The type of event that triggered this webhook.                                                                                                                                                                                                                        |
| `flow_status`        | `string`  | <p>This holds the result of the processed ticket and its <strong>confidence\_score</strong> threshold matching. <br><br>As noted above, its value may be one of these 2 posibilities:<br>- ACCEPTED<br>- REJECTED</p>                                                 |
| `disposition`        | `string`  | <p>This holds the result of the last executed subprocess. <br><br>As noted above, its value may be one of these 2 posibilities:<br>- PASSED<br>- FAILED</p>                                                                                                           |
| `remaining_attempts` | `number`  | Specifies the number of remaining retries that could be attempted.                                                                                                                                                                                                    |
| `risk_code`          | `string`  | <p>This contains risk analysis based on 3 possible values listed below, in order from <strong>safest</strong> to <strong>riskiest</strong> evaluation result:<br>- LOW<br>- MODERATE<br>- HIGH<br><br>This value depends on <code>confidence\_score</code> result</p> |
| `confidence_score`   | `number`  | This value is the calculation result from all factors and subprocesses, going from 0 to 100. Used for ticket's **acceptance** or **rejection**.                                                                                                                       |


# Invitations link

<figure><img src="/files/5Y2KwUnj1BuXwbCghF5C" alt=""><figcaption><p>Invitation webhook trigger</p></figcaption></figure>

## 1. Invitation - Completed

The *ticket.verification.completed* event is triggered when a *Verification* has completed all of its subprocesses, or an error has been raised and there are no more retries to attempt. Notification payload specifies a set of properties as shown on following JSON. It will contain its ticket, so it can be tracked by your processes. Also, it holds its **event**. The **flow\_status** specified ticket's current state, which can be either `ACCEPTED` or `REJECTED` , this value depends on **confidence\_score** property. The value of the **disposition** property can be either `PASSED` or `FAILED` which determines last executed subprocess' state. It also gives final results of entire flow, such as **risk\_code** and **confidence\_score**.

```json
{
    "id": "YOUR-INVITATION-ID",
    "invitation_state": "COMPLETED",
    "cifcod": "YOUR-USER-CIFCODE",
    "full_name": "Jon Doe",
    "ticket": "YOUR-USER-IDV-TICKET",
    "transaction_status": "ACCEPTED",
    "attempts": 1
}
```

#### Completed Invitation state

* `COMPLETED`: indicates that **invitation's** ticket has been **completed**, so this is set to a **completed state**.

#### IDV ticket's transaction\_status statuses

* `ACCEPTED:` all IDV Ticket flow's subprocesses were executed correctly and their results have been considered as OK, so ticket is set to COMPLETED state.
* `REJECTED:` this status is set when an exception has been raised, or any IDV ticketsubprocess' result has been considered as unacceptable and no more retries can be atempted, ***eg.*** ***liveness detection*** process.

Here you find a further description of the response values below:

| Key                  | Data type | Description                                                                                                                                                                                                           |
| -------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                 | `string`  | The UUID of the *Invitation* which triggered this webhook. This will help you query our backend API for the details of the *Invitation*.                                                                              |
| `invitation_state`   | `string`  | Invitation's current state.                                                                                                                                                                                           |
| `cifcod`             | `string`  | User's unique identifier.                                                                                                                                                                                             |
| `full_name`          | `string`  | User's name read from its IDV ticket process.                                                                                                                                                                         |
| `ticket`             | `string`  | Invitation's IDV ticket's UUID.                                                                                                                                                                                       |
| `transaction_status` | `string`  | <p>This holds the result of the processed ticket and its <strong>confidence\_score</strong> threshold matching. <br><br>As noted above, its value may be one of these 2 posibilities:<br>- ACCEPTED<br>- REJECTED</p> |
| `attempts`           | `number`  | Specifies the number of attempts made by the user to complete its IDV ticket process.                                                                                                                                 |


# Document image quality requirements

Below are the requirements for size and quality of document images captured by any device, which are necessary for successful image processing by Preventor ID API:

![](/files/qRgBwEqBKjZxDXPOKUDb)


# Overview

Welcome to Preventor ID! This documentation will show you how to integrate Preventor broker SDK into your website.

## What is the Preventor broker SDK?

The Preventor broker SDK allows you to verify your customers as a service without the need to have any kind of integrations or do any development on your platforms. It is a very easy to use platform and in which your clients will be able to carry out their verification in a fast, secure, agile and frictionless process.

You will be able to manage these verifications and you will also be able to view and monitor the results interactively using the available options.

This platform can be used as an additional service to verify the identity of clients in their own offices in a secure way, it can also be used for the maintenance of their clients' information and even for campaigns to attract more clients to your business.

## How to use it?

Invitations can be shared with your client via email, to a mobile with an SMS message or with the customer assistance option so that a representative of your company from their own mobile can help a client with identity verification in person when the client doesn’t have a cell phone, don't have internet or the camera doesn't work properly.


# HTML + Javascript

Steps to integrate the Preventor broker SDK into HTML and JavaScript vanilla application.

## 1. Installation

To install the Preventor Broker SDK, add the following script.

```html
<script
    type="module"
    src="https://sdk.preventor.com/pvtidaas/broker/broker.esm.js"
></script>
```

## 2. Setup the SDK

1. Add `pvt-broker` tag into your HTML.

<pre class="language-html"><code class="lang-html"><strong>&#x3C;pvt-broker>&#x3C;/pvt-broker>
</strong></code></pre>

2. Set your configuration

You can find your credentials on the [Preventor platform](https://sandbox.preventor.com/)

<div align="left"><figure><img src="/files/j7ksSIe60LU5Dh9CXRFt" alt="" width="303"><figcaption><p>Go to settings / integration keys</p></figcaption></figure></div>

<div align="left"><figure><img src="/files/yTB9gr2S7jnut2x8dZxs" alt="" width="375"><figcaption><p>Integration keys</p></figcaption></figure></div>

You can find the broker ID on the [Preventor platform](https://sandbox.preventor.com/)

<div align="left"><figure><img src="/files/l3bSrEimlfRL4Z74jddo" alt="" width="169"><figcaption><p>Go to apps option</p></figcaption></figure></div>

<div align="left"><figure><img src="/files/ZF1DkQsCFbyb10aVAJ2F" alt="" width="316"><figcaption><p>Go to broker management</p></figcaption></figure></div>

<div align="left"><figure><img src="/files/qQhvt698DeXuxtVyozny" alt=""><figcaption><p>You must pass this Broker ID to your configuration. If don't have any broker, you can create it.</p></figcaption></figure></div>

```javascript
window.PvtBrokerSDK = {
    brokerId: 'YOUR_BROKER_ID',
    credentials: {
      apiKey: 'YOUR_API_KEY',
      clientSecret: 'YOUR_CLIENT_SECRET',
      tenant: 'YOUR_TENANT',
      banknu: 'YOUR_BANKNU',
      env: 'YOUR_ENV',
    },
  };
```

3. Call the `open()` method to open the component

```javascript
const component = document.querySelector('pvt-broker');
component.open();
```

4. `pvt-broker` emits a loaded event when the Preventer Broker SDK finishes downloading. In the example below, the loaded event is utilized to enable a button that opens the Preventer Broker SDK.

```javascript
const component = document.querySelector('pvt-broker');
const button = document.querySelector('button');  
button.addEventListener('click', () => component.open())

component.addEventListener('loaded', () => {
  button.disabled = false;
});
```

5. A complete `HTML`file should look similar to the example below.

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta charset="utf-8" />
    <title>Preventor, Remote digital identity platform for brokers</title>
  </head>

  <body>
    <button disabled>Click me</button>
    <pvt-broker></pvt-broker>

    <script
      type="module"
      src="https://sdk.preventor.com/pvtidaas/broker/broker.esm.js"
    ></script>
    <script>
      window.PvtBrokerSDK = {
        brokerId: 'YOUR_BROKER_ID',
        credentials: {
          apiKey: 'YOUR_API_KEY',
          clientSecret: 'YOUR_CLIENT_SECRET',
          tenant: 'YOUR_TENANT',
          banknu: 'YOUR_BANKNU',
          env: 'YOUR_ENV',
        },
      };

      const component = document.querySelector('pvt-broker');
      const button = document.querySelector('button');  
      button.addEventListener('click', () => component.open())

      component.addEventListener('loaded', () => {
        button.disabled = false;
      });
    </script>
  </body>
</html>
```

{% hint style="success" %}
Congratulations, the Preventor Broker SDK has been successfully configured!
{% endhint %}

<figure><img src="/files/Um4imyX1K2uguZazPkHk" alt="" width="313"><figcaption><p>Web SDK</p></figcaption></figure>


# React

Steps to integrate the Web SDK into React application.

## 1. Installation

To install the Preventor Web SDK, add the following to your project’s:

1. Add `https://sdk.preventor.com/pvtidaas/broker/broker.esm.js` in your `public/index.html`.

```html
<script
    type="module"
    src="https://sdk.preventor.com/pvtidaas/broker/broker.esm.js"
></script>
```

2\. Setup the button in your component file

```tsx
import React, { useEffect, useRef } from "react";

export default function App() {
  const pvtButtonRef = useRef(null);
  useEffect(() => {
    window.PvtBrokerSDK = YOUR_CONFIGURATION;
  }, []);

  return <pvt-broker ref={pvtButtonRef}></pvt-broker>;
}
```

{% hint style="success" %}
You have successfully installed the Preventor Web SDK!
{% endhint %}


# Vue.js

Steps to integrate the Web SDK into Vue application.

## 1. Installation

To install the Preventor Web SDK, add the following to your project’s:

1. &#x20;Add `https://sdk.preventor.com/pvtidaas/broker/broker.esm.js` in your `public/index.html`.

```html
<script
    type="module"
    src="https://sdk.preventor.com/pvtidaas/broker/broker.esm.js"
></script>
```

2\. Ignore the custom tag `pvt-broker` in your `main.js` file

```typescript
Vue.config.ignoredElements = [/pvt-broker/]; // ignore the pvt-button tag

new Vue({
  render: h => h(App)
}).$mount("#app");
```

3\. Setup the button in your component file

```html
<template>
  <div id="app">
    <pvt-broker></pvt-broker>
  </div>
</template>

<script>
export default {
  name: "App",
  mounted: function () {
    window.PvtBrokerSDK = YOUR_CONFIGURATION;
  },
};
</script>
```

{% hint style="success" %}
You have successfully installed the Preventor Web SDK!
{% endhint %}


# Introduction

Welcome to Preventor! This documentation will show you how to integrate Preventor into your website, app, and backend and verify your customers.

#### What is Preventor?

Preventor is a suite of customizable identification tools including liveness detection, document verification, facial recognition, and more. These tools are combined to estimate the authenticity of a user's true identity.&#x20;

#### **How it works**

A **User** submits a video selfie and valid identifying **Resources** during a **Verification** guided by the Preventor client-side integration. Once all the necessary **Resources** are submitted, **Data points** are extracted, digitized, and authenticated. These **Data points** then become part of the **User's Identity**. The **User** then consents to share **Resources** and/or **Data points** from their **Identity** with you. This information is passed to you and can be used to make decisions about a **User** (e.g. activate account).&#x20;

This table below explains our terminology further.

| Term                 | Description                                                                                                                                                                                                                                                                               |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Identity**         | A set of **Data points** and **Resources** related to and owned by one single **User**. This data can be accessed by you through a **Verification**                                                                                                                                       |
| **Resource**         | A source document used to generate the **Data points** for a **User** (E.g. Passport).                                                                                                                                                                                                    |
| **User**             | The owner of an **Identity.**                                                                                                                                                                                                                                                             |
| **Client-side SDKs** | Language specific packages you can use to integrate Preventor into your website or app (E.g.Android, Web-component) .                                                                                                                                                                     |
| **Verification**     | A transaction through which a **User** consents to share **Data points** with you. If the **Data points** you request are not already available in the **User**'s **Identity**, the Preventor client will ask the **User** to submit the necessary **Resource** required to extract them. |
| **Data point**       | Any data about a **User** extracted from a **Resource** (E.g. Passport Number, or Age).                                                                                                                                                                                                   |

{% hint style="info" %}

#### You can find a full list of data points by checking out [our full API specification here](https://api-reference.preventor.com).

{% endhint %}


