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_completedwebhook.
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
idand the code underdata.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
}| Field | Type | Description |
|---|---|---|
verificationId | String | Identifier for the OTP verification attempt. |
status | String | Verification status, for example approved or reject. |
attemptCount | Integer | Number 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_statusis"evaluation_paused"orstatusis"ON_HOLD".data_enrichmentsincludes an object whereenrichment_provideris"SocureDocRequest".
Extract the handoff assets
Read these from the SocureDocRequest object's response.data:
| Field | Purpose |
|---|---|
docvTransactionToken | Required. Initialize the Capture App or DocV SDK with this value. |
url | Optional. Direct mobile redirect to the Capture App. |
qrCode | Optional. 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
- Persist the
eval_idanddocvTransactionTokento correlate the webhook result later. - Return the token to your client.
- 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
Updated 9 days ago

