KYC Onboarding
KYC onboarding is the regulated identity-verification flow every fintech runs before a user can transact. It collects identity documents, runs sanctions and PEP screening, and produces a verified-customer record that downstream systems can trust.
What KYC onboarding is
KYC — Know Your Customer — is the regulated process of verifying a user’s identity before allowing them to transact on a financial platform. KYC onboarding is the user-facing flow that collects the inputs the platform needs to satisfy that verification: a government-issued ID, a selfie or liveness check, address documents, and screening lookups against sanctions lists, PEP (politically-exposed persons) lists, and adverse-media indices.
The output is a verified-customer record with a tier (basic, full, enhanced) and a risk score. Downstream systems — payments, payouts, lending, savings — read the tier and the score and decide what the user is allowed to do.
What a complete KYC flow looks like
A production KYC onboarding flow has six phases:
- Personal information capture. Name, date of birth, address, country, government identifier (SSN, PAN, NIN, or local equivalent).
- Document upload. Photo of a government-issued ID, sometimes a proof-of-address. Captured via webcam or file upload, validated for legibility and tamper signs.
- Liveness check. A short selfie video or interactive prompts to verify the user is a real person and matches the ID.
- AML screening. Asynchronous lookups against sanctions, PEP, and adverse-media lists. Hits return for manual review.
- Risk scoring. A composite score combining geography, document quality, screening results, and behavioral signals.
- Tier assignment + persistence. Store the verified record and the tier the user is approved for, with retention policies the regulator requires.
Vendors like Onfido, Persona, Stripe Identity, Sumsub, and Veriff handle phases 2–4. Engineers integrate them through webhooks and decision rules — a fintech development team typically owns the orchestration layer that ties the vendor flow to the platform’s internal customer model.
KYC versus KYB
KYB onboarding is the business-equivalent flow, run on companies rather than individuals. It collects incorporation documents, beneficial-ownership records, and tax IDs, and runs equivalent screening. Most fintech platforms run KYC on individual users and KYB on connected business entities, sharing identity vendor infrastructure.
Designing for conversion and compliance
The design tension every KYC flow lives with is between strictness (regulator wants more checks) and conversion (users abandon long forms). Production flows resolve this with progressive verification: collect just enough at signup to allow basic actions, then unlock higher tiers when the user wants higher limits. This pattern keeps activation rates high without compromising the regulator-facing record.
Other production decisions:
- Run AML screening after identity verification, not before. Screening on bad data wastes manual-review time.
- Cache document upload state so retries do not start from scratch.
- Surface clear error states for liveness-check failures — most are device-related, not fraud.
- Persist every external screening response with a timestamp, so audits can reconstruct what was known when.
Code-shape example
A minimal KYC orchestration state machine:
type KycState =
| "personal_info"
| "document_upload"
| "liveness"
| "screening"
| "manual_review"
| "approved_tier_1"
| "approved_tier_2"
| "rejected";
interface KycCustomer {
id: string;
state: KycState;
tier: 0 | 1 | 2;
vendorRef?: string; // Onfido check id, Persona inquiry id, etc.
riskScore?: number;
amlHits?: ScreeningHit[];
history: { state: KycState; at: string }[];
}
// Webhook handler when the vendor finishes liveness + document checks.
export async function onVendorComplete(
customerId: string,
vendorResult: VendorResult,
): Promise<void> {
const c = await db.kyc.find(customerId);
if (vendorResult.outcome !== "clear") {
return advance(c, "rejected", { reason: vendorResult.reason });
}
// Kick off AML screening only after identity is clear.
const screening = await aml.screen({
name: c.fullName,
dob: c.dateOfBirth,
country: c.country,
});
if (screening.hits.length > 0) {
return advance(c, "manual_review", { amlHits: screening.hits });
}
return advance(c, "approved_tier_1", { riskScore: screening.score });
}
Each phase advances by writing a new record into an append-only kyc_history table. Tier transitions are policy-driven, not vendor-driven.
How we implement it at Dashhold
Every KYC build we ship follows the same patterns:
- Vendor-as-driver, not vendor-as-platform. The orchestration layer is ours; the vendor handles document capture and screening. Swapping vendors later is a config change, not a rewrite.
- Webhook idempotency on every callback. Vendors retry. The
Idempotency-Keyis the vendor’s event id, persisted with the result. - Tier policy as data, not code. A
tier_policiestable maps(country, product, risk_score)→ tier. Compliance can update the policy without an engineering deploy. - Manual-review queue with structured reason codes. Every rejection or hold writes a reason code. Auditors get a clean filter; ops gets a triage view; analytics gets a measurable funnel.
- Encrypted document storage with separate key hierarchy. PII documents live in a separate KMS-protected bucket. Application code never reads them; only the manual-review tool does, and every read is logged.
This shape passes the design tests every regulator runs: who saw the data, when, why, and where is the audit trail. We have shipped it in production at neobanks, payment platforms, and lending products with no major findings during regulator reviews.
Common pitfalls
- Treating KYC as a one-time event. Re-screening at intervals (monthly, quarterly) is required by most regulators. Build the re-screening loop on day one or it ships months late.
- Mixing PII into the main application database. Document images, full ID numbers, and selfie videos belong in a separate, encrypted store. Mixing them in the main DB is a discovery risk during incidents.
- Hard-coding tier rules in application code. Compliance teams need to change them. Move to a policy table with a small DSL or a structured JSON config.
- Ignoring vendor outage handling. When Onfido has an outage, KYC stops. A documented degraded-mode (e.g., fall back to a secondary vendor, or accept manual review SLAs) prevents revenue loss during the inevitable outage.
- Saving raw document images forever. Retention is regulator-mandated, but it is also bounded. Store for the required period, then automate deletion. Forever-storage is a breach risk.
- Missing the abandonment funnel. Most KYC failures are device or UX issues, not fraud. Instrument every step. Most flows discover that
liveness_checkis the abandonment cliff and a different vendor’s SDK fixes it.
Where KYC sits in a fintech platform
KYC onboarding is the gateway every payment, lending, or banking payment platform runs before letting a user move money. Production teams treat it as a first-class part of the platform — not a vendor wrapper — because the integrations, the policies, and the manual-review workflows are where the platform earns its compliance posture.
See also
- KYB onboarding — the business-equivalent verification flow
- AML screening — the sanctions and PEP checks run inside KYC
- Payment platform — the broader system KYC gates