> 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.

# KYC Onboarding

> Verify customer identities during account creation with document verification, biometrics, and screening.

Know Your Customer (KYC) onboarding is the process of verifying a new customer's
identity before granting them access to your product. Financial institutions,
fintechs, crypto exchanges, and lending platforms are required by regulation to
verify customer identities — but any platform handling sensitive data or
transactions benefits from KYC.

## What Verifa handles

A KYC onboarding workflow in Verifa typically includes these checks:

| Step | Check                 | What it does                                                          | How it's added                              |
| ---- | --------------------- | --------------------------------------------------------------------- | ------------------------------------------- |
| 1    | `document_ocr`        | Extracts name, DOB, address, and document number from the ID          | You add this to your workflow               |
| 2    | `face_match`          | Compares the selfie against the ID photo                              | You add this to your workflow               |
| 3    | `watchlist_screening` | Screens against OFAC, EU, UN, and UK sanctions                        | Runs automatically on every session         |
| 4    | `risk_assessment`     | Aggregates 150+ fraud signals into a risk score (0–100)               | Runs automatically on every session         |
| 5    | `identity_crossref`   | Compares user-submitted data against OCR-extracted data               | Runs automatically if you collect user info |
| 6    | `auto_approve`        | Routes to approved, rejected, or manual review based on prior results | You add this to your workflow               |

Steps 3–5 run automatically on every session — Verifa inserts them into your
workflow behind the scenes. You'll see them listed under "Runs automatically on
every session" on your workflow detail page.

For enhanced compliance, you can also add these optional checks to your workflow:

* **`aml_screening`** — Screens against 6,000+ global watchlists including PEP
  databases and adverse media (Professional plan and above)
* **`duplicate_detection`** — Catches repeat applicants using the same device,
  face, document, or contact details
* **`email_risk_enhanced`** / **`phone_risk_enhanced`** — Validates contact info
  for fraud signals

## Quick implementation

### 1. Create a session

Include an `external_ref` — this is your internal user ID and is used to
automatically create an identity record when the session completes.

#### cURL

```bash
curl -X POST https://api.withverifa.com/api/v1/sessions \
  -H "X-API-Key: vk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "external_ref": "user_abc123",
    "country": "US",
    "workflow_id": "wf_kyc_standard"
  }'
```

#### Python

```python
import requests

session = requests.post(
    "https://api.withverifa.com/api/v1/sessions",
    headers={"X-API-Key": "vk_live_your_key_here"},
    json={
        "external_ref": "user_abc123",
        "country": "US",
        "workflow_id": "wf_kyc_standard",
    },
).json()

# Redirect user to session["capture_url"]
```

#### JavaScript

```javascript
const session = await fetch('https://api.withverifa.com/api/v1/sessions', {
  method: 'POST',
  headers: {
    'X-API-Key': 'vk_live_your_key_here',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    external_ref: 'user_abc123',
    country: 'US',
    workflow_id: 'wf_kyc_standard',
  }),
}).then(r => r.json());

// Redirect user to session.capture_url
```

### 2. User completes verification

Send the user to `capture_url`. They will:

