KYC Compliance Flow
This guide explains how to integrate the KYC compliance system using both webhooks (push) and the Compliance Status API (pull).
Overview
The KYC system provides two complementary mechanisms:
- Webhooks (Push): Real-time notifications when KYC state changes
- Compliance Status API (Pull): On-demand status with actionable guidance
Use webhooks for real-time updates; use the API to get current state and determine next steps.
Integration Paths
Connect Financial supports two KYC integration strategies:
| Strategy | Description | Best For |
|---|---|---|
| Standard (CF_KYC) | Users complete identity verification via Connect Financial's SDK | Most integrations |
| External KYC | You handle verification with your own KYC provider | Clients with existing KYC infrastructure |
This guide covers the standard flow first. See External KYC Integration if you manage your own KYC process.
Webhook Events
Subscribe to these events via the Webhook API:
| Event | When it fires | What it means |
|---|---|---|
CUSTOMER_KYC_STARTED | POST /v1/compliance/kyc called | KYC process initiated |
CUSTOMER_KYC_SDK_FLOW_REQUIRED | SDK links generated | User needs to complete identity verification |
CUSTOMER_KYC_SDK_FLOW_COMPLETED | User finishes SDK | Identity verification submitted |
CUSTOMER_KYC_FINISHED | Final outcome reached | KYC approved or denied (check status field) |
CUSTOMER_KYC_RESTARTED | POST /v1/compliance/kyc/:id/rerun | KYC re-run, new onboarding created |
CUSTOMER_KYC_SDK_EXPIRED | SDK links expire | Links expired before user completed |
CUSTOMER_KYC_ERROR | Verification error | System error during verification |
Webhook Payload
{
"eventType": "CUSTOMER_KYC_SDK_FLOW_COMPLETED",
"data": {
"customerId": "uuid",
"status": "APPROVED",
"onboardingId": "uuid"
}
}
For CUSTOMER_KYC_RESTARTED, also includes previousOnboardingId.
Compliance Status API
Endpoint: GET /v1/compliance/status/:customerId
Returns actionable compliance data without requiring message parsing.
Response Structure
{
"isCompliant": false,
"onboardingStatus": "PROCESSING",
"nextAction": "UPLOAD_DOCUMENT",
"checks": [
{
"type": "KYC_STATUS",
"passed": false,
"required": true,
"suggestedAction": "UPLOAD_DOCUMENT"
},
{
"type": "DOC_SOURCE_OF_FUNDS",
"passed": false,
"required": true,
"suggestedAction": "UPLOAD_DOCUMENT"
},
...
],
"summary": {
"passed": 8,
"failed": 2,
"requiredFailed": ["KYC_STATUS", "DOC_SOURCE_OF_FUNDS"]
}
}
Suggested Action Values
| Action | What to do |
|---|---|
START_KYC | Initiate KYC |
COMPLETE_SDK_FLOW | User must complete identity verification SDK |
UPLOAD_DOCUMENT | Upload required document via API |
UPDATE_PROFILE | Update customer profile data |
RERUN_KYC | Rerun KYC |
WAIT | No user action needed - system processing (e.g., SDK done, docs uploaded, awaiting approval) |
CONTACT_SUPPORT | Terminal failure, verification error, or denied - requires support |
Check Types
| Check | Description | Required |
|---|---|---|
KYC_DATA_PRESENT | Customer has KYC data submitted | Always |
KYC_STARTED | KYC process initiated | Always |
SDK_VERIFICATION_COMPLETED | Identity verification SDK completed | CF_KYC only* |
KYC_STATUS | Overall KYC approved/denied | Always |
REGISTRATION_ADDRESS | Registration address on file | Always |
TAX_COUNTRY | Tax country specified | Always |
OCCUPATION | Occupation registered | Always |
DOC_SOURCE_OF_FUNDS | Source of funds document | Always |
DOC_FATCA | W9/W8BEN document | Always |
DOC_BIOMETRIC_REPORT | Biometric verification report | External KYC only* |
DOC_PROOF_OF_ADDRESS | Proof of address document | Only when no IP address |
*See External KYC Integration for details on strategy-dependent checks.
Complete Integration Flow (Standard)
┌─────────────────────────────────────────────────────────────────────────────┐
│ PHASE 1a: Customer Creation (without KYC data) │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Client API Webhook │
│ │ │ │ │
│ │──POST /v1/customers──────────▶│ │ │
│ │◀──────────────────────────────│ │ │
│ │◀────────────────────────────────────────────CUSTOMER_CREATED─│ │
│ │ │ │ │
│ │──GET /compliance/status──────▶│ │ │
│ │◀──────────────────────────────│ │ │
│ │ KYC_DATA_PRESENT: false │ │ │
│ │ nextAction: UPDATE_PROFILE │ │ │
│ │ │ │ │
│ │──PATCH /v1/customers/:id─────▶│ (add KYC data) │ │
│ │◀────────────────────────────────────────────CUSTOMER_UPDATED─│ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ PHASE 1b: Customer Creation (with KYC data) │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Client API Webhook │
│ │ │ │ │
│ │──POST /v1/customers──────────▶│ │ │
│ │◀──────────────────────────────│ │ │
│ │◀────────────────────────────────────────────CUSTOMER_CREATED─│ │
│ │ │ │ │
│ │──GET /compliance/status──────▶│ │ │
│ │◀──────────────────────────────│ │ │
│ │ KYC_DATA_PRESENT: true │ │ │
│ │
└─────────────────────────────── ──────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────────────────────────────────┐
│ PHASE 2: KYC Initiation │
├────────────────────────────────────────────────────────────────────────────────────────────┤
│ │
│ Client API Webhook │
│ │ │ │ │
│ │──GET /compliance/status──────▶│ │ │
│ │◀──────────────────────────────│ │ │
│ │ KYC_DATA_PRESENT: true │ │ │
│ │ KYC_STARTED: false │ │ │
│ │ nextAction: START_KYC │ │ │
│ │ │ │ │
│ │──POST /v1/compliance/kyc─────▶│ │ │
│ │◀──────────────────────────────│ │ │
│ │ { sdk: { link, qrCode } } │ │ │
│ │◀───────────────────────────────────────────────────────CUSTOMER_KYC_STARTED─│ │
│ │◀─────────────────────────────────────────────CUSTOMER_KYC_SDK_FLOW_REQUIRED─│ │
│ │ │ │ │
│ │ Display SDK link/QR to user │ │ │
│ │
└────────────────────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ PHASE 3: User Completes SDK │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Client API Webhook │
│ │ │ │ │
│ │ (User completes SDK flow) │ │ │
│ │ │ │ │
│ │◀──────────────────────────────────CUSTOMER_KYC_SDK_FLOW_DONE─│ │
│ │ │ │ │
│ │──GET /compliance/status──────▶│ │ │
│ │◀───────────────────────────── │ │ │
│ │ SDK_VERIFICATION_COMPLETED: ✓│ │ │
│ │ KYC_STATUS: false │ │ │
│ │ DOC_SOURCE_OF_FUNDS: false │ │ │
│ │ DOC_FATCA: false │ │ │
│ │ nextAction: UPLOAD_DOCUMENT │ │ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ PHASE 4: Document Upload │
├────────────────────────────────────────────── ───────────────────────────────┤
│ │
│ Client API Webhook │
│ │ │ │ │
│ │──POST /compliance/upload-doc─▶│ (Source of Funds) │ │
│ │◀──────────────────────────────│ │ │
│ │ │ │ │
│ │──POST /compliance/upload-doc─▶│ (W9 or W8BEN) │ │
│ │◀──────────────────────────────│ │ │
│ │ │ │ │
│ │──GET /compliance/status──────▶│ │ │
│ │◀──────────────────────────────│ │ │
│ │ All DOC_* checks: ✓ │ │ │
│ │ KYC_STATUS: false │ │ │
│ │ nextAction: WAIT │ (processing, docs present) │ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ PHASE 5: KYC Approved │
├────────── ───────────────────────────────────────────────────────────────────┤
│ │
│ Client API Webhook │
│ │ │ │ │
│ │◀─────────────────────────────────CUSTOMER_KYC_FINISHED───────│ │
│ │ │ (status: APPROVED) │ │
│ │ │ │ │
│ │──GET /compliance/status──────▶│ │ │
│ │◀──────────────────────────────│ │ │
│ │ isCompliant: true │ │ │
│ │ nextAction: null │ │ │
│ │ │ │ │
│ │ Customer ready for │ │ │
│ │ virtual account creation │ │ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
External KYC Integration
For clients who perform identity verification through their own KYC provider, Connect Financial offers an External KYC integration path. This allows you to leverage your existing KYC infrastructure while still meeting Connect Financial's compliance requirements.
How External KYC Differs
| Aspect | Standard (CF_KYC) | External KYC |
|---|---|---|
| Identity Verification | Connect Financial SDK | Your KYC provider |
| SDK Links | Provided | Not provided |
| Approval Trigger | SDK completion + documents | Documents only |
Key Differences
-
When you call
POST /v1/compliance/kyc, the response contains onlyonboardingdata—nosdklinks or QR codes. -
The
SDK_VERIFICATION_COMPLETEDcheck returnspassed: trueandrequired: falsesince your external provider handles verification. -
You must upload a
BIOMETRIC_REPORTdocument from your KYC provider. This replaces the biometric data that would normally come from our SDK. -
Once all required documents are uploaded and occupation is set, the customer is automatically approved—no waiting for SDK completion.
External KYC Integration Flow
┌─────────────────────────────────────────────────────────────────────────────┐
│ PHASE 1: Customer Creation (with KYC data) │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Client API Webhook │
│ │ │ │ │
│ │──POST /v1/customers──────────▶│ (include kycData) │ │
│ │◀──────────────────────────────│ │ │
│ │◀────────────────────────────────────────────CUSTOMER_CREATED─│ │
│ │ │ │ │
│ │──GET /compliance/status──────▶│ │ │
│ │◀──────────────────────────────│ │ │
│ │ KYC_DATA_PRESENT: true │ │ │
│ │ nextAction: START_KYC │ │ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ PHASE 2: KYC Initiation (No SDK) │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Client API Webhook │
│ │ │ │ │
│ │──POST /v1/compliance/kyc─────▶│ │ │
│ │◀──────────────────────────────│ │ │
│ │ { onboarding: {...} } │ ← No SDK links! │ │
│ │◀───────────────────────────────────────────CUSTOMER_KYC_STARTED─│ │
│ │ │ │ │
│ │ (No CUSTOMER_KYC_SDK_FLOW_REQUIRED webhook) │ │
│ │ │ │ │
│ │──GET /compliance/status──────▶│ │ │
│ │◀──────────────────────────────│ │ │
│ │ SDK_VERIFICATION_COMPLETED: │ │ │
│ │ passed: true │ ← Auto-passes for │ │
│ │ required: false │ External KYC │ │
│ │ DOC_BIOMETRIC_REPORT: │ │ │
│ │ passed: false │ │ │
│ │ required: true │ ← Required for External KYC │ │
│ │ nextAction: UPLOAD_DOCUMENT │ │ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ PHASE 3: Document Upload (including Biometric Report) │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Client API Webhook │
│ │ │ │ │
│ │ (Run your external KYC verification) │ │
│ │ │ │ │
│ │──POST /compliance/upload-doc─▶│ (Biometric Report from │ │
│ │◀──────────────────────────────│ your KYC provider) │ │
│ │ │ │ │
│ │──POST /compliance/upload-doc─▶│ (Source of Funds) │ │
│ │◀──────────────────────────────│ │ │
│ │ │ │ │
│ │──POST /compliance/upload-doc─▶│ (W9 or W8BEN) │ │
│ │◀──────────────────────────────│ │ │
│ │ │ │ │
│ │──GET /compliance/status──────▶│ │ │
│ │◀──────────────────────────────│ │ │
│ │ All DOC_* checks: ✓ │ │ │
│ │ KYC_STATUS: false │ │ │
│ │ nextAction: WAIT │ │ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ PHASE 4: Automatic Approval │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Client API Webhook │
│ │ │ │ │
│ │ (System auto-approves when │ │ │
│ │ all docs present + occupation set) │ │
│ │ │ │ │
│ │◀──────────────────────────────────────CUSTOMER_KYC_FINISHED──│ │
│ │ │ (status: APPROVED) │ │
│ │ │ │ │
│ │──GET /compliance/status──────▶│ │ │
│ │◀──────────────────────────────│ │ │
│ │ isCompliant: true │ │ │
│ │ onboardingStatus: APPROVED │ │ │
│ │ nextAction: null │ │ │
│ │ │ │ │
│ │ Customer ready for │ │ │
│ │ virtual account creation │ │ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Required Documents for External KYC
| Document | Type Code | Description |
|---|---|---|
| Biometric Report | BIOMETRIC_REPORT | Verification report from your KYC provider (PDF) |
| Source of Funds | SOURCE_OF_FUNDS | Document proving source of funds |
| Tax Document | W9 or W8BEN | W9 for US persons, W8BEN for non-US |
| Proof of Address | PROOF_OF_ADDRESS | Only if customer has no IP address on file |
Example: Compliance Status Response (External KYC)
{
"isCompliant": false,
"onboardingStatus": "PROCESSING",
"nextAction": "UPLOAD_DOCUMENT",
"checks": [
{
"type": "KYC_DATA_PRESENT",
"passed": true,
"required": true
},
{
"type": "KYC_STARTED",
"passed": true,
"required": true
},
{
"type": "SDK_VERIFICATION_COMPLETED",
"passed": true,
"required": false
},
{
"type": "KYC_STATUS",
"passed": false,
"required": true,
"suggestedAction": "UPLOAD_DOCUMENT"
},
{
"type": "DOC_BIOMETRIC_REPORT",
"passed": false,
"required": true,
"suggestedAction": "UPLOAD_DOCUMENT"
},
{
"type": "DOC_SOURCE_OF_FUNDS",
"passed": false,
"required": true,
"suggestedAction": "UPLOAD_DOCUMENT"
},
{
"type": "DOC_FATCA",
"passed": false,
"required": true,
"suggestedAction": "UPLOAD_DOCUMENT"
}
],
"summary": {
"passed": 6,
"failed": 4,
"requiredFailed": ["KYC_STATUS", "DOC_BIOMETRIC_REPORT", "DOC_SOURCE_OF_FUNDS", "DOC_FATCA"]
}
}
Webhook Events for External KYC
External KYC uses a subset of the standard webhook events:
| Event | Fired? | Notes |
|---|---|---|
CUSTOMER_KYC_STARTED | ✓ | When POST /v1/compliance/kyc is called |
CUSTOMER_KYC_SDK_FLOW_REQUIRED | ✗ | Never fired—no SDK required |
CUSTOMER_KYC_SDK_FLOW_COMPLETED | ✗ | Never fired—no SDK required |
CUSTOMER_KYC_FINISHED | ✓ | When all requirements met and approved |
Getting External KYC Access
Contact your Connect Financial account representative to configure your integration for External KYC.
Edge Case Flows
SDK Expired
Webhook: CUSTOMER_KYC_SDK_EXPIRED
│
▼
GET /compliance/status
│
├─ SDK_VERIFICATION_COMPLETED: false
└─ nextAction: RERUN_KYC
│
▼
POST /compliance/kyc/:onboardingId/rerun
│
▼
Webhook: CUSTOMER_KYC_RESTARTED
│
▼
(Flow continues from Phase 2)
KYC Denied
Webhook: CUSTOMER_KYC_FINISHED (status: DENIED_COMPLIANCE)
│
▼
GET /compliance/status
│
├─ onboardingStatus: DENIED_COMPLIANCE
├─ KYC_STATUS: false
└─ nextAction: CONTACT_SUPPORT
│
▼
Contact Connect Financial support
Verification Error
Webhook: CUSTOMER_KYC_ERROR
│
▼
GET /compliance/status
│
├─ SDK_VERIFICATION_COMPLETED: false
└─ nextAction: CONTACT_SUPPORT
│
▼
Contact Connect Financial support
Under Review
When identity verification requires manual review by our compliance team, the system enters a "pending review" state.
Webhook: CUSTOMER_KYC_SDK_FLOW_COMPLETED
│
▼
GET /compliance/status
│
├─ SDK_VERIFICATION_COMPLETED: false (pending review, not yet completed)
├─ KYC_STATUS: false (awaiting decision)
└─ nextAction: WAIT
│
▼
Wait for review completion:
- Poll /compliance/status periodically
- Or await CUSTOMER_KYC_FINISHED webhook
│
▼
Review outcome:
- APPROVED → CUSTOMER_KYC_FINISHED (status: APPROVED)
- DENIED → CUSTOMER_KYC_FINISHED (status: DENIED_COMPLIANCE)
Important: During manual review, SDK_VERIFICATION_COMPLETED remains false because the verification is not yet complete as it's awaiting human decision. The nextAction: WAIT indicates no user action is required.