## Step 1: Detect Document Verification

Identify a step-up to DocV by checking that all of the following are present in the evaluation response:

- `eval_status = evaluation_paused`
- `data_enrichments` contains an object where `enrichment_provider = "SocureDocRequest"`

### Extract handoff assets

Locate the `SocureDocRequest` object and extract the following from `response.data`:

| Field | Purpose |
| --- | --- |
| `docvTransactionToken` | **Required.** Pass this to your frontend to initialize the DocV SDK. |
| `url` | **Optional.** Use for direct mobile redirects to the Capture App. |
| `qrCode` | **Optional.** Base64 PNG for desktop-to-mobile handoff. |

### Example response

JSON

```json
{
  "decision": "REVIEW",
  "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/..."
        }
      }
    }
  ]
}
```

**Note**:

The `REVIEW` decision in this response is non-terminal and indicates the evaluation is paused for DocV.

**What to do**:

1. Locate the `SocureDocRequest` object in `data_enrichments`.
2. Extract `docvTransactionToken` from `response.data`.
3. Persist the `eval_id` and `docvTransactionToken`.
4. Send the token to your frontend and launch DocV.
5. Wait for the final result via webhook or updated evaluation.

## Step 2: Launch the DocV Web SDK

The [DocV Web SDK](https://help.socure.com/riskos/docs/web-sdk) is a client-side JavaScript library that embeds the RiskOS™ document verification experience directly into your application.

It renders the [Capture App](https://help.socure.com/riskos/docs/capture-app), a secure mobile experience that guides the user through:

- Capturing a government-issued ID
- Taking a selfie
- Completing liveness verification

The Capture App UI is configurable from the **DocV App** page in the RiskOS™ Dashboard.

1. Include the DocV Web SDK script in your application.
2. Pass your **SDK key** (from the RiskOS™ Dashboard) and `docvTransactionToken` to `SocureDocVSDK.launch()`.

HTML

```html
<html>
  <head>
    <script src="https://websdk.socure.com/bundle.js"></script>
  </head>
  <body>
    <button onclick="start()">Start Verification</button>
    <div id="websdk"></div>

<script>
      var config = {
        onProgress: function (event) {
          /* Called during capture */
        },
        onSuccess: function (response) {
          /* Called on success */
        },
        onError: function (error) {
          /* Called on error */
        },
        qrCodeNeeded: true, // Show QR code option
        disableSmsInput: false, // Enable SMS input
        closeCaptureWindowOnComplete: true, // Auto-close tab after document upload confirmation
        autoOpenTabOnMobile: true, // Skip "Continue on New Tab" screen on mobile and launch Capture App in a new tab
      };
      function start() {
        SocureDocVSDK.launch(
          'SDKKey', // Replace with your SDK Key
          'docvTransactionToken', // Replace with the docvTransactionToken
          '#websdk',
          config // optional
        );
      }
    </script>
  </body>
</html>
```

### Handoff options

Depending on your integration pattern, users can access the Capture App using:

1. **QR code** for desktop-to-mobile handoff
2. **Secure SMS link** for desktop or mobile
3. **Mobile redirect URL** using `response.data.url`

**No retry or resubmit**

Document Verification runs once per evaluation.

The following conditions result in a `REJECT` decision:

- DocV returns `reject` or `resubmit`
- The DocV request does not reach `SESSION_COMPLETE`
- The session expires
- The user declines consent
- DocV request or response errors occur

## Step 3: Receive the final decision

DocV is asynchronous. After the Capture App flow completes, RiskOS™ resumes the paused evaluation, performs Watchlist Screening, and returns the final result.

Use one of the following approaches:

- Wait for an updated evaluation
- Receive the final result through a [webhook event](https://help.socure.com/riskos/docs/docv-receive-results)

To receive the final decision by webhook, configure a webhook endpoint on the [Developer Workbench > Webhooks](https://help.socure.com/riskos/docs/webhooks) page in the RiskOS™ Dashboard.

### Watchlist screening behavior

After Document Verification completes, RiskOS™ performs Watchlist Screening.

The following conditions result in a `REJECT` decision:

- Watchlist match (based on configured reason codes)
- Watchlist service error

Only users who pass both Document Verification and Watchlist Screening receive an `ACCEPT` decision.

### Final routing

After DocV completes:

- Wait for the `evaluation_completed` webhook
- Route based on the terminal response
- Do not re-submit DocV for the same evaluation

**Routing outcomes**:

- `ACCEPT` → Continue onboarding (for example, create account or grant access)
- `REJECT` → Route to your fallback, manual review, or decline flow

### Example routing logic

TypeScript

```typescript
if (data.decision === "ACCEPT") {
  router.push("/success");
}

if (data.decision === "REJECT") {
  router.push("/review");
}
```

## Key takeaways

- Detect Document Verification using `SocureDocRequest` in `data_enrichments`.
- Persist `eval_id` and `docvTransactionToken` for webhook correlation.
- DocV runs once per evaluation.
- Do not route on the initial response (`decision = REVIEW`).
- Wait for the `evaluation_completed` webhook before routing.
- Document Verification failures (including `resubmit`, incomplete, or expired sessions) result in **REJECT**.
- Watchlist matches or errors result in **REJECT**.

## Error handling

If the API returns an HTTP error (4xx or 5xx), your application should handle it before processing any evaluation logic.

| Status code | Meaning | What to do |
| --- | --- | --- |
| `400` | Bad request — missing or invalid fields | Check request body against required fields. |
| `401` | Unauthorized — invalid or missing API key | Verify your `Authorization` header. |
| `404` | Not found — invalid `eval_id` or endpoint | Confirm the `eval_id` and endpoint URL. |
| `429` | Rate limited | Back off and retry after the `Retry-After` header value. |
| `500` | Internal server error | Retry with exponential backoff (max three attempts). |

## Data handling

### What to persist

Store these fields for tracking:

| Field | Description |
| --- | --- |
| `id` | Unique identifier for the request |
| `eval_id` | Evaluation identifier |
| `decision` | Final decision outcome (`ACCEPT` or `REJECT`; initial `REVIEW` is non-terminal) |
| `status` | Overall request status |
| `eval_status` | Evaluation processing status |
| `workflow` | Workflow name |
