Handle Step-Up Verification (DocV and OTP) via API

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:

For routing patterns and response interpretation, see 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

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:

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.

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 with the required top-level fields.

Example request

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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:

What your application should do

Prefill handling

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

Example: Prefill successful, more PII still required

{
  "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.

{
  "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 for request structure and field guidance.

Handle Predictive Document Verification

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