Verification

KYC modules

The module catalog for ThirdFactor Verify — what each module does, where it runs, and how to pick the right set for your risk tier.

Obsidian ships ThirdFactor Verify, a built-in, standards-based KYC engine: document verification, passive / colour-flash / 3D-action / gesture liveness, 1:1 face match, AML screening, proof of address, document AI, NFC chip reads, and agent video calls. No external verification SDK and no third-party verification credentials are involved — heavy inference runs on your own deployment's inference service.

Modules are the building blocks of a workflow (built in Console → Config → KYC Workflows). A session runs one workflow's enabled modules once. Each module has its own configuration, its own result on the session, and its own credit rate (set per tenant/module — there is no fixed public price).

Info

Workflows are DAGs (directed graphs) of repeatable feature-instance nodes, not a fixed linear list. You can run ID_VERIFICATION twice in one workflow (front ID + proof-of-address document, or primary + secondary ID) and wire each FACE_MATCH node to the specific document node it should compare against. See Workflows for the graph model.

Where each module runs

Not every module is applicant-facing. Three execution surfaces exist:

  • Hosted flow — the applicant captures evidence inside the hosted WebView / iframe (document photos, selfie, OTP). Every client SDK supports these identically.
  • Server-side — no applicant capture; the engine runs the check in the background from data already on the session.
  • Native-only — needs a device radio the WebView cannot reach (NFC). Present in the iOS / Android / Flutter SDKs; on web it falls back to a server-side review.

Info

The workflow decides which modules run and how — including which liveness method. The hosted flow asks the server what to do at each step; the client cannot downgrade or skip a check. A tampered browser gets a review or a decline, never a cheap approval.

Capability comparison

Every module maps to a ModuleResult with a status of approved, declined, in_review, or not_started. The table below adds what each module typically declines or reviews on, so you can see at a glance which checks carry real fraud-detection weight versus which ones just capture data.

