# Combined Consent

The Combined Consent module shows the user one or more preconfigured [consents](https://developer.incode.com/docs/configuration-consents-tab) to review and accept, then records their agreement. Consents obtain the user's permission to collect and process their data. Most jurisdictions require this at the start of an identity verification journey. Consents are [configured in Dashboard](https://developer.incode.com/docs/configuration-consents-tab); the module presents what your Flow or Workflow configuration provides.

For an overview of this module and how it works, see [Data Sharing Consent](https://developer.incode.com/docs/combined-consent).

How you use this module depends on your [integration pattern](https://developer.incode.com/docs/android-common-implementation-patterns#integration-patterns). In Patterns 1 and 2, you add the module to a `FlowConfig` in code as shown on this page. In Pattern 3, you define your modules and configuration in Dashboard as a Flow or Workflow and reference it by ID with `startFlow()` or `startWorkflow()` as shown on [Run Flows Configured in Dashboard](https://developer.incode.com/docs/android-run-flows-configured-online).

## Add Combined Consent

Add the module with `addCombinedConsent()`, passing a `CombinedConsent` instance built with its `Builder`.

```kotlin
flowConfigBuilder.addCombinedConsent(combinedConsent)
```
```java
flowConfigBuilder.addCombinedConsent(combinedConsent);
```

### Example

The example below builds a `CombinedConsent` with a combined consents ID, adds it to the flow, and listens for the result through `onCombinedConsentCompleted()`.

To get the consent ID, first create Data Sharing Consent in the Dashboard under Configuration → Consents, then copy the resulting ID.

```kotlin
val combinedConsent = CombinedConsent.Builder()
    .setCombinedConsentsId("YOUR_COMBINED_CONSENTS_ID")
    .build()

val flowConfig = FlowConfig.Builder()
    .addCombinedConsent(combinedConsent)
    .build()

val onboardingListener = object : OnboardingListener() {
    override fun onCombinedConsentCompleted(combinedConsentResult: CombinedConsentResult) {
        // Consent step finished. Process the result.
    }
}

IncodeWelcome.getInstance()
    .startOnboarding(activityContext, sessionConfig, flowConfig, onboardingListener)
```
```java
CombinedConsent combinedConsent = new CombinedConsent.Builder()
    .setCombinedConsentsId("YOUR_COMBINED_CONSENTS_ID")
    .build();

FlowConfig flowConfig = new FlowConfig.Builder()
    .addCombinedConsent(combinedConsent)
    .build();

IncodeWelcome.OnboardingListener onboardingListener = new IncodeWelcome.OnboardingListener() {
    @Override
    public void onCombinedConsentCompleted(@NonNull CombinedConsentResult combinedConsentResult) {
        // Consent step finished. Process the result.
    }
};

IncodeWelcome.getInstance()
    .startOnboarding(activityContext, sessionConfig, flowConfig, onboardingListener);
```

## Configuration Options

Build the module with `CombinedConsent.Builder`. The table below lists the common options.

| Setting                                              | Description                                                                                 |
| ---------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| `setCombinedConsentsId(String)`                      | Sets the ID of the preconfigured combined consents to present. Ignored in DELAYED SDK mode. |
| `setOfflineCombinedConsentData(CombinedConsentData)` | Sets the offline consent data. Used only in DELAYED SDK mode.                               |

For the complete option set, see `CombinedConsent.Builder` in [API Reference](https://developer.incode.com/docs/android-api-reference).

## Result

Combined Consent delivers a `CombinedConsentResult` to the `onCombinedConsentCompleted(CombinedConsentResult)` callback on the `OnboardingListener`. Key fields include:

- `isSuccess`: `true` if the combined consent was submitted successfully; otherwise, `false`.
- Fields inherited from `BaseResult`:
  - `resultCode`: The `ResultCode` for this result.
  - `error`: When `resultCode` is `ERROR`, the `Throwable` that caused it; otherwise, `null`.
  - `deviceStats`: The `DeviceStats` snapshot of the device state when the result was produced.
  - `motionStatus`: Device motion assessment during capture. One of the following:
    - `UNCLEAR`: Motion could not be determined; the default.
    - `PASS`: Device motion was within acceptable limits.
    - `FAIL`: Excessive device motion was detected.

Errors surface through `OnboardingListener.onError(Throwable)`. This module does not deliver a module-specific exception subtype.

For all fields, see `CombinedConsentResult` in [API Reference](https://developer.incode.com/docs/android-api-reference).
