This guide walks through integrating the KYC API Framework at a community financial institution. It is written for technical teams with standard software integration experience — no specialized fintech engineering background is required.
Before implementing this framework, document your existing process:
- Where does a customer currently initiate account opening? (branch, web, mobile)
- Which identity verification vendor do you currently use (if any)?
- How long does a typical KYC review currently take?
- What percentage of applications require manual review?
- What are your current abandonment rates?
These baseline metrics will let you measure the impact of the framework implementation.
Configure the Risk Scoring Module with thresholds appropriate for your institution and customer base. A starting template:
LOW RISK — Auto-approve path
Conditions: Existing customer relationship OR
Applying for low-value product (checking/savings) AND
Geography: domestic AND
No adverse signals from identity verification
MEDIUM RISK — Enhanced verification path
Conditions: New customer AND
No existing relationship AND
Product: standard retail
HIGH RISK — Manual review path
Conditions: Business account OR
High-value product (large credit line, wire services) OR
Geography: high-risk jurisdiction OR
Any adverse signal from sanctions screening
Your compliance and BSA officer should review and approve risk tier definitions before go-live.
The framework requires three external service integrations. Evaluate vendors against these criteria:
Identity Verification
- Supports real-time (synchronous) API response
- Returns confidence score, not just pass/fail
- Offers alternative verification methods for thin-file applicants
- SOC 2 Type II certified
- Examples: Socure, Jumio, Alloy, Persona (not endorsements)
Document Processing
- Supports government ID (driver's license, passport, state ID)
- Returns structured extracted fields (name, DOB, address, ID number)
- Offers real-time and asynchronous processing modes
- DPPA compliant for DMV data
- Examples: Mitek, Onfido, Amazon Textract (not endorsements)
Sanctions Screening
- Covers OFAC SDN, FinCEN 314(a), EU consolidated list at minimum
- Returns match results with match confidence scores
- Provides audit-ready screening records
- Real-time API available
- Examples: LexisNexis, Dow Jones, ComplyAdvantage (not endorsements)
The Workflow Engine exposes a single entry-point API that your onboarding UI calls to initiate a KYC check. Here is the request/response structure:
Initiate KYC Workflow
POST /api/v1/kyc/initiate
Request Body:
{
"applicant": {
"first_name": "string",
"last_name": "string",
"date_of_birth": "YYYY-MM-DD",
"ssn_last4": "string", // or full SSN depending on product
"address": {
"street": "string",
"city": "string",
"state": "string",
"zip": "string"
},
"email": "string",
"phone": "string"
},
"product_type": "CHECKING | SAVINGS | LOAN | BUSINESS",
"channel": "WEB | MOBILE | BRANCH",
"consent_provided": true,
"consent_timestamp": "ISO8601 datetime"
}
Response:
{
"kyc_id": "uuid",
"status": "IN_PROGRESS",
"risk_tier": "LOW | MEDIUM | HIGH",
"estimated_completion": "ISO8601 datetime",
"verification_steps": ["IDENTITY", "DOCUMENT", "SANCTIONS"],
"webhook_url": "string (your callback endpoint)"
}
Check KYC Status
GET /api/v1/kyc/{kyc_id}/status
Response:
{
"kyc_id": "uuid",
"status": "IN_PROGRESS | APPROVED | DENIED | PENDING_REVIEW | INCOMPLETE",
"risk_tier": "LOW | MEDIUM | HIGH",
"completed_steps": ["IDENTITY", "SANCTIONS"],
"pending_steps": ["DOCUMENT"],
"decision_summary": {
"identity_verified": true,
"document_verified": null,
"sanctions_cleared": true,
"overall_confidence": 0.87
},
"escalation_reason": null,
"updated_at": "ISO8601 datetime"
}
The Workflow Engine should call all three verification services simultaneously on workflow initiation. Pseudocode:
function executeVerification(applicant, riskTier):
// Launch all three in parallel
identityJob = async: callIdentityService(applicant)
documentJob = async: callDocumentService(applicant) // if riskTier >= MEDIUM
sanctionsJob = async: callSanctionsService(applicant)
// Wait for all to complete (or timeout)
results = awaitAll([identityJob, documentJob, sanctionsJob], timeout=30s)
// Route to decision
return decisionRouter.evaluate(results, riskTier)
Important: Set individual service timeouts (recommended: 10s per service) and an overall workflow timeout (recommended: 30s). Services that time out should escalate to the manual review queue rather than returning an error to the customer.
Every event in the KYC workflow must be logged. Minimum required fields:
{
"event_id": "uuid",
"kyc_id": "uuid",
"event_type": "INITIATED | STEP_COMPLETED | DECISION_MADE | ESCALATED | REVIEWED",
"timestamp": "ISO8601 datetime",
"actor": "SYSTEM | [examiner_id]",
"step": "IDENTITY | DOCUMENT | SANCTIONS | WORKFLOW",
"result": "PASS | FAIL | TIMEOUT | ESCALATED",
"vendor_reference_id": "string",
"confidence_score": "float",
"decision_rationale": "string"
}
The audit log must be append-only and retained per your institution's BSA record retention policy (minimum 5 years for most KYC records).
This phase is optional but highly recommended for institutions serving underbanked populations.
When a LOW or MEDIUM risk applicant cannot complete standard identity verification (e.g., limited credit history, non-standard ID), offer these alternatives before routing to manual review:
Consumer-Permissioned Bank Data (CFPB Section 1033) If the applicant has an account at another institution, they can permission access to their transaction history via Section 1033 API. This provides an alternative signal for identity confirmation without requiring credit bureau data.
Alternative verification trigger:
IF identity_confidence_score < threshold AND risk_tier IN [LOW, MEDIUM]:
OFFER: "Connect your existing bank account to verify your identity"
REDIRECT: Section 1033 consent flow
ON SUCCESS: re-run identity scoring with transaction history signal
Utility and Telecom Verification Utility account records or mobile carrier records can confirm name and address for applicants without standard documentation.
Employer Verification For loan products, employer payroll data (via Argyle, Pinwheel, or similar payroll API) can verify income and identity simultaneously.
Every alternative verification path requires explicit, specific customer consent. Before calling any third-party data source, record consent in the Consent Registry:
POST /api/v1/consent/record
{
"kyc_id": "uuid",
"applicant_id": "uuid",
"data_source": "OPEN_BANKING | UTILITY | EMPLOYER_PAYROLL",
"purpose": "KYC_IDENTITY_VERIFICATION",
"consent_given": true,
"consent_timestamp": "ISO8601 datetime",
"consent_method": "DIGITAL_SIGNATURE | CHECKBOX_WITH_IP_LOG",
"ip_address": "string"
}
Before going live, test the following scenarios:
- Low-risk applicant with clean identity verification → should auto-approve
- Low-risk applicant with thin credit file → should trigger progressive verification
- Medium-risk applicant with document upload → should complete within 15 minutes
- High-risk applicant → should route to manual review queue
- Applicant with sanctions match → should deny with logged rationale
- Service timeout scenario → should escalate gracefully, not error
After go-live, track these metrics weekly for the first 90 days:
- Auto-approval rate by risk tier (target: 70%+ of low-risk applicants)
- Average completion time by risk tier
- Manual review queue volume (flag if > 15% of all applications)
- Abandonment rate at each step (flag if > 20% at any single step)
- False positive rate on sanctions screening (flag and tune thresholds if > 5%)
If you are using AI-assisted risk scoring or document verification, also track:
- Decision consistency by applicant demographic (required under NIST AI RMF fairness monitoring)
- Model confidence score distribution over time (drift detection)
- Human override rate on AI-assisted decisions
If you encounter implementation questions not covered in this guide, open an issue in this repository. Questions from practitioners at community banks, credit unions, and CDFIs are particularly welcome — your feedback improves this framework for the institutions that need it most.