# CURP Validation

The CURP Validation module validates a person's CURP (Clave Única de Registro de Población), a personal identification number issued in Mexico, against Mexico's RENAPO registry. It accepts a CURP extracted via OCR, entered manually, or generated from personal data when the user doesn't know it.

For an overview of this module and how it works, see [CURP Validation](https://developer.incode.com/docs/curp-validation).

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 CURP Validation

Add the module with `addCurpValidation()`, or pass a configured instance to `addCurpValidation(curpValidation)`.&#x20;

```kotlin
flowConfigBuilder.addCurpValidation()
```
```java
flowConfigBuilder.addCurpValidation();
```

CURP Validation ships both a v1 (legacy View) and a v2 (Jetpack Compose) capture screen; the active one depends on your Incode configuration. Contact your Incode representative to enable v2.

### Example

The example below builds a `CurpValidation` with validation enabled, adds it to the flow, and listens for the result through `onCurpValidationCompleted()`.

```kotlin
val curpValidation = CurpValidation.Builder()
    .setValidationEnabled(true)
    .build()

val flowConfig = FlowConfig.Builder()
    .addCurpValidation(curpValidation)
    .build()

val onboardingListener = object : OnboardingListener() {
    override fun onCurpValidationCompleted(curpValidationResult: CurpValidationResult) {
        // CURP validation finished. Inspect the result.
    }
}

IncodeWelcome.getInstance()
    .startOnboarding(activityContext, sessionConfig, flowConfig, onboardingListener)
```
```java
CurpValidation curpValidation = new CurpValidation.Builder()
    .setValidationEnabled(true)
    .build();

FlowConfig flowConfig = new FlowConfig.Builder()
    .addCurpValidation(curpValidation)
    .build();

IncodeWelcome.OnboardingListener onboardingListener = new IncodeWelcome.OnboardingListener() {
    @Override
    public void onCurpValidationCompleted(@NonNull CurpValidationResult curpValidationResult) {
        // CURP validation finished. Inspect the result.
    }
};

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

## Configuration Options

Build the module with `CurpValidation.Builder` when you need to set an option. The table below lists the most common option.

| Setting                         | Description                                                                                    |
| ------------------------------- | ---------------------------------------------------------------------------------------------- |
| `setValidationEnabled(boolean)` | Controls whether the entered CURP is validated against the RENAPO service. Defaults to `true`. |

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

## Result

CURP Validation delivers a `CurpValidationResult` to the `onCurpValidationCompleted(CurpValidationResult)` callback on the `OnboardingListener`. Key fields include:

- `curp`: The validated CURP string; `null` when unavailable.
- `isValid`: `true` when the CURP was validated successfully; otherwise, `false`.
- `data`: Additional CURP validation data as key/value pairs. May be empty or `null`.
- `isFinalAttempt`: `true` when this was the last allowed validation attempt.
- 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)`. There is no CURP-specific exception subtype.

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