> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.withverifa.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.withverifa.com/_mcp/server.

# Fraud Prevention

> Detect and block identity fraud with 150+ signals, duplicate detection, and custom blocklists.

Identity fraud costs businesses billions annually. Verifa collects 150+ fraud
signals during every verification — behavioral analysis, device fingerprinting,
document forensics, and network intelligence — and aggregates them into a risk
score that lets you auto-approve legitimate users while catching fraudsters.

## How Verifa detects fraud

Fraud detection runs automatically on every session through checks that Verifa
inserts into your workflow behind the scenes:

* **Risk assessment** — Aggregates 150+ signals into a composite risk score (0–100).
  Runs on every session automatically.
* **Watchlist screening** — Screens against OFAC, EU, UN, and UK sanctions lists.
  Runs on every session automatically.
* **Identity cross-reference** — Compares user-submitted data against
  OCR-extracted data. Runs automatically if your workflow collects user info.

You don't need to add these to your workflow — they're always there.

For additional fraud protection, you can add these checks to your workflow:

* **`duplicate_detection`** — Catches repeat applicants across sessions
* **`check_against_list`** — Matches against your custom blocklists

## Signal categories

Verifa collects signals across six categories:

| Category               | Examples                                                          | Signals |
| ---------------------- | ----------------------------------------------------------------- | ------- |
| **Behavioral**         | Completion speed, hesitation, copy-paste, bot-like mouse movement | 9       |
| **Device**             | Bot detection, virtual cameras, VM detection, devtools            | 8       |
| **Network**            | VPN/proxy/Tor, IP velocity, impossible travel, datacenter IPs     | 13      |
| **Document forensics** | EXIF editing, screen photos, MRZ tampering, barcode mismatch      | 17      |
| **Identity graph**     | Duplicate device, email, phone, document, face                    | 7       |
| **Integrity**          | Payload tampering, checksum mismatches, contradictions            | 5       |

See [Fraud Signals](/best-practices/fraud-signals) for the complete list with risk weights.

## Risk scoring

All triggered signals feed into a composite risk score:

| Risk level   | Score  | Recommended action                    |
| ------------ | ------ | ------------------------------------- |
| **Low**      | 0–20   | Auto-approve                          |
| **Medium**   | 21–50  | Proceed with caution                  |
| **High**     | 51–80  | Manual review or step-up verification |
| **Critical** | 81–100 | Auto-reject                           |

### View risk signals for a session

#### cURL

```bash
curl https://api.withverifa.com/api/v1/sessions/session_abc123/risk \
  -H "X-API-Key: vk_live_your_key_here"
```

#### Python

```python
import requests

risk = requests.get(
    "https://api.withverifa.com/api/v1/sessions/session_abc123/risk",
    headers={"X-API-Key": "vk_live_your_key_here"},
).json()

print(f"Risk: {risk['risk_level']} ({risk['risk_score']})")
for signal in risk["triggered_signals"]:
    print(f"  - {signal['signal']} (weight: {signal['weight']})")
```

```json
{
  "risk_score": 65,
  "risk_level": "high",
  "triggered_signals": [
    { "signal": "virtual_camera", "weight": 50, "action": "block" },
    { "signal": "front_exif_edited", "weight": 25, "action": "flag" },
    { "signal": "vpn_detected", "weight": 25, "action": "flag" }
  ],
  "triggered_count": 3,
  "hard_blocked": true
}
```

## Duplicate detection

The `duplicate_detection` check finds repeat offenders by comparing hashed
identity attributes across all previous sessions:

* Device fingerprint
* Email address
* Phone number
* Document number
* Face embedding (biometric similarity)
* Name + DOB combination

Add it to your workflow in the dashboard to catch users attempting multiple
verifications. When a duplicate is detected, the session routes to manual review.

## Custom blocklists

Create lists of known bad actors and match incoming sessions against them. Add
the `check_against_list` check to your workflow to enable matching.

```bash
# Create a blocklist
curl -X POST https://api.withverifa.com/api/v1/lists \
  -H "X-API-Key: vk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Known Fraudsters",
    "type": "block",
    "match_fields": ["email", "phone", "document_number", "device_fingerprint"]
  }'

# Add an entry
curl -X POST https://api.withverifa.com/api/v1/lists/list_abc123/entries \
  -H "X-API-Key: vk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "fraudster@example.com",
    "phone": "+15551234567",
    "reason": "Chargebacks on 3 accounts"
  }'
```

## Workflow example: fraud-aware onboarding

This workflow adds duplicate detection and list checks on top of standard
identity verification:

```
Capture → Document Scan → Face Match → Duplicate Detection
  → List Check → Auto-Approve
```

Watchlist screening, risk assessment, and identity cross-reference run
automatically on top of whatever you configure. You can use conditional nodes in
the workflow builder to route sessions based on the risk score:

* **Low risk** — Auto-approve
* **Medium/high risk** — Route to manual review
* **Critical risk** — Auto-reject

See the [Creating a Workflow tutorial](/tutorials/creating-a-workflow) for how
to build this in the dashboard.

## Tuning signal sensitivity

Each signal can be configured with one of three actions per organization:

| Action           | Behavior                                       |
| ---------------- | ---------------------------------------------- |
| `block`          | Counts in risk score + eligible for hard block |
| `flag` (default) | Counts in risk score                           |
| `ignore`         | Excluded from risk score entirely              |

For example, if your users commonly use VPNs, set `vpn_detected` to `ignore`.
If you want zero tolerance for virtual cameras, set `virtual_camera` to `block`.

## Hard blocks

Certain signals can trigger an immediate block regardless of the overall risk
score:

* `bot_detected` — Headless browser or WebDriver
* `virtual_camera` — OBS, ManyCam, or similar
* `camera_injection_detected` — Fake video injection on mobile
* `integrity_checksum_mismatch` — Tampered signal payload

Configure which signals trigger hard blocks in your organization settings.

## Related

* [Fraud Signals](/best-practices/fraud-signals) — Complete signal reference with risk weights
* [Verifications & Checks](/core-concepts/verifications-checks) — `risk_assessment`,
  `duplicate_detection`, and `check_against_list`
* [Lists](/core-concepts/lists) — Create and manage custom blocklists
* [Cases](/core-concepts/cases) — Review flagged sessions
* [Workflows](/core-concepts/workflows) — Build risk-aware verification pipelines
* [Tutorial: Creating a Workflow](/tutorials/creating-a-workflow) — Step-by-step workflow guide