## Initialize the SDK

Initialize once before launching any flow.

```ts
import IncodeSdk, { IncodeSdkInitError } from '@incode-sdks/react-native-incode-sdk';

try {
  await IncodeSdk.initialize({
    testMode: false,
    apiConfig: {
      key: 'YOUR_API_KEY',
      url: 'YOUR_API_URL',
    },
  });
} catch (error) {
  const e = error as IncodeSdkInitError;
  console.error(`Incode SDK initialize failed: ${e.code} - ${e.message}`);
  console.error(`Incode SDK initialize failed with error ${e.code} - ${e.message}`);
}
```

Check initialization when app screens can be re-entered:

```ts
const initialized = await IncodeSdk.isInitialized();
```

## Configure Flows Locally and Run End to End

Use this path when the React Native app owns the module order.

### Configure Onboarding session

```ts
const sessionConfig = {
  region: 'ALL',
  externalId: 'external-id',
  validationModules: ['id', 'liveness', 'faceRecognition'],
};
```

Useful `sessionConfig` fields include:

| Field | Use |
| --- | --- |
| `region` | `ALL`, `BR`, or `IN`. |
| `queue` | Assign the session to a queue. |
| `interviewId` / `token` | Start from a backend-created session. |
| `configurationId` | Apply a dashboard flow configuration. |
| `externalId` / `externalCustomerId` | Link the Incode session to your own user/customer ID. |
| `validationModules` | Select server-side validation modules. |
| `customFields` | Attach custom string data. |
| `e2eEncryptionEnabled` | Enable E2EE for the session. |
| `mergeSessionRecordings` | Merge ID and Face recordings. |
| `voiceConsentLanguage` | Set `VideoSelfie` voice consent language: `en`, `es`, `pt`, or `he`. |

Available validation modules:

- `id`
- `liveness`
- `faceRecognition`
- `governmentValidation`
- `governmentFaceValidation`
- `governmentOcrValidation`
- `videoSelfie`

Default validation modules are `id`, `liveness`, and `faceRecognition`.

### Configure Onboarding Flow

```ts
const flowConfig = [
  { module: 'IdScan' },
  { module: 'SelfieScan' },
  { module: 'FaceMatch' },
];
```

Place dependent modules after the modules they need:

- `FaceMatch` should follow `IdScan` and `SelfieScan`.
- `ProcessId` should follow `IdScanFront` and `IdScanBack`.
- `UserScore` and `Approve` should be at the end.

### Start the onboarding

```ts
const result = await IncodeSdk.startOnboarding({
  sessionConfig,
  flowConfig,
});

if (result.status === 'userCancelled') {
  console.log('User cancelled onboarding');
}
```

```ts
try {
  await IncodeSdk.startOnboarding({ sessionConfig, flowConfig });
} catch (error) {
  if (error.code === 'permissionsDenied') {
    console.log('User denied some mandatory permission during the flow');
  }
}
```

To listen for the results of the steps in the flow as soon as they're completed, register optional listeners before starting the flow:

```ts
const unsubscribers = [
  IncodeSdk.onSessionCreated((session) => {
    console.log(session.interviewId);
  }),
  IncodeSdk.onStepCompleted({
    module: 'IdScanFront',
    listener: (event) => console.log(event.result),
  }),
  IncodeSdk.onStepCompleted({
    module: 'IdScanBack',
    listener: (event) => console.log(event.result),
  }),
  IncodeSdk.onStepCompleted({
    module: 'ProcessId',
    listener: (event) => console.log(event.result.extendedOcrData),
  }),
  IncodeSdk.onStepCompleted({
    module: 'SelfieScan',
    listener: (event) => console.log(event.result),
  }),
  IncodeSdk.onStepCompleted({
    module: 'FaceMatch',
    listener: (event) => console.log(event.result),
  }),
];
```

Call each unsubscriber when the screen unmounts:

```ts
React.useEffect(() => {
  const unsubscribers = setupListeners();

return () => {
    unsubscribers.forEach((unsubscriber) => unsubscriber());
  };
}, []);
```

Enable ID/Selfie screen recording when using the streaming variant:

```ts
await IncodeSdk.startOnboarding({
  sessionConfig,
  flowConfig,
  recordSessionConfig: {
    recordSession: true,
    forcePermissions: false,
  },
});
```

## Configure Flows Locally and Run Step by Step

Use the Sections API when your app needs custom screens or business logic between SDK modules.

### Set up an onboarding session

```ts
const session = await IncodeSdk.setupOnboardingSession({
  sessionConfig: {
    region: 'ALL',
  },
});

console.log(session.interviewId, session.token);
```

### Configure section flow

```ts
const idSectionConfig = {
  sectionTag: 'idSection',
  flowConfig: [{ module: 'IdScan' }],
};
```

### Start onboarding section

