Use **Hosted Flows** when you want a no-SDK integration. Instead of embedding a capture UI, your app redirects the consumer to Socure's hosted Capture App in a browser. The evaluation response returns a top-level `redirect_uri` — you send the consumer there to start capture.

This guide covers the Hosted Flows path end to end. To embed the capture UI in your own app instead, see [DocV Direct API Integration](https://help.socure.com/riskos/docs/docv-sdk-integration).

## Before you start

[Publish a workflow](https://help.socure.com/riskos/docs/workflows) configured for Socure's hosted experience that includes a **Document Request** step, with decision logic that routes on the workflow decision (`ACCEPT`, `REVIEW`, `REJECT`).

Get your **API key** from the [API & SDK Keys](https://riskos.sandbox.socure.com/developers/key-management) page in the RiskOS™ Dashboard. Hosted Flows needs no SDK key.

Publish a [Capture App flow](https://help.socure.com/riskos/docs/capture-app-setup) for your flow type.

Register a [webhook endpoint](https://help.socure.com/riskos/docs/webhooks) to receive `evaluation\_completed` events for asynchronous decisions and optional `case\_notes\_added` events for status updates.

## Step 1: Create the evaluation

Submit consumer data to the RiskOS™ Evaluation API. Because your workflow contains a Document Request step, RiskOS™ pauses the evaluation and returns the `redirect_uri` you send the consumer to.

### Endpoint and authentication

Start with **Sandbox** for development and testing, then move to **Production** for live applications.

SandboxProduction

```http
POST https://riskos.sandbox.socure.com/api/evaluation
```

```http
POST https://riskos.socure.com/api/evaluation
```

Include your API key as a Bearer token:

HTTP

```http
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
Accept: application/json
X-API-Version: 2025-01-01.orion   # optional – pins a specific API version
```

### Example request

Send the consumer's PII and your `docv.config` capture settings. To bring the consumer back to your app after capture, set your callback URL in `data.individual.custom.redirect_uri`. Optionally set `docv.config.send_message: true` to text the consumer the Capture App link.

```curl
curl --request POST \
  --url https://riskos.sandbox.socure.com/api/evaluation \
  --header "Authorization: Bearer YOUR_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "id": "APP-123456",
    "timestamp": "2025-07-31T15:00:10.761Z",
    "workflow": "docv_socure_pass",
    "data": {
      "individual": {
        "given_name": "John",
        "family_name": "Smith",
        "date_of_birth": "1989-05-07",
        "phone_number": "+19998887777",
        "address": {
          "line_1": "1234 N College Ave",
          "locality": "New York City",
          "major_admin_division": "NY",
          "country": "US",
          "postal_code": "10001"
        },
        "custom": {
          "redirect_uri": "https://yourapp.com/callback"
        },
        "docv": {
          "config": {
            "use_case_key": "your-use-case-key",
            "document_type": "license",
            "send_message": true,
            "language": "en-us"
          }
        }
      }
    }
  }'
```

```json
{
  "id": "APP-123456",
  "timestamp": "2025-07-31T15:00:10.761Z",
  "workflow": "docv_socure_pass",
  "data": {
    "individual": {
      "given_name": "John",
      "family_name": "Smith",
      "date_of_birth": "1989-05-07",
      "phone_number": "+19998887777",
      "address": {
        "line_1": "1234 N College Ave",
        "locality": "New York City",
        "major_admin_division": "NY",
        "country": "US",
        "postal_code": "10001"
      },
      "custom": {
        "redirect_uri": "https://yourapp.com/callback"
      },
      "docv": {
        "config": {
          "use_case_key": "your-use-case-key",
          "document_type": "license",
          "send_message": true,
          "language": "en-us"
        }
      }
    }
  }
}
```

### Configure by DocV product

DocV supports four [flow types](https://help.socure.com/riskos/docs/docv-integration-guide#supported-flow-types). They share the same PII fields described earlier in this topic, but each requires different `docv` configuration, and the result returns a different enrichment object. You select the flow with the `use_case_key` from your published [Capture App flow](https://help.socure.com/riskos/docs/capture-app-setup) — the rest of the request changes as shown in the following tabs.

| Flow type | Distinguishing request fields | Result enrichment object |
| --- | --- | --- |
| **[Document Verification](https://help.socure.com/riskos/docs/document-verification-setup)** | `config.document_type` (`license` \| `passport`) to skip the selection screen | `documentVerification` |
| **[Secondary Document Capture](https://help.socure.com/riskos/docs/secondary-doc-setup)** | `config.use_case_key` for a secondary-document flow; no `document_type` | `secondaryDocument` |
| **[Selfie Intelligence](https://help.socure.com/riskos/docs/selfie-intelligence-setup)** | `config.use_case_key` for a selfie flow; no `document_type` | `selfieIntelligence` |
| **[Selfie Reverification](https://help.socure.com/riskos/docs/selfie-reverification-setup)** | `config.use_case_key` **and**`additional_context.previous_reference_id` | `selfieReverification` |

Captures a government-issued ID and a selfie. Set `document_type` to skip the document-selection screen, or omit it to let the consumer choose.

JSON

```json
// ...excerpt of the full request body — data.individual shown
"individual": {
  "given_name": "John",
  "family_name": "Smith",
  "phone_number": "+19998887777",
  "address": { "country": "US" },
  "custom": { "redirect_uri": "https://yourapp.com/callback" },
  "docv": {
    "config": {
      "document_type": "license",
      "language": "en-us"
    }
  }
}
```

Captures supporting documents such as utility bills or bank statements (JPEG, PNG, or PDF). No selfie or facial match. Select the flow with `use_case_key` and omit `document_type`.

JSON

```json
// ...excerpt of the full request body — data.individual shown
"individual": {
  "given_name": "John",
  "family_name": "Smith",
  "phone_number": "+19998887777",
  "address": { "country": "US" },
  "custom": { "redirect_uri": "https://yourapp.com/callback" },
  "docv": {
    "config": {
      "use_case_key": "YOUR_SECONDARY_DOC_FLOW",
      "language": "en-us"
    }
  }
}
```

Captures a live selfie for age, liveness, and trust checks. Select the flow with `use_case_key` and omit `document_type`.

JSON

```json
// ...excerpt of the full request body — data.individual shown
"individual": {
  "given_name": "John",
  "family_name": "Smith",
  "phone_number": "+19998887777",
  "address": { "country": "US" },
  "custom": { "redirect_uri": "https://yourapp.com/callback" },
  "docv": {
    "config": {
      "use_case_key": "YOUR_SELFIE_FLOW",
      "language": "en-us"
    }
  }
}
```

Captures a live selfie and compares it to a prior DocV headshot. **Requires**`additional_context.previous_reference_id` — the reference ID of the earlier evaluation that holds the headshot.

JSON

```json
// ...excerpt of the full request body — data.individual shown
"individual": {
  "given_name": "John",
  "family_name": "Smith",
  "phone_number": "+19998887777",
  "address": { "country": "US" },
  "custom": { "redirect_uri": "https://yourapp.com/callback" },
  "additional_context": {
    "previous_reference_id": "3639f9ad-e1fe-4e3e-9202-18faf20ace56"
  },
  "docv": {
    "config": {
      "use_case_key": "YOUR_REVERIFICATION_FLOW",
      "language": "en-us"
    }
  }
}
```

### Request fields

**Minimum required for DocV:**`given_name`, `family_name`, `phone_number` (E.164), and `address.country`. Add `date_of_birth`, `email`, and the remaining address fields for the highest match accuracy.

**Top-level fields** (path: root request object)

| Field | Type | Required | Description | Example |
| --- | --- | --- | --- | --- |
| `id` | String | Required | Customer-defined unique identifier for the request. Must be unique per evaluation — reusing an ID causes RiskOS™ to treat the request as a re-run and can affect results. | `"APP-123456"` |
| `timestamp` | String `<Date-Time>` | Required | RFC 3339 timestamp indicating when the evaluation request was initiated. | `"2025-07-31T15:00:10.761Z"` |
| `workflow` | String | Required | Environment-specific workflow identifier from RiskOS™. Must identify a single active workflow. | `"consumer_onboarding"` |
| `data.ip_address` | String | Optional | Client IP address (IPv4/IPv6). Used for device intelligence. | `"1.2.3.4"` |

**Individual fields** (path: `data.individual`)

| Field | Type | Required | Description | Example |
| --- | --- | --- | --- | --- |
| `given_name` | String | Required | Consumer's first/given name. | `"John"` |
| `family_name` | String | Required | Consumer's last/family name. | `"Smith"` |
| `date_of_birth` | String | Optional | Date of birth in ISO 8601 format (`YYYY-MM-DD`). | `"1989-05-07"` |
| `phone_number` | String | Required | Phone number. The API expects **E.164 format** but tolerates hyphens and spaces. | `"+19998887777"` |
| `email` | String | Optional | Consumer's email address. | `"john.smith@example.com"` |
| `custom.redirect_uri` | String | Optional | The URL RiskOS™ returns the consumer to after the hosted Capture App completes or is canceled. Set this to bring the consumer back to your app. | `"https://yourapp.com/callback"` |
| `additional_context` | Object | Optional | Passes additional data required by specific Socure products. See [Additional context fields](https://help.socure.com/riskos/docs/docv-hosted-flows-integration#additional-context-fields). | `{ "previous_reference_id": "…" }` |

**Address fields** (path: `data.individual.address`)

| Field | Type | Required | Description | Example |
| --- | --- | --- | --- | --- |
| `line_1` | String | Optional | The first line of the consumer's address. | `"1234 N College Ave"` |
| `line_2` | String | Optional | An optional second line, such as apartment or suite number. | `"Apt 4B"` |
| `locality` | String | Optional | City, town, or village where the consumer resides. | `"New York City"` |
| `major_admin_division` | String | Optional | State, province, or region (ISO 3166-2). | `"NY"` |
| `postal_code` | String | Optional | ZIP, postal code, or equivalent regional identifier. | `"10001"` |
| `country` | String | Required | Country in **ISO 3166-1 alpha-2 country code** format. | `"US"` |

**Predictive DocV fields** (path: `data.individual.docv`)

DocV behavior is configured server-side through the `docv` object and its nested `config` object. All fields are optional or conditional:

| Field | Type | Required | Description | Example |
| --- | --- | --- | --- | --- |
| `config` | Object | Optional | Configuration options controlling Capture App behavior and the document verification flow. | `{ "document_type": "license" }` |
| `config.document_type` | String (`license` \| `passport`) | Optional | Restrict capture to a single type to skip the document selection screen. | `"license"` |
| `config.use_case_key` | String | Optional | Deploy a specific [Capture App flow](https://help.socure.com/riskos/docs/capture-app-setup). Defaults to your account's default flow. | `"your-use-case-key"` |
| `config.send_message` | Boolean | Optional | Set to `true` to send the consumer an SMS with the document request URL. Defaults to `false`. Sent from short code 33436 in the US & Canada; from +1 (510) 330-19xx in other countries. | `false` |
| `config.language` | String | Optional | Capture App [UI language](https://help.socure.com/riskos/docs/language-options). Defaults to `en-us`. | `"en-us"` |
| `config.redirect.url` | String (URL) | Conditional | Destination URL the Capture App sends the consumer to after capture completes or is canceled. Required if `redirect` is provided. | `"https://www.example.com"` |
| `config.redirect.method` | String (`GET` \| `POST`) | Conditional | HTTP method for the redirect. Required if `redirect` is provided. | `"GET"` |
| `config.transaction_token` | String | Conditional | Used primarily in Sandbox testing to indicate the expected decision outcome. Required when simulating test results. See [Test Your Integration](https://help.socure.com/riskos/docs/docv-test-integration). | `"SOC32671365"` |

#### Additional context fields

Path: `data.individual.additional_context`

The `additional_context` object passes extra data required by specific Socure products and flows:

| Field | Type | Required | Description | Example |
| --- | --- | --- | --- | --- |
| `driver_license` | String | Optional | Driver's license number. | `"000000000"` |
| `driver_license_state` | String | Optional | Two-letter issuing state code. | `"NY"` |
| `previous_reference_id` | String (UUID) | Conditional | Reference to a prior evaluation. Required when using the Selfie Reverification enrichment. | `"3639f9ad-e1fe-4e3e-9202-18faf20ace56"` |

### Step 2: Handle the paused response

When the workflow reaches the Document Request step, RiskOS™ pauses the evaluation and returns `decision: "REVIEW"`, `status: "ON_HOLD"`, and `eval_status: "evaluation_paused"`. The launch asset is a **top-level `redirect_uri`** — there is no `docvTransactionToken` on this path.

```json
{
  "id": "APP-123456",
  "workflow": "docv_socure_pass",
  "eval_id": "6c3e1165-1617-4417-b759-92176c75c6e5",
  "decision": "REVIEW",
  "status": "ON_HOLD",
  "eval_status": "evaluation_paused",
  "redirect_uri": "https://riskos.sandbox.socure.com/hosted/xyz"
}
```

These fields confirm the workflow is waiting for capture:

| Field | Value | Meaning |
| --- | --- | --- |
| `eval_id` | UUID | The evaluation identifier. **Persist this** — you need it to correlate the result webhook. |
| `decision` | `REVIEW` | The workflow is paused, not finished. Do not treat this as a final decision. |
| `status` | `ON_HOLD` | The evaluation is held, waiting for the consumer to complete capture. |
| `eval_status` | `evaluation_paused` | Confirms the pause at the Document Request step. |

The launch asset for the Hosted Flows path is the top-level `redirect_uri`:

| Field | Location | Description |
| --- | --- | --- |
| `redirect_uri` | Top level of the response | Redirect the consumer to this URL to start capture. |

### Step 3: Launch by redirecting the consumer

Send the consumer to the top-level `redirect_uri` to start Socure's hosted Capture App. RiskOS™ resumes the paused evaluation automatically when capture finishes.

| Delivery method | How to use |
| --- | --- |
| **Redirect** | Redirect the consumer's browser to the top-level `redirect_uri` value from the evaluation response. |
| **SMS delivery** | Set `send_message: true` in `docv.config` on the request. RiskOS™ sends an SMS with the Capture App link to the consumer's phone number. |

TypeScript

```typescript
function handleStepUp(evaluationResponse: EvaluationResponse) {
  // Hosted Flows returns a top-level redirect_uri — send the consumer there
  window.location.href = evaluationResponse.redirect_uri;

// SMS is sent automatically when send_message is true in docv.config
}
```

### Return the consumer to your app after capture

The callback URL you set in `data.individual.custom.redirect_uri` (Step 1) is where RiskOS™ sends the consumer after the Capture App completes or is canceled. Use it to return the consumer to your app's "verification in progress" screen — the final decision still arrives through the [webhook](https://help.socure.com/riskos/docs/docv-receive-results), not the redirect.

## Step 4: Receive the result

Once capture finishes, RiskOS™ resumes the evaluation and delivers the final `ACCEPT`, `REVIEW`, or `REJECT` decision through the `evaluation_completed` webhook. You can also retrieve the result with a GET request using the `eval_id` you persisted in Step 2.

For the webhook payload, the enrichment objects returned per flow type, and how to retrieve results, see [Receive DocV Results](https://help.socure.com/riskos/docs/docv-receive-results).

## Retry behavior

Document Verification runs **once per evaluation**. If the capture session does not reach `SESSION_COMPLETE` — it expires, the consumer declines consent, or DocV returns `reject` or `resubmit` — the evaluation resolves to `REJECT`. To retry Document Verification, create a new evaluation.

## Error handling

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

| Status code | Meaning | What to do |
| --- | --- | --- |
| `400` | Bad request — missing or invalid fields | Check the request body against the required fields above. |
| `401` | Unauthorized — invalid or missing API key | Verify your `Authorization` header and that the key matches the environment. |
| `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). |

### Additional resources

- [DocV Integration Overview](https://help.socure.com/riskos/docs/docv-integration-guide)
- [Socure Hosted UX (Capture App)](https://help.socure.com/riskos/docs/capture-app)
- [Language options](https://help.socure.com/riskos/docs/language-options#/)  
- [Hosted Flows integration guide](https://help.socure.com/riskos/docs/hosted-flows-integration-guide)  
- [Receive DocV Results](https://help.socure.com/riskos/docs/docv-receive-results)  
- [Evaluation API Reference](https://help.socure.com/riskos/reference)

Updated about 1 month ago
