Handle Age Assurance Step-Up Flows

Resolve Age Assurance step-ups — resubmit the evaluation for a one-time passcode, and complete an active selfie or document capture that returns asynchronously through a webhook.

Overview

Some Age Assurance workflows escalate to an interactive step-up when a passive method can't resolve age on its own. When a step-up starts, the evaluation pauses with status: ON_HOLD. The two step-ups resume differently:

  • One-time passcode (OTP) — resumes when you resubmit the evaluation with the passcode. The result returns synchronously.
  • Active capture (selfie or document) — resumes asynchronously. After the user completes capture, RiskOS™ delivers the final decision on the evaluation_completed webhook.

For when each step-up occurs and the high-level integration, see Build an Age Assurance Integration.


End-to-end async sequence

sequenceDiagram
    participant Client as Client app + SDK
    participant Backend as Your backend
    participant RiskOS as RiskOS™

    Backend->>RiskOS: POST /api/evaluation
    RiskOS-->>Backend: status ON_HOLD (step-up required)

    alt One-time passcode (OTP)
        Backend-->>Client: Prompt for passcode
        Client->>Backend: Submit passcode
        Backend->>RiskOS: Resubmit evaluation with data.individual.otp
        RiskOS-->>Backend: Final decision (synchronous response)
    else Active capture (selfie or document)
        Backend-->>Client: Launch DocV capture with docvTransactionToken
        Client->>RiskOS: Complete capture
        RiskOS-->>Backend: evaluation_completed webhook (final decision)
    end

    Backend-->>Client: Allow or block on the final decision

One-time passcode (OTP)

Phone- and email-based methods can send a one-time passcode to confirm the user controls the contact. OTP runs only when RiskOS™ finds an identity.

  • Trigger — A phone or email method needs to confirm possession.
  • Behavior — RiskOS™ sends a passcode and pauses the evaluation on the OTP step.
  • Resume — Collect the passcode from the user, then resubmit the evaluation with the same request id and the code under data.individual.otp.
{
  "id": "test-user-phone",
  "workflow": "docv_demo_socure",
  "data": {
    "individual": {
      "otp": {
        "code": "123456",
        "resend": false
      }
    }
  }
}

Set resend to true to send a new passcode instead of verifying one.

The OTP result appears under computed.otp_step_response:

{
  "verificationId": "a23ddf16-0a17-4639-9a46-e491ee237bae",
  "status": "approved",
  "attemptCount": 1
}
FieldTypeDescription
verificationIdStringIdentifier for the OTP verification attempt.
statusStringVerification status, for example approved or reject.
attemptCountIntegerNumber of passcode attempts made for this evaluation.

For OTP configuration, see One-Time Passcode (OTP).


Active capture (selfie or document)

When no passive method resolves age, the workflow escalates to an active selfie or document capture. This is an asynchronous step-up — the evaluation pauses until the user completes capture.

Detect the step-up

Check the evaluation response for both conditions:

  • eval_status is "evaluation_paused" or status is "ON_HOLD".
  • data_enrichments includes an object where enrichment_provider is "SocureDocRequest".

Extract the handoff assets

Read these from the SocureDocRequest object's response.data:

FieldPurpose
docvTransactionTokenRequired. Initialize the Capture App or DocV SDK with this value.
urlOptional. Direct mobile redirect to the Capture App.
qrCodeOptional. Base64 PNG for desktop-to-mobile handoff.
{
  "eval_id": "7e79e169-5021-475b-af98-9362ac690c38",
  "status": "ON_HOLD",
  "eval_status": "evaluation_paused",
  "data_enrichments": [
    {
      "enrichment_provider": "SocureDocRequest",
      "response": {
        "data": {
          "docvTransactionToken": "70c6a4bc-f646-4c6a-94c1-9cd428e356ef",
          "url": "https://verify.socure.com/#/dv/70c6a4bc-f646-4c6a-94c1-9cd428e356ef"
        }
      }
    }
  ]
}

Complete the handoff

  1. Persist the eval_id and docvTransactionToken to correlate the webhook result later.
  2. Return the token to your client.
  3. Launch the Predictive DocV SDK Capture App to present the capture UI.

Receive the final decision

After capture, RiskOS™ resumes the evaluation and delivers the final result through the evaluation_completed webhook event. Correlate it to the original evaluation with eval_id.

{
  "event_type": "evaluation_completed",
  "data": {
    "eval_id": "7e79e169-5021-475b-af98-9362ac690c38",
    "decision": "ACCEPT",
    "status": "CLOSED",
    "eval_status": "evaluation_completed"
  }
}
📘

Note:

Register a webhook endpoint before you run active capture in Production. Without it, your integration can't receive the asynchronous final decision.


FAQs

How do I tell an OTP step-up from an active capture step-up?

Both pause the evaluation with status: ON_HOLD. An active capture step-up also includes a data_enrichments object where enrichment_provider is SocureDocRequest and carries a docvTransactionToken. An OTP step-up has no SocureDocRequest handoff — you resume it by resubmitting the evaluation with the passcode.

How do I resend a one-time passcode?

Resubmit the evaluation with the same request id and data.individual.otp.resend set to true. RiskOS™ sends a new passcode instead of verifying one.

What happens if the user abandons a step-up?

The evaluation stays ON_HOLD until the user completes the step-up or the workflow's configured timeout is reached. Route the user to your fallback flow if the step-up does not complete.


Related


Did this page help you?