Skip to main content

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:

  1. Webhooks (Push): Real-time notifications when KYC state changes
  2. 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:

StrategyDescriptionBest For
Standard (CF_KYC)Users complete identity verification via Connect Financial's SDKMost integrations
External KYCYou handle verification with your own KYC providerClients 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:

EventWhen it firesWhat it means
CUSTOMER_KYC_STARTEDPOST /v1/compliance/kyc calledKYC process initiated
CUSTOMER_KYC_SDK_FLOW_REQUIREDSDK links generatedUser needs to complete identity verification
CUSTOMER_KYC_SDK_FLOW_COMPLETEDUser finishes SDKIdentity verification submitted
CUSTOMER_KYC_FINISHEDFinal outcome reachedKYC approved or denied (check status field)
CUSTOMER_KYC_RESTARTEDPOST /v1/compliance/kyc/:id/rerunKYC re-run, new onboarding created
CUSTOMER_KYC_SDK_EXPIREDSDK links expireLinks expired before user completed
CUSTOMER_KYC_ERRORVerification errorSystem 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

ActionWhat to do
START_KYCInitiate KYC
COMPLETE_SDK_FLOWUser must complete identity verification SDK
UPLOAD_DOCUMENTUpload required document via API
UPDATE_PROFILEUpdate customer profile data
RERUN_KYCRerun KYC
WAITNo user action needed - system processing (e.g., SDK done, docs uploaded, awaiting approval)
CONTACT_SUPPORTTerminal failure, verification error, or denied - requires support

Check Types

CheckDescriptionRequired
KYC_DATA_PRESENTCustomer has KYC data submittedAlways
KYC_STARTEDKYC process initiatedAlways
SDK_VERIFICATION_COMPLETEDIdentity verification SDK completedCF_KYC only*
KYC_STATUSOverall KYC approved/deniedAlways
REGISTRATION_ADDRESSRegistration address on fileAlways
TAX_COUNTRYTax country specifiedAlways
OCCUPATIONOccupation registeredAlways
DOC_SOURCE_OF_FUNDSSource of funds documentAlways
DOC_FATCAW9/W8BEN documentAlways
DOC_BIOMETRIC_REPORTBiometric verification reportExternal KYC only*
DOC_PROOF_OF_ADDRESSProof of address documentOnly 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

AspectStandard (CF_KYC)External KYC
Identity VerificationConnect Financial SDKYour KYC provider
SDK LinksProvidedNot provided
Approval TriggerSDK completion + documentsDocuments only

Key Differences

  1. When you call POST /v1/compliance/kyc, the response contains only onboarding data—no sdk links or QR codes.

  2. The SDK_VERIFICATION_COMPLETED check returns passed: true and required: false since your external provider handles verification.

  3. You must upload a BIOMETRIC_REPORT document from your KYC provider. This replaces the biometric data that would normally come from our SDK.

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

DocumentType CodeDescription
Biometric ReportBIOMETRIC_REPORTVerification report from your KYC provider (PDF)
Source of FundsSOURCE_OF_FUNDSDocument proving source of funds
Tax DocumentW9 or W8BENW9 for US persons, W8BEN for non-US
Proof of AddressPROOF_OF_ADDRESSOnly 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:

EventFired?Notes
CUSTOMER_KYC_STARTEDWhen POST /v1/compliance/kyc is called
CUSTOMER_KYC_SDK_FLOW_REQUIREDNever fired—no SDK required
CUSTOMER_KYC_SDK_FLOW_COMPLETEDNever fired—no SDK required
CUSTOMER_KYC_FINISHEDWhen 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.