## Detect additional verification

Use this guide to handle additional verification when an evaluation returns `REVIEW` and requires more input before RiskOS™ can return a terminal decision.

In this workflow, additional verification can take three forms:

- **One-Time Passcode (OTP)** — Verify control of the phone number
- **Additional identity data** — Collect more PII to continue the evaluation
- **Predictive Document Verification (DocV)** — Launch document capture and resume the evaluation asynchronously

For routing patterns and response interpretation, see [Handle Results](https://help.socure.com/riskos/docs/prefill-kyc-fraud-watchlist-direct-api-handle-results).

RiskOS™ pauses an evaluation when more input or verification is required.

### Common signals:

| Verification type | How to detect it | What your application should do |
| --- | --- | --- |
| OTP | `decision = REVIEW`, `status = ON_HOLD`, `sub_status = Awaiting Customer OTP`, `tags` include `OTP Triggered` | Prompt for the code and verify with `PATCH /api/evaluation/{eval_id}` |
| Additional identity data | `decision = REVIEW`, `status = ON_HOLD`, `sub_status = More information needed`, `tags` include `Additional PII Requested` | Collect identity data and continue with `PATCH /api/evaluation/{eval_id}` |
| Predictive DocV | `decision = REVIEW`, `status = ON_HOLD` or `eval_status = evaluation_paused`, and `data_enrichments` contains `enrichment_provider = "SocureDocRequest"` | Launch the DocV flow and wait for the final result |

> 📘
>
> **Important**:
> 
> Treat `REVIEW` as a non-terminal state. After every OTP submission, identity update, or DocV handoff, re-evaluate the updated response to determine the next step.

## Verification flow at a glance

```text
REVIEW
  ├── Awaiting Customer OTP
  │     └── Verify OTP with PATCH
  │            ├── REVIEW → More information needed
  │            ├── ACCEPT
  │            └── REJECT
  ├── More information needed
  │     └── Collect identity data and PATCH
  │            ├── ACCEPT
  │            └── REJECT
  └── SocureDocRequest present
        └── Launch DocV
               └── Wait for webhook or updated evaluation
```

## Handle One-Time Passcode

Use this flow when the evaluation returns:

- `decision = REVIEW`
- `status = ON_HOLD`
- `sub_status = Awaiting Customer OTP`
- `tags` contains `OTP Triggered`

### What your application should do

1. Display a 6-digit OTP input.
2. Allow the user to retry if needed (up to five attempts).
3. Submit the code using `PATCH /api/evaluation/{eval_id}`.
4. Route the user based on the updated evaluation response.

If the maximum number of attempts is reached, the evaluation returns a final `REJECT` decision.

For more information on OTP-specific scenarios, see the [OTP Integration Guide](https://help.socure.com/riskos/docs/otp-integration-guide).

### Verify the One-Time Passcode (`PATCH`)

When the user enters the 6-digit code, your backend should verify it by sending a `PATCH` request to the [Evaluation endpoint](https://help.socure.com/riskos/reference/patchevaluation) with the required top-level fields.

#### Example request

```json
{
  "id": "f0b3075b-0ae1-4130-9171-88d6c75a982c",
  "timestamp": "2026-02-16T20:02:44.717Z",
  "workflow": "non_hosted_advanced_pre_fill",
  "data": {
    "individual": {
      "otp": {
        "code": "622123"
      }
    }
  }
}
```

#### `data.individual.otp` fields

| Field | Action | Description |
| --- | --- | --- |
| `code` | **Verify** | 6-digit OTP entered by the user |
| `resend` | **Resend** | Set to `true` to resend the code |

### One-Time Passcode outcomes

After OTP submission, RiskOS™ returns an updated evaluation.

| Outcome | decision | status | What to do |
| --- | --- | --- | --- |
| OTP challenge still active | `REVIEW` | `ON_HOLD` | Prompt for OTP again and continue until the workflow resolves or retries are exhausted |
| OTP verified, more identity data required | `REVIEW` | `ON_HOLD` | Display prefilled data if available, collect remaining PII, and continue |
| Evaluation fails | `REJECT` | `CLOSED` | Route to fallback or decline handling |
| Evaluation completes | `ACCEPT` | `CLOSED` | Continue onboarding |

> 👍
>
> **Tip**:
>
> Use tags such as `OTP Triggered`, `OTP Approved`, `Prefill Successful`, and `Prefill Unsuccessful` to determine what happened after OTP verification.

### Example: One-Time Passcode challenge still active

```json
{
  "eval_id": "8d455113-94f8-4bc2-82f6-e016e078f5dc",
  "decision": "REVIEW",
  "status": "ON_HOLD",
  "sub_status": "Awaiting Customer OTP",
  "tags": [
    "OTP Triggered"
  ]
}
```
### Example: One-Time Passcode approved, more identity data required

```json
{
  "eval_id": "8d455113-94f8-4bc2-82f6-e016e078f5dc",
  "decision": "REVIEW",
  "status": "ON_HOLD",
  "sub_status": "More information needed",
  "tags": [
    "OTP Triggered",
    "OTP Approved",
    "Prefill Successful",
    "Approved to Display the Prefill Data",
    "Additional PII Requested"
  ]
}
```
### Example: Final accept after One-Time Passcode flow

```json
{
  "eval_id": "8d455113-94f8-4bc2-82f6-e016e078f5dc",
  "decision": "ACCEPT",
  "status": "CLOSED",
  "sub_status": "Accept",
  "tags": [
    "OTP Triggered",
    "OTP Approved",
    "Prefill Successful",
    "Approved to Display the Prefill Data",
    "Additional PII Requested"
  ]
}
```
### Example: Final reject

```json
{
  "eval_id": "8d455113-94f8-4bc2-82f6-e016e078f5dc",
  "decision": "REJECT",
  "status": "CLOSED",
  "tags": [
    "Phone - High Risk"
  ]
}
```
## Handle Additional Identity Data

Use this flow when the evaluation returns:

- `decision = REVIEW`
- `status = ON_HOLD`
- `sub_status = More information needed`
- `tags` contains `Additional PII Requested`

### What your application should do

- If `tags` contains `Prefill Successful` and `Approved to Display the Prefill Data`, display the prefilled data to the user
- If `tags` contains `Prefill Unsuccessful`, display a blank or partially completed form
- Collect the remaining identity data
- Submit the update using `PATCH /api/evaluation/{eval_id}`

### Prefill handling

If Prefill data is returned, do not allow users to edit:

- `phone_number`
- `date_of_birth`

#### Example: Prefill successful, more PII still required

```json
{
  "decision": "REVIEW",
  "status": "ON_HOLD",
  "sub_status": "More information needed",
  "tags": [
    "OTP Triggered",
    "OTP Approved",
    "Prefill Successful",
    "Approved to Display the Prefill Data",
    "Additional PII Requested"
  ]
}
```

### Continue the evaluation with identity data

When the workflow requires identity data, submit a `PATCH` request to continue the evaluation.

```json
{
  "id": "f0b3075b-0ae1-4130-9171-88d6c75a982c",
  "timestamp": "2026-03-11T13:24:43.000Z",
  "workflow": "non_hosted_advanced_pre_fill",
  "data": {
    "individual": {
      "given_name": "Jane",
      "family_name": "Smith",
      "date_of_birth": "1990-05-15",
      "email": "jane.smith@example.com",
      "phone_number": "+14155550001",
      "address": {
        "line_1": "123 Main St",
        "locality": "Newark",
        "major_admin_division": "NJ",
        "postal_code": "07102",
        "country": "US"
      }
    }
  }
}
```

See [Update an Evaluation](https://help.socure.com/riskos/docs/prefill-kyc-fraud-watchlist-direct-api-update-evaluation) for request structure and field guidance.

## Handle Predictive Document Verification

Use this flow when the evaluation pauses and returns a DocV handoff request.
