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.


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

CheckDescription
KYC_DATA_PRESENTCustomer has KYC data submitted
KYC_STARTEDKYC process initiated
SDK_VERIFICATION_COMPLETEDIdentity verification SDK completed
KYC_STATUSOverall KYC approved/denied
REGISTRATION_ADDRESSRegistration address on file
TAX_COUNTRYTax country specified
OCCUPATIONOccupation registered
DOC_SOURCE_OF_FUNDSSource of funds document
DOC_FATCAW9/W8BEN document
DOC_BIOMETRIC_REPORTBiometric verification report (only required for clients that run their own KYC)
DOC_PROOF_OF_ADDRESSProof of address document (only required when no IP Address is set for said customer)

Complete Integration Flow

┌─────────────────────────────────────────────────────────────────────────────┐
│ 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 │ │ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

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.