## Overview

The Direct API lifecycle allows your platform to collect identity data, submit it to RiskOS™, and progressively complete an evaluation through API calls.

Your application owns the onboarding experience and is responsible for:

- Collecting user identity data (PII)
- Sending API requests to RiskOS™
- Handling responses and routing the user

RiskOS™ processes identity, fraud, and compliance signals and returns decisions either:

- **Synchronously** (immediate `ACCEPT` or `REJECT`), or
- **Asynchronously** when additional verification (such as Document Verification) is required

During the evaluation, RiskOS™ orchestrates Prefill, KYC, Fraud, Watchlist, and conditional step-up verification.

## Key behaviors

| Behavior | Detail |
| --- | --- |
| **Data collection** | Your application is responsible for collecting and validating all identity data. |
| **API communication** | Make all API requests server-to-server using your API key. |
| **Evaluation lifecycle** | The evaluation is stateful and progresses using `eval_id`. |
| **OTP (conditional)** | OTP may occur conditionally before Prefill completes. |
| **Prefill outcome** | Prefill may succeed or fail and impacts UI behavior. |
| **Document capture** | DocV may occur conditionally after downstream checks. Extract the `docvTransactionToken` from the response to launch the [Capture App](https://help.socure.com/riskos/docs/capture-app). |
| **Synchronous decisions** | Decisions are returned immediately when no step-up is required. |
| **Asynchronous decisions** | Decisions are delivered via webhook when DocV is triggered. |

## End-to-end flow

01. Collect initial user data (typically phone number, date of birth, and country).
02. Generate a `di_session_token` using the Digital Intelligence SDK.
03. Create an evaluation (`POST /api/evaluation`).
04. RiskOS™ evaluates device and phone risk signals.
05. If device or phone risk fails, the evaluation is immediately rejected.
06. If additional verification is required, RiskOS™ may trigger a One-Time Passcode (OTP) challenge.
07. After OTP (if required), RiskOS™ runs Prefill.
08. Your application collects any additional required identity data.
09. Continue the evaluation (`PATCH /api/evaluation/{eval_id}`).
10. RiskOS™ runs KYC, Fraud, and Watchlist screening.
11. If no additional verification is required, a final decision is returned synchronously.
12. If additional verification is required, RiskOS™ triggers Document Verification (DocV), pauses the evaluation, and resumes asynchronously via webhook.
13. Route the user based on the final decision.

```plaintext
Your WebhookRiskOS™Your BackendYour FrontendEnd UserYour WebhookRiskOS™Your BackendYour FrontendEnd User
Run Digital Intelligence + Phone Risk
alt[High risk device or phone][Additional verification required]
Run Prefill
alt[Prefill successful][Prefill unsuccessful]
Run KYC, Fraud, Watchlist
alt[No DocV required][DocV required]
Enter initial identity data
1Generate di_session_token
2Submit data
3POST /api/evaluation
4REJECT
5Reject user
6REVIEW (ON_HOLD)
7Prompt OTP
8Enter OTP
9Submit OTP
10PATCH /evaluation/{eval_id}
11Show prefilled data
12Collect full identity data
13Submit additional PII
14PATCH /evaluation/{eval_id}
15ACCEPT or REJECT
16evaluation_paused + docvTransactionToken
17Launch DocV
18Submit document + selfie
19evaluation_completed
20Final decision
21Route user
22
```

## Evaluation processing

During the Direct API flow, RiskOS™ orchestrates multiple products:

- **Digital Intelligence**: Evaluates device and behavioral risk signals early in the flow.
- **Phone Risk**: Validates phone integrity and risk indicators.
- **One-Time Passcode (OTP)**: Conditional verification step before Prefill.
- **Prefill**: Enriches identity data using authoritative sources.
- **KYC**: Verifies identity against trusted providers.
- **Fraud**: Evaluates identity and behavioral fraud signals.
- **Watchlist**: Screens against sanctions, PEP, and adverse media.
- **Document Verification (DocV)**: Step-up verification when additional validation is required.

### Conditional One-Time Passcode

After submitting phone number and date of birth, RiskOS™ may require OTP verification before Prefill can proceed.

OTP is conditional and triggered based on risk signals.

If triggered:

- The evaluation returns `REVIEW` and `ON_HOLD`
- Your application must collect a 6-digit code
- You must continue the evaluation with a `PATCH` request

If OTP fails, the system rejects the evaluation.

### Conditional Document Verification (DocV)

After Prefill and downstream checks, RiskOS™ may require DocV.

DocV is triggered when additional verification is needed based on fraud, identity, or risk signals.

If triggered:

- The evaluation pauses (`evaluation_paused`)
- A `docvTransactionToken` is returned in `data_enrichments`
- Your application must launch the DocV SDK or redirect the user
- The evaluation completes asynchronously via webhook

## Decision delivery

RiskOS™ may return decisions in two ways:

### Synchronous decision

Returned immediately after API request:

- `ACCEPT` → continue onboarding
- `REJECT` → stop or route to fallback
- `REVIEW` → additional steps required

### Asynchronous decision

Occurs when DocV is triggered:

- Evaluation pauses during verification
- Final decision is delivered via webhook (`evaluation_completed`)
- Outcome is in `data.decision`

## End-to-end code walkthrough

This walkthrough shows the full Direct API sequence: create an evaluation, submit an OTP, submit identity data, and handle the final decision via webhook.

### 1. Create the evaluation (`POST`)

```bash
curl --request POST \
  --url "https://riskos.sandbox.socure.com/api/evaluation" \
  --header "Authorization: Bearer YOUR_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "id": "session_abc123",
    "timestamp": "2026-04-15T14:00:00Z",
    "workflow": "non_hosted_advanced_pre_fill",
    "data": {
      "individual": {
        "phone_number": "+14155550001",
        "date_of_birth": "1990-05-15",
        "di_session_token": "tok_device_session",
        "address": {
          "country": "US"
        }
      }
    }
  }'
```

**Response** — OTP required:

```json
{
  "eval_id": "296652a5-0a17-4e9f-8f2c-534076fefcd7",
  "decision": "REVIEW",
  "status": "ON_HOLD",
  "sub_status": "Awaiting Customer OTP",
  "tags": ["OTP Triggered"]
}
```

### 2. Submit the OTP (`PATCH`)

```bash
curl --request PATCH \
  --url "https://riskos.sandbox.socure.com/api/evaluation/296652a5-0a17-4e9f-8f2c-534076fefcd7" \
  --header "Authorization: Bearer YOUR_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "id": "session_abc123",
    "timestamp": "2026-04-15T14:01:00Z",
    "workflow": "non_hosted_advanced_pre_fill",
    "data": {
      "individual": {
        "otp": {
          "code": "482901"
        }
      }
    }
  }'
```

**Response** — OTP verified, additional identity data required:

```json
{
  "eval_id": "296652a5-0a17-4e9f-8f2c-534076fefcd7",
  "decision": "REVIEW",
  "status": "ON_HOLD",
  "sub_status": "More information needed",
  "tags": ["OTP Triggered", "OTP Approved", "Prefill Successful", "Additional PII Requested"]
}
```

### 3. Submit identity data (`PATCH`)

```bash
curl --request PATCH \
  --url "https://riskos.sandbox.socure.com/api/evaluation/296652a5-0a17-4e9f-8f2c-534076fefcd7" \
  --header "Authorization: Bearer YOUR_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "id": "session_abc123",
    "timestamp": "2026-04-15T14:02:00Z",
    "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"
        }
      }
    }
  }'
```

**Response** — evaluation accepted:

```json
{
  "eval_id": "296652a5-0a17-4e9f-8f2c-534076fefcd7",
  "decision": "ACCEPT",
  "status": "CLOSED",
  "tags": ["OTP Triggered", "OTP Approved", "Prefill Successful"]
}
```

If Document Verification (DocV) is triggered instead, the response contains `eval_status: "evaluation_paused"` and a `docvTransactionToken` in `data_enrichments`. Launch the DocV SDK and wait for the `evaluation_completed` webhook.

### 4. Receive the webhook (asynchronous decisions)

For evaluations that require Document Verification (DocV), the final decision arrives via webhook:

```json
{
  "event_type": "evaluation_completed",
  "data": {
    "eval_id": "296652a5-0a17-4e9f-8f2c-534076fefcd7",
    "decision": "ACCEPT",
    "status": "CLOSED",
    "evaluation_status": "evaluation_completed"
  }
}
```

Route the user based on `data.decision`.

## Next steps

- [Start a new evaluation](https://help.socure.com/riskos/docs/prefill-kyc-fraud-watchlist-direct-api-start-an-evaluation)
- [Handle results](https://help.socure.com/riskos/docs/prefill-kyc-fraud-watchlist-direct-api-handle-results)
- [Update an evaluation](https://help.socure.com/riskos/docs/prefill-kyc-fraud-watchlist-direct-api-update-evaluation)
- [Handle additional verification](https://help.socure.com/riskos/docs/prefill-kyc-fraud-watchlist-direct-api-handle-additional-verification)