1. Give consent for identity verification
2. Select their document type (passport, driver's license, or national ID)
3. Photograph the front (and back, if applicable) of their ID
4. Take a selfie for biometric matching
5. Fill in any required user information fields (if configured in your workflow)

### 3. Handle the result

Listen for the `session.approved` or `session.declined` webhook, then fetch the
full result:

#### cURL

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

#### Python

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

#### JavaScript

```javascript
const result = await fetch(
  'https://api.withverifa.com/api/v1/results/session_abc123',
  { headers: { 'X-API-Key': 'vk_live_your_key_here' } }
).then(r => r.json());
```

```json
{
  "session_id": "session_abc123",
  "external_ref": "user_abc123",
  "status": "approved",
  "result": {
    "face_match_passed": true,
    "face_match_score": 0.94,
    "age_check_passed": true,
    "extracted_age": 28,
    "extracted_data": {
      "first_name": "Jane",
      "last_name": "Doe",
      "date_of_birth": "1997-06-15",
      "address": "123 Main St, San Francisco, CA 94102",
      "document_type": "drivers_license",
      "document_number": "D1234567",
      "document_expiration_date": "2028-06-15"
    }
  },
  "processing_mode": "workflow",
  "created_at": "2026-01-15T12:05:00Z"
}
```

> **Note**
>
> Extracted PII is encrypted at rest and subject to your organization's data
> retention policy. After the access window expires, `extracted_data` will be
> empty and `sensitive_data_expired` will be `true`.

### 4. Identity is created automatically

When a session completes, Verifa automatically creates (or updates) an
**identity record** linked to the `external_ref` you provided. This identity
stores the verified data and serves as the anchor for:

* Future re-verification sessions
* Continuous AML monitoring (if enabled)
* Duplicate detection across sessions

You can retrieve the identity at any time:

```bash
curl https://api.withverifa.com/api/v1/identities?external_ref=user_abc123 \
  -H "X-API-Key: vk_live_your_key_here"
```

> **Tip**
>
> Always pass an `external_ref` when creating sessions. This is what links
> sessions to identities and enables duplicate detection, re-verification, and
> monitoring. Without it, no identity record is created.

## Recommended workflow

For standard KYC onboarding, build a workflow with these steps:

```
Capture → Document Scan → Face Match → Auto-Approve
```

Watchlist screening, risk assessment, and identity cross-reference run
automatically — you don't need to add them.

For high-risk verticals (crypto, lending), add more checks:

```
Capture → Document Scan → Face Match → AML Screening
  → Duplicate Detection → Auto-Approve
```

See the [Creating a Workflow tutorial](/tutorials/creating-a-workflow) for a
step-by-step walkthrough of building a workflow in the dashboard.

### Risk-based routing

Use conditional nodes to route high-risk sessions to manual review:

```json
{
  "risk_gate": {
    "type": "conditional",
    "routes": [
      {
        "conditions": [
          { "field": "risk_assessment.risk_level", "op": "==", "value": "critical" }
        ],
        "target": "reject_terminal"
      },
      {
        "conditions": [
          { "field": "risk_assessment.risk_level", "op": "in", "value": ["high", "medium"] }
        ],
        "target": "review_terminal"
      },
      {
        "conditions": [],
        "target": "approve_terminal"
      }
    ]
  }
}
```

## Handling edge cases

### Document not accepted

If a user submits an unsupported document type, the `document_ocr` check fails
with a `requires_retry` status. The capture flow automatically prompts them to
try again (up to 4 retries).

### Needs manual review

Sessions routed to `needs_review` appear in the Cases dashboard. Assign
reviewers, add notes, and approve or reject with a full audit trail.

### Re-verification

For periodic KYC refresh (common in financial services), create a new session
with the same `external_ref`. Verifa automatically links it to the existing
identity:

```bash
curl -X POST https://api.withverifa.com/api/v1/sessions \
  -H "X-API-Key: vk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "external_ref": "user_abc123",
    "country": "US"
  }'
```

The new session's results will update the existing identity record when it
completes.

## Compliance mapping

| Requirement                  | Verifa capability                                                    |
| ---------------------------- | -------------------------------------------------------------------- |
| CDD (Customer Due Diligence) | `document_ocr` + `face_match` (in your workflow)                     |
| Sanctions screening          | `watchlist_screening` (runs automatically, OFAC/EU/UN/UK)            |
| PEP screening                | Add `aml_screening` to your workflow (Professional plan)             |
| Adverse media                | Add `aml_screening` to your workflow (Professional plan)             |
| Ongoing monitoring           | Enable continuous monitoring on `aml_screening`                      |
| Fraud detection              | `risk_assessment` runs automatically (150+ signals)                  |
| Duplicate prevention         | Add `duplicate_detection` to your workflow                           |
| Record keeping               | Session results + audit logs retained per your data retention policy |

## Related

* [Tutorial: Creating a Workflow](/tutorials/creating-a-workflow) — Build a workflow step by step
* [Quickstart](/getting-started/quickstart) — Create your first session in 5 minutes
* [Sessions](/core-concepts/sessions) — Full session lifecycle and API
* [Identities](/core-concepts/identities) — How identity records work
* [Screening & Reports](/core-concepts/screening-reports) — AML screening details
* [Cases](/core-concepts/cases) — Manual review workflow
* [Workflows](/core-concepts/workflows) — Customize the verification pipeline