Build an Age Assurance Integration
Connect your systems to the RiskOS™ Evaluation API to run Age Assurance evaluations, act on privacy-preserving threshold decisions, and handle step-up flows.
Overview
Age Assurance uses the same single RiskOS™ Evaluation API as every other workflow. You submit a POST /api/evaluation request that names your Age Assurance workflow and carries the inputs the workflow needs. RiskOS™ orchestrates the passive and active methods you configured and returns a privacy-preserving threshold decision.
This guide covers the system integration: connecting your backend to the Evaluation API, submitting requests, acting on decisions, and handling step-ups. For method selection, waterfall ordering, and routing, see Configure the Workflow.
System architecture
sequenceDiagram
participant Client as Client App + SDK
participant Backend as Your Backend
participant RiskOS as RiskOS
Client->>Backend: Collect inputs and consent
Backend->>RiskOS: POST /api/evaluation
RiskOS->>RiskOS: Run passive waterfall (device, email, phone)
alt Passive method resolves age
RiskOS-->>Backend: ACCEPT or REJECT + Valid Age tag
Backend-->>Client: Allow or block
else OTP or active capture required
RiskOS-->>Backend: ON_HOLD with OTP or capture link
Backend-->>Client: Prompt user
Client->>Backend: Submit OTP or complete capture
Backend->>RiskOS: Resume evaluation
RiskOS-->>Backend: Final decision
Backend-->>Client: Allow or block
end
Integration flow
- Collect the inputs your configured methods need. Passive assurance uses a phone number, email, name, or address; device-based assurance uses a Digital Intelligence session token from the Digital Intelligence SDK. Age Assurance does not require date of birth or SSN.
- Submit a
POST /api/evaluationrequest from your backend with the workflow name and collected inputs. - Act on the top-level
decision(ACCEPTorREJECT) andValid Agetag to allow or block the user. - Handle a step-up if the workflow pauses for an OTP or an active selfie or document capture. See Step-up flows.
Required components
di\_session\_token — required only for device-based assurance.
Endpoint
POST https://riskos.sandbox.socure.com/api/evaluation POST https://riskos.socure.com/api/evaluationInclude your API key in the Authorization header:
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
Accept: application/jsonExample request
Send the workflow name plus the inputs your waterfall reads. Phone-based assurance uses a phone number; email-based assurance uses an email; device-based assurance uses a Digital Intelligence session token. The workflow's routing conditions decide whether to escalate to an active selfie or document capture; the docv.config object controls that capture experience (language and whether Socure sends the capture link).
{
"id": "test-user-phone",
"timestamp": "2026-07-07T12:44:22.059Z",
"workflow": "docv_demo_socure",
"data": {
"event_type": "identity_verification",
"individual": {
"given_name": "Alex",
"family_name": "Doe",
"phone_number": "19843359615",
"email": "[email protected]",
"address": {
"country": "US"
},
"docv": {
"config": {
"language": "en",
"send_message": false
}
}
},
"channel": "web"
}
}curl --request POST \
--url https://riskos.sandbox.socure.com/api/evaluation \
--header "Authorization: Bearer YOUR_API_KEY" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data '{
"id": "test-user-phone",
"timestamp": "2026-07-07T12:44:22.059Z",
"workflow": "docv_demo_socure",
"data": {
"event_type": "identity_verification",
"individual": {
"given_name": "Alex",
"family_name": "Doe",
"phone_number": "19843359615",
"email": "[email protected]",
"address": {
"country": "US"
},
"docv": {
"config": {
"language": "en",
"send_message": false
}
}
},
"channel": "web"
}
}'Request fields
Note:
For the complete field schema, see the Evaluation API Reference.
Top-level fields
Path: root request object
| Field | Type | Required | Description | Example |
|---|---|---|---|---|
id | String | Required | Customer-defined unique identifier for the request. Reusing an ID causes RiskOS™ to treat the request as a re-run. | "test-user-phone" |
timestamp | String | Required | RFC 3339 timestamp for when your system initiated the request. | "2026-07-07T12:44:22.059Z" |
workflow | String | Required | Your environment-specific Age Assurance workflow identifier. | "docv_demo_socure" |
data.event_type | String | Optional | The event category for the evaluation. | "identity_verification" |
data.channel | String | Optional | The channel the request originates from. | "web" |
Individual fields
Path: data.individual
| Field | Type | Required | Description | Example |
|---|---|---|---|---|
given_name | String | Optional | First name. Improves passive identity resolution. | "Alex" |
family_name | String | Optional | Last name. Improves passive identity resolution. | "Doe" |
phone_number | String | Conditional | Required for phone-based assurance. | "19843359615" |
email | String | Conditional | Required for email-based assurance. | "[email protected]" |
address.country | String | Optional | Country in ISO 3166-1 alpha-2 format. | "US" |
Device fields
Path: data.individual
| Field | Type | Required | Description | Example |
|---|---|---|---|---|
di_session_token | String | Conditional | Device session token captured by the Digital Intelligence SDK and passed in the request. Required for device-based assurance. | "eyJraWQiOi_di_token" |
DocV configuration fields
Path: data.individual.docv.config
| Field | Type | Required | Description | Example |
|---|---|---|---|---|
send_message | Boolean | Optional | When true, RiskOS™ sends the capture link to the user for the active step. When false, your app opens the capture flow directly. | false |
language | String | Optional | Capture-app language. | "en" |
Tip:
Routing conditions in an Age Assurance workflow branch on whether a request field is set — for example, whether a phone number, email, or device signal is present. They can also branch on custom fields you pass in the request. See How routing works.
Handling responses
The evaluation response reports the age result at two levels: a top-level decision your application acts on, and per-method threshold flags under computed for finer-grained logic.
Decision routing
| Decision | Action |
|---|---|
ACCEPT | Allow the user through. A Valid Age tag confirms the age check passed. |
REJECT | Block the user or route to a fallback flow. |
Use the top-level decision and Valid Age tag as your primary control signal. Do not use status, sub_status, or eval_status for business decisions — those describe evaluation lifecycle state only.
Example response
{
"id": "test-user-phone",
"workflow": "docv_demo_socure",
"eval_id": "7e79e169-5021-475b-af98-9362ac690c38",
"decision": "ACCEPT",
"status": "CLOSED",
"sub_status": "Accept",
"tags": ["Valid Age"],
"computed": {
"socure_age_assurance_response": {
"age18Plus": true,
"age21Plus": true,
"age25Plus": false,
"entityKind": "phone",
"isSuccess": true,
"refId": "789a83ce-8b28-4239-8a7c-20e1a8ba0b5a",
"uniqueCnt": 96
}
},
"eval_status": "evaluation_completed"
}Key response fields
| Area | Fields | Purpose |
|---|---|---|
| Decision and routing | decision, tags, review_queues, score | Primary signals for application logic and secondary routing |
| Threshold flags | computed.socure_age_assurance_response | Per-method Boolean age-threshold results (age18Plus/21/25) |
| Traceability | id, eval_id | Persist for correlation across API calls, logs, webhooks, and support |
| Lifecycle | eval_status, status, sub_status | Monitoring and async flow tracking only |
Threshold flag fields
A passive method returns its result under computed.socure_age_assurance_response:
| Field | Type | Description |
|---|---|---|
age18Plus | Boolean | true if the user meets the 18+ threshold, false if not. |
age21Plus | Boolean | true if the user meets the 21+ threshold, false if not. |
age25Plus | Boolean | true if the user meets the 25+ threshold, false if not. |
entityKind | String | The method that produced the result: globalDeviceId, email, phone, selfie, or document. |
isSuccess | Boolean | true when the method returned a usable result. |
refId | String | Enrichment-level reference identifier. |
uniqueCnt | Integer | Identity-graph match count (cardinality) for the lookup. |
Active methods (selfie or document) wrap the same threshold flags in an ageAssurance object under computed.socure_selfie_age_assurance_response, and add a decision of accept, reject, or resubmit.
Full response reference:
For the complete evaluation response envelope — lifecycle fields,
decision,tags, and enrichment objects — see the Evaluation API Reference.
Step-up flows
Some 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.
- One-time passcode (OTP)
If a phone- or email-based method needs to confirm contact ownership, the evaluation pauses for OTP verification. Resume the evaluation by resubmitting the passcode with the original request id. - Active capture (selfie or document)
If passive methods cannot resolve age, the evaluation pauses for selfie or document capture. Launch the Capture App or DocV SDK and wait for the final decision on the evaluation_completed webhook.
For implementation details, including request payloads, capture handoff assets, and webhook handling, see Handle Age Assurance Step-Up Flows.
Billing behavior
Age Assurance bills only when a method returns a usable result.
| Method category | Billable when... |
|---|---|
| Passive (device / phone / email) | Age is successfully returned. A no-hit lookup is not billable. |
| Phone / email OTP | Billed as part of the age-lookup SKU (not a separate charge). Runs only when an identity exists. |
This "no hit, no charge" model on passive methods lets you place low-cost lookups early in a waterfall without paying for misses.
Privacy and data handling
Age Assurance minimizes the age-related data your application ever receives or that Socure retains.
Not returned to your application:
- Date of birth
- Exact age or age range
- Raw PII
- Images (selfie or document)
- Confidence scores
Deleted immediately after processing:
- Input phone number and email
- Captured images (selfie, document)
- Age-range and confidence response data
- OTP-related data is deleted or anonymized
Retained for billing and audit only:
- Transaction ID and timestamp
- Methods (modules) called
- Method used for billing
- Final decision
Socure does not store raw PII, images, or confidence scores in the audit record.
Integration testing
isSuccess: true and returns the threshold flags
decision for accept, reject, and resubmit
decision and Valid Age tag
id and eval\_id are persisted for traceability
Before going live
For a comprehensive go-live process, see the Go-Live Checklist.
FAQs
What is the primary field to act on?
Use the top-level decision (ACCEPT or REJECT) and the Valid Age tag as your primary signal. The per-method threshold flags (age18Plus, age21Plus, age25Plus) under computed are available for finer-grained logic.
How do I switch a workflow from selfie to document capture?
Configure the routing conditions in the RiskOS™ Dashboard. Conditions branch on request inputs (for example, whether a phone, email, or device signal is present) and can also read custom fields you pass in the request. Because routing is configured in the workflow, you can change the active method without a code change once the workflow is integrated.
Related
Updated 9 days ago

