> ## Documentation Index
> Fetch the complete documentation index at: https://developer.verilock.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Risk Score Engine

> Unified 0-100 composite risk scoring across all verification signals.

The Risk Score Engine produces a unified **0 -- 100** composite score for each verification session by combining six weighted signal components. Use it to automate approval workflows and flag high-risk sessions for manual review.

## Risk Levels

| Score Range | Level        | Suggested Action          |
| ----------- | ------------ | ------------------------- |
| 0 -- 25     | **Low**      | Auto-approve              |
| 26 -- 50    | **Medium**   | Approve with monitoring   |
| 51 -- 75    | **High**     | Manual review recommended |
| 76 -- 100   | **Critical** | Block or escalate         |

## Score Components

The composite score is a weighted sum of six individual component scores:

| Component                 | Weight | Description                                                          |
| ------------------------- | ------ | -------------------------------------------------------------------- |
| **Document authenticity** | 25%    | MRZ validation, tamper detection, document expiry, hologram analysis |
| **Face match**            | 20%    | Similarity between selfie and document photo                         |
| **Liveness**              | 15%    | Passive or active liveness detection score                           |
| **AML screening**         | 15%    | Sanctions, PEP, and adverse media screening results                  |
| **Device fingerprint**    | 15%    | Browser/device anomalies, VPN, bot detection                         |
| **Data consistency**      | 10%    | Cross-field validation (name/DOB/address consistency across sources) |

<Note>
  Component weights are defaults. Custom weights can be configured per workflow in **Dashboard > Workflows > Risk Settings**.
</Note>

## API

### Get Risk Score

```
GET /v1/sessions/{id}/risk
```

Returns the full risk breakdown for a completed session.

<RequestExample>
  ```bash cURL theme={null}
  curl -X GET \
    "https://verilock.io/api/v1/sessions/ses_a1b2c3d4-e5f6-7890-abcd-ef1234567890/risk" \
    -H "Authorization: Bearer qi_live_your_api_key_here"
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://verilock.io/api/v1/sessions/ses_a1b2c3d4-e5f6-7890-abcd-ef1234567890/risk",
      headers={"Authorization": "Bearer qi_live_your_api_key_here"},
  )

  risk = response.json()
  print(f"Risk level: {risk['risk_level']} ({risk['composite_score']})")
  ```

  ```javascript Node.js theme={null}
  const res = await fetch(
    'https://verilock.io/api/v1/sessions/ses_a1b2c3d4-e5f6-7890-abcd-ef1234567890/risk',
    {
      headers: { 'Authorization': 'Bearer qi_live_your_api_key_here' },
    }
  );

  const risk = await res.json();
  console.log(`Risk level: ${risk.risk_level} (${risk.composite_score})`);
  ```
</RequestExample>

<ResponseExample>
  ```json 200 Low Risk theme={null}
  {
    "session_id": "ses_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "composite_score": 12,
    "risk_level": "low",
    "components": {
      "document_authenticity": {
        "score": 8,
        "weight": 0.25,
        "weighted_score": 2.0,
        "details": {
          "mrz_valid": true,
          "tamper_detected": false,
          "document_expired": false
        }
      },
      "face_match": {
        "score": 5,
        "weight": 0.20,
        "weighted_score": 1.0,
        "details": {
          "similarity": 96.4
        }
      },
      "liveness": {
        "score": 10,
        "weight": 0.15,
        "weighted_score": 1.5,
        "details": {
          "liveness_score": 92.5,
          "liveness_mode": "active"
        }
      },
      "aml_screening": {
        "score": 0,
        "weight": 0.15,
        "weighted_score": 0.0,
        "details": {
          "matches_found": 0
        }
      },
      "device_fingerprint": {
        "score": 15,
        "weight": 0.15,
        "weighted_score": 2.25,
        "details": {
          "device_risk_score": 15,
          "fraud_signals": []
        }
      },
      "data_consistency": {
        "score": 10,
        "weight": 0.10,
        "weighted_score": 1.0,
        "details": {
          "name_match": true,
          "dob_match": true
        }
      }
    },
    "calculated_at": "2026-03-18T10:30:00Z"
  }
  ```

  ```json 200 Critical Risk theme={null}
  {
    "session_id": "ses_suspicious-uuid",
    "composite_score": 82,
    "risk_level": "critical",
    "components": {
      "document_authenticity": {
        "score": 70,
        "weight": 0.25,
        "weighted_score": 17.5,
        "details": {
          "mrz_valid": false,
          "tamper_detected": true,
          "document_expired": false
        }
      },
      "face_match": {
        "score": 60,
        "weight": 0.20,
        "weighted_score": 12.0,
        "details": {
          "similarity": 62.1
        }
      },
      "liveness": {
        "score": 80,
        "weight": 0.15,
        "weighted_score": 12.0,
        "details": {
          "liveness_score": 38.0,
          "liveness_mode": "passive"
        }
      },
      "aml_screening": {
        "score": 90,
        "weight": 0.15,
        "weighted_score": 13.5,
        "details": {
          "matches_found": 2
        }
      },
      "device_fingerprint": {
        "score": 87,
        "weight": 0.15,
        "weighted_score": 13.05,
        "details": {
          "device_risk_score": 87,
          "fraud_signals": ["bot", "webdriver"]
        }
      },
      "data_consistency": {
        "score": 40,
        "weight": 0.10,
        "weighted_score": 4.0,
        "details": {
          "name_match": false,
          "dob_match": true
        }
      }
    },
    "calculated_at": "2026-03-18T10:35:00Z"
  }
  ```
</ResponseExample>

## Response Fields

| Field                         | Type    | Description                            |
| ----------------------------- | ------- | -------------------------------------- |
| `session_id`                  | string  | The session ID                         |
| `composite_score`             | integer | Unified risk score (0-100)             |
| `risk_level`                  | string  | `low`, `medium`, `high`, or `critical` |
| `components`                  | object  | Breakdown of each scoring component    |
| `components.*.score`          | integer | Raw component score (0-100)            |
| `components.*.weight`         | number  | Weight applied to this component       |
| `components.*.weighted_score` | number  | Score multiplied by weight             |
| `components.*.details`        | object  | Component-specific details             |
| `calculated_at`               | string  | ISO 8601 timestamp                     |

## Using Risk Scores in Workflows

You can configure automatic actions based on risk levels in **Dashboard > Workflows > Risk Rules**:

| Rule            | Condition               | Action                        |
| --------------- | ----------------------- | ----------------------------- |
| Auto-approve    | `composite_score <= 25` | Approve session automatically |
| Flag for review | `composite_score > 50`  | Assign to review queue        |
| Block           | `composite_score > 75`  | Decline session automatically |

<Tip>
  Combine risk scoring with webhooks to build fully automated verification pipelines. Subscribe to `session.completed` and check the `risk_score` field in the payload.
</Tip>