Module (feature key)What it checksRunsTypical outcomesCommon failure reasons
ID_VERIFICATIONDocument authenticity, OCR/MRZ/barcode field extraction, tamper analysisHosted flowapproved / declined / reviewForgery suspected, MRZ↔visual mismatch, unreadable capture, expired (if disallowed), document type not permitted
NFC_VERIFICATIONCryptographic chip integrity (BAC/PACE, DG1/DG2/SOD, passive authentication)Native-only (web → review)approved / review / declinedNo CSCA masterlist configured (caps at review), chip data tampered (decline), host has no NFC radio
LIVENESSReal, present human vs. photo/replay/mask/deepfakeHosted flowapproved / declined / reviewSpoof/replay detected (active methods), capture-quality retries exhausted, static-capture (injection) suspected
FACE_MATCH1:1 biometric comparison, document portrait vs. selfieHosted flowapproved / declined / reviewImpostor (cosine below model threshold), no face detected after retries, similarity below tenant's review floor
AGE_ESTIMATIONBiometric age estimate from the selfieServer-sideapproved / review / declinedEstimated age under the configured minimum (decline or review depending on decline_underage)
AML_SCREENINGSanctions / PEP / adverse-media / POI watchlist screeningServer-sideapproved / review / declinedConfirmed hit on a decline-action list, hit on a review-action list, insufficient identity data to screen
PROOF_OF_ADDRESSAddress-document classification, freshness, address extractionHosted flowapproved / reviewStale document (older than max_age_days), unclassifiable document, no address found
DOCUMENT_AIGeneric OCR/classification of an arbitrary custom documentHosted flowapproved / reviewUnreadable capture, configured fields not found
IP_ANALYSISVPN / proxy / Tor / datacenter and abuse signalsServer-sideapproved / review / declinedTor exit node (decline), VPN detected (decline), elevated abuse score (review)
DATABASE_VALIDATIONCross-check against an external authoritative databaseNeeds an external provider → reviewreview onlyNo provider wired up — always routes to review
EMAIL_VERIFICATIONOne-time-code ownership checkHosted flowapproved / in-progress / reviewWatchlisted email address held for review
PHONE_VERIFICATIONSMS/voice OTP ownership checkHosted flowapproved / in-progress / reviewWatchlisted phone number held for review
QUESTIONNAIREStructured answers via a console-built formHosted flowapproved— (informational capture, doesn't gate)
CONFIRM_DETAILSApplicant corrects OCR'd fields before continuingHosted flowapproved
INFORMATIONPlain instruction/consent screenHosted flowapproved
PRODUCT_SELECTIONApplicant picks one of your productsHosted flowapproved
VIDEO_CALLAgent-attended live video verification, server-recordedHosted flow (agent-attended)approved / declined / reviewAgent-driven; depends on the call outcome the operator records

Warning

Two modules have no automated implementation and must never fake-approve. NFC_VERIFICATION on a non-native host, and DATABASE_VALIDATION (needs an external data provider), route to manual review instead of silently passing. They are hidden from the workflow builder but can still appear in legacy or imported workflows.

Which modules do I need?

There is no universal answer — it depends on your regulatory obligations and fraud risk — but most integrations converge on one of three tiers. Use this as a starting point, then tune per jurisdiction with your compliance team.

Identity capture with a live-human check. Suitable for lower-risk onboarding (content platforms, marketplaces, age-gated services) where you need "a real person who presented this document," not deep financial-crime assurance.

  • ID_VERIFICATION — document capture and field extraction
  • LIVENESS (PASSIVE or PASSIVE_VIDEO) — highest-conversion, low-friction
  • FACE_MATCH — confirms the applicant is the document holder

Note

This tier alone does not satisfy most AML/CFT regulatory regimes — it proves identity, not the absence of sanctions/PEP exposure. Add AML_SCREENING before treating it as compliant KYC for a regulated product.

Tip

You don't have to choose a fixed tier per product — a graph workflow can branch: run AML_SCREENING for everyone, then route only sessions with a medium risk level or a large transaction amount to an NFC_VERIFICATION + VIDEO_CALL sub-path. See Workflows for conditional branching.

Reading module results

Per-module outcomes come back on GET /v3/session/<id>/ and, in summary form, in decision_v3 on GET /v3/session/<id>/decision/. Each result carries a status (approved / declined / in_review / not_started), an optional score, warnings, and a data blob. The evidence checklist (/checklist/) tells you what was captured; the timeline (/logs/) tells you what happened and when.

{
  "session_id": "6f0e2b7a-…",
  "status": "in_review",
  "decision": "review",
  "decision_v3": {
    "id_verifications": [{ "node_id": "ID_VERIFICATION", "status": "approved", "score": 92.0, "warnings": [], "data": { "detected_type": "passport" } }],
    "liveness_checks": [{ "node_id": "LIVENESS", "status": "approved", "score": 87.5, "warnings": [], "data": { "method": "PASSIVE" } }],
    "face_matches": [{ "node_id": "FACE_MATCH", "status": "in_review", "score": 61.2, "warnings": ["similarity_below_minimum"], "data": {} }],
    "aml_screenings": [{ "node_id": "AML_SCREENING", "status": "approved", "score": 100, "warnings": [], "data": { "risk_level": "clear" } }],
    "nfc_verifications": [],
    "poa_verifications": [],
    "reviews": []
  },
  "reason": "similarity_below_minimum"
}

Every decision_v3 array key maps 1:1 to a feature key: id_verifications, liveness_checks, face_matches, aml_screenings, nfc_verifications, poa_verifications, phone_verifications, email_verifications, ip_analyses, database_validations, questionnaire_responses. Each entry carries node_id (so you can tell repeated instances of the same module apart in a graph workflow), status, score, warnings, and data.

Warning

The client-visible result is advisory. Grant access or move money only after your backend confirms the authoritative decision from the signed webhook (identity.kyc.session.approved / .declined / .review / .expired) or GET /v3/session/<id>/decision/. See Decisions for the full contract.

Standalone tools

Several module engines are also exposed as stateless one-shot utilities under /v3/tools/* — AML check, face search, signature verify/search/enroll, document extract. They create no session and carry no audit trail. See Standalone tools.

Comparing execution modes

Hosted-flow moduleServer-side moduleStandalone tool
Applicant capture✅ Yes❌ No❌ No
Creates a session✅ Yes✅ Yes❌ No
Audit trail / evidence checklist✅ Yes✅ Yes❌ No
Contributes to decision_v3✅ Yes✅ Yes❌ No (returns its own response)
Good for a compliance decision✅ Yes✅ Yes⚠️ Only as enrichment/triage input
Typical useOnboarding a new applicantBackground checks during onboardingAd-hoc lookups, back-office tooling

FAQ