## After the Hosted Flow

After you [create the evaluation and redirect the user to the Hosted Flow](https://help.socure.com/riskos/docs/kyc-watchlist-screening-hosted-flow-start-an-evaluation), the initial API response contains `decision: "REVIEW"` and `status: "ON_HOLD"`. This is not the final decision — it indicates the evaluation is paused while the user completes the hosted experience.

The final outcome is delivered asynchronously via the `evaluation_completed` webhook.

## Receive the final decision (webhook)

After the Hosted Flow completes, RiskOS™ sends an `evaluation_completed` [webhook](https://help.socure.com/riskos/docs/webhook-events) to your [configured webhook endpoint](https://help.socure.com/riskos/docs/webhooks).

The final outcome is in:

- `data.decision`

RiskOS™ responses include additional fields for enrichment results, workflow context, and observability. This workflow processes multiple enrichments, including [Digital Intelligence](https://help.socure.com/riskos/docs/digital-intelligence), [Socure Verify](https://help.socure.com/riskos/docs/verify-integration-guide), [Sigma Identity Fraud](https://help.socure.com/riskos/docs/sigma-identity-fraud-integration-guide), [Sigma Synthetic Fraud](https://help.socure.com/riskos/docs/sigma-synthetic-fraud-integration-guide), [Watchlist Screening](https://help.socure.com/riskos/docs/integrate-watchlist-screening), and [Document Verification (DocV)](https://help.socure.com/riskos/docs/docv-integration-guide). See each enrichment's integration guide for full response schema details.

### Example webhook

Example webhook payload (truncated)

```json
{
  "event_type": "evaluation_completed",
  "event_id": "3b31289c-2d4a-4107-80bc-dda63031d5a0",
  "event_at": "2025-07-17T01:20:01Z",
  "data": {
    "eval_id": "11111111-2222-3333-4444-555555555555",
    "id": "client-transaction-12345",
    "workflow": "consumer_onboarding",
    "workflow_id": "5937a624-f298-452c-9169-ceeae9e66b74",
    "workflow_version": "1.0.0",
    "environment_name": "Sandbox",
    "eval_source": "API",
    "eval_start_time": "2025-07-17T01:18:27Z",
    "eval_end_time": "2025-07-17T01:20:01Z",
    "evaluation_status": "evaluation_completed",
    "decision": "ACCEPT",
    "decision_at": "2025-07-17T01:20:01Z",
    "status": "CLOSED",
    "sub_status": "Accept",
    "tags": [],
    "notes": "",
    "review_queues": [
      "Default Queue"
    ],
    "data_enrichments": [
      {
        "enrichment_name": "Socure Document Request - Default Flow",
        "enrichment_endpoint": "https://service.socure.com/api/5.0/documents/request",
        "enrichment_provider": "SocureDocRequest",
        "status_code": 200,
        "response": {
          "referenceId": "ed6a5077-b272-4a75-8c21-b284e10927cd",
          "status": "SESSION_COMPLETE",
          "data": {
            "docvTransactionToken": "7d6ad42b-f804-4255-b25e-268b8a77c86f",
            "url": "https://verify.socure.com/#/dv/7d6ad42b-f804-4255-b25e-268b8a77c86f"
          }
        }
      },
      {
        "enrichment_name": "Socure Document Verification",
        "enrichment_endpoint": "https://service.socure.com/api/5.0/documents/verify",
        "enrichment_provider": "Socure",
        "status_code": 200,
        "response": {
          "referenceId": "ed6a5077-b272-4a75-8c21-b284e10927c",
          "documentVerification": {
            "decision": {
              "name": "standard",
              "value": "accept"
            },
            "reasonCodes": [
              "I831",
              "I836"
            ],
            "documentType": {
              "type": "Drivers License",
              "country": "US",
              "state": "NY"
            },
            "documentData": {
              "firstName": "Test",
              "surName": "User",
              "fullName": "Test User",
              "dob": "1990-01-01",
              "documentNumber": "TST1234567",
              "expirationDate": "2030-01-01"
            }
          }
        }
      }
    ]
  }
}
```

## Route the user based on the final decision

Because the evaluation completes asynchronously, your frontend should wait for your backend to persist the final decision before routing the user.

Expose the persisted `decision` from your backend to the frontend (for example, via a status endpoint), then handle routing as follows:

- `ACCEPT` → Continue onboarding
- `REJECT` → Route to fallback or denial flow
- `REVIEW` → Route to manual review (if applicable)

One common approach is polling your backend until the stored `decision` is available.

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

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

## 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 |
| `status` | Overall request status |
| `eval_status` | Evaluation processing status |
| `workflow` | Workflow name (optional) |

## Implementation flow

```undefined
Start evaluation
    |
    v
Store `eval_id`
    |
    v
Redirect user to the Hosted Flow
    |
    v
Wait for webhook
    |
    v
Persist final `decision`
    |
    v
Route user based on outcome
```

## Summary

- The API response starts the session.
- The user completes verification in the Hosted Flow.
- The webhook delivers the final decision.
- Your application should act only on the webhook result.