```ts
const idSection = await IncodeSdk.startOnboardingSection(idSectionConfig);

if (idSection.status === 'success') {
  await IncodeSdk.startOnboardingSection({
    sectionTag: 'selfieSection',
    flowConfig: [{ module: 'SelfieScan' }],
  });
}
```

You can start multiple sections, but only one at a time.

### Finish onboarding session

```ts
await IncodeSdk.finishOnboardingFlow();
```

## Run Flows Configured Online

Use this path when the module order and settings live on the Incode Dashboard.

### Start flow

Starts the flow based on the `sessionConfig` provided. Specify `configurationId`, and optionally use `moduleId` to start from a specific step within the flow.

```ts
const result = await IncodeSdk.startFlow({
  sessionConfig: {
    configurationId: 'YOUR_CONFIGURATION_ID',
    externalId: 'external-id',
  },
});
```

### Start flow from deep link

Starts the flow based on the deep link URL. The SDK reads the `configurationId`, `interviewId`, and the step from which it should start.

```ts
const result = await IncodeSdk.startFlowFromDeepLink('YOUR_DEEPLINK_URL');
```

### Start workflow

`startWorkflow` creates a new session based on the `configurationId` provided through `sessionConfig`.

```ts
const result = await IncodeSdk.startWorkflow({
  sessionConfig: {
    configurationId: 'YOUR_CONFIGURATION_ID',
  },
});
```

## Using SDK without an API KEY

To use the SDK without an API KEY, please provide a token to the `setupOnboardingSession` method, and afterwards you should proceed with using Sections API like in the example below:

```javascript
try {
  await IncodeSdk.initialize({
    testMode: false,
    apiConfig: {
      url: 'YOUR API URL',
    },
  });
} catch (error) {
  const e = error as IncodeSdkInitError;
  console.error(e.code + " - " + e.message)
}

IncodeSdk.setupOnboardingSession({
      sessionConfig: {
        token: 'YOUR_TOKEN',
       }
      }).then((sessionResult) => {
        IncodeSdk.startOnboardingSection({
          flowConfig: [{ module: 'IdScan', showTutorial: false },
                   { module: 'SelfieScan', showTutorial: false},],
        })
          .then((onboardingSectionResult) => {
            IncodeSdk.faceMatch()
            .then((faceMatchResult) => {
              IncodeSdk.finishOnboardingFlow()
              .then((finishResult) => {
                console.log('Session completed successfully');
              })
              .catch((e) => {
                console.error('Finish session error', e);
              })
            })
            .catch((e) => {
              console.error('Face match error', e);
            })
          })
          .catch((e) => {
            console.error('Start onboarding section error', e);
          });
       })
       .catch((e) => {
        console.error('Set onboarding session error', e);
       });
```

## Run Face Login

Face Login requires an approved customer with an enrolled face.

### Face Login 1:1

Use 1:1 Face Login when you already have the user's `customerUUID`.

```ts
const result = await IncodeSdk.startFaceLogin({
  showTutorials: true,
  customerUUID: 'CUSTOMER_UUID',
  faceMaskCheck: false,
  lensesCheck: false,
  logAuthenticationEnabled: false,
  e2eeEncryptionEnabled: false,
});
```

### Face Login 1:N

Use 1:N Face Login when you want the SDK to search for the captured face in the enrolled database. Omit `customerUUID`.

```ts
const result = await IncodeSdk.startFaceLogin({
  showTutorials: true,
  faceMaskCheck: false,
  lensesCheck: false,
  logAuthenticationEnabled: false,
  e2eeEncryptionEnabled: false,
});
```

On Android, `faceMaskCheck` requires:

```groovy
implementation 'com.incode.sdk:model-mask-detection:2.0.0'
```

## Reduce Local SDK Storage

To delete locally stored onboarding session data on Android devices, call:

```ts
await IncodeSdk.deleteLocalUserData();
```

This removes up to 5-6 MB of data stored locally during onboarding.

## Dynamic Delivery

To use Dynamic Delivery of the resources on Android and iOS platforms, please follow the guide [here](https://developer.incode.com/docs/react-native-dynamic-delivery-usage-guide)

## E2EE SDK Integration Guide

Configure the E2EE URL during initialization and enable encryption on the session.

End-to-End Encryption adds an extra layer of security by encrypting data transmitted between the server and client. The process begins with a key exchange where the client and server share keys for encrypting and decrypting messages.

```ts
await IncodeSdk.initialize({
  apiConfig: {
    key: 'YOUR_API_KEY',
    url: 'YOUR_API_URL',
    e2eeUrl: 'YOUR_E2EE_URL',
  },
});

const sessionConfig = {
  e2eEncryptionEnabled: true,
};
```

Pass `sessionConfig` when setting up an onboarding session or when starting a flow:

```ts
await IncodeSdk.setupOnboardingSession({ sessionConfig });

await IncodeSdk.startOnboarding({
  sessionConfig,
  flowConfig,
});
```
