eKYC Middleware API

v3.0.0

Production Ready
Try Demo

API Documentation

Identity verification as an API for any platform that onboards people: lending, fintech, HR, healthcare, marketplaces and gaming. 13-stage decision pipeline with AWS Textract OCR, risk scoring, fraud detection, face embedding deduplication, and strict response contracts.

v3.0 — 13-stage pipeline, risk scoring layer, face embedding dedup, AWS Textract OCR, idempotent endpoints, rate limiting.

PASSPORT_NFC_VERIFIED

Passport + MRZ match + NFC chip verified + liveness + face match

PASSPORT_ENHANCED_VERIFIED

Passport + MRZ match + liveness + face match (no NFC)

BASIC_VERIFIED

Non-passport basic biometric verification

Base URL

/api

Authentication

Two authentication methods:

API Key

For operators creating KYC sessions

X-API-Key: pk_live_...

JWT Bearer Token

For admin/operator dashboard access

Authorization: Bearer eyJ...

Operator Integration Flow

Quick Start — 3 Steps

1

Create a session

POST /api/kyc/start
Headers: X-API-Key: pk_live_your_key
Body: { "externalUserId": "user-123" }
2

Redirect user to widget

https://your-domain.com/kyc?session={sessionToken}
3

Receive webhook or poll

// Webhook: POST to your configured webhookUrl
// Or poll: GET /api/kyc/session/{sessionToken}

Passport Verification Flow

10-Step Passport Flow

1.POST /api/kyc/start → Create session
2.POST /api/kyc/consent → Record consent
3.POST /api/kyc/document-type → Set type to PASSPORT
4.Upload passport biodata page (presigned URL)
5.POST /api/kyc/ocr/run → OCR + auto MRZ parse
6.POST /api/kyc/nfc/check → Check NFC capability
7.If NFC: POST /api/kyc/nfc/result | If not: POST /api/kyc/nfc/skip
8.Upload selfie + Face Liveness check
9.POST /api/kyc/face-match/run → Face comparison
10.POST /api/kyc/decision/finalize → 13-stage decision pipeline + risk scoring

KYC Widget Endpoints

Called by the KYC widget. Authenticated via sessionToken.

Passport & MRZ Endpoints

Passport-specific verification endpoints.

NFC Endpoints

NFC is an optional enhancement — it never blocks verification. If NFC is unavailable, verification continues at PASSPORT_ENHANCED_VERIFIED level. NFC data inconsistency after a successful chip read WILL trigger a failure.

Risk Scoring Layer

Computes a composite risk score (0-100) from weighted analysis of all verification signals. Integrated as Stage 11 in the decision pipeline.

Score Weights (Total = 100)

Fraud Signals35Document tampering score (HEAVILY weighted)
Face Match20Selfie-to-ID similarity
OCR Confidence15Textract extraction confidence
Completeness15Required field extraction rate
Liveness15AWS Rekognition liveness confidence

Risk Levels

LOW0 – 29

→ PASS (auto-approved)

MEDIUM30 – 60

→ MANUAL_REVIEW (human review required)

HIGH61 – 100

→ FAIL (auto-rejected)

// Risk scoring in decision/finalize response:
{
  "riskScore": 18,
  "riskLevel": "LOW",
  "evaluation": {
    "riskScore": 18,
    "riskLevel": "LOW",
    "stages": [{
      "name": "risk_scoring",
      "passed": true,
      "details": {
        "riskScore": 18,
        "riskLevel": "LOW",
        "breakdown": {
          "ocrConfidence":  { "score": 0.9, "raw": 0.94, "details": "..." },
          "completeness":   { "score": 0.0, "raw": 1.0,  "details": "..." },
          "faceMatch":      { "score": 1.6, "raw": 92.0, "details": "..." },
          "liveness":       { "score": 0.4, "raw": 97.5, "details": "..." },
          "fraud":          { "score": 3.5, "raw": 10,   "details": "..." }
        }
      }
    }]
  }
}

Face Embedding Duplicate Detection

Uses AWS Rekognition Collections to detect duplicate faces across sessions. Automatically triggered on selfie upload.

Flow

1.User uploads selfie → confirmed via /upload-confirm
2.Backend calls SearchFacesByImage against the collection
3.If match > 90% similarity → flag MANUAL_REVIEW_DUPLICATE_FACE
4.Backend calls IndexFaces to add the new face to the collection
5.FaceId, similarity score, and matched session stored in DB

Stored Data

• faceId — AWS Rekognition face identifier

• similarity — Match score (0-100%)

• matchedSessionId — Previous session with matching face

• collectionId — Rekognition collection used

AWS Requirements

• rekognition:CreateCollection

• rekognition:IndexFaces

• rekognition:SearchFacesByImage

• rekognition:DescribeCollection

Non-blocking: gracefully degrades if permissions missing.

Health & Rate Limiting

Rate Limiting

• /kyc/start — Rate limited (burst protection)

• Returns 429 Too Many Requests when exceeded

• Per-IP and per-API-key tracking

Idempotency

• /decision/finalize — Returns cached decision

• /ocr/run — Returns cached OCR result

• /face-match/run — Returns cached match

• Response includes idempotent: true

Correlation IDs

All API responses include x-request-id header for tracing. Optionally send your own.

// Request header (optional):
X-Request-Id: your-correlation-id

// Response header (always present):
X-Request-Id: abc123-uuid

Admin Portal APIs

All admin endpoints require Authorization: Bearer <token>. Session list/detail now includes document type, MRZ, NFC, verification level.

Operator Portal APIs

Webhooks

Signed webhook on PASS or FAIL. Includes verificationLevel, riskScore, and riskLevel.

POST {operator.webhookUrl}
X-Webhook-Signature: sha256=a1b2c3...

{
  "event": "kyc.completed",
  "data": {
    "sessionId": "...",
    "externalUserId": "user-12345",
    "status": "PASS",
    "verificationLevel": "PASSPORT_ENHANCED_VERIFIED",
    "riskScore": 15,
    "riskLevel": "LOW",
    "decision": {
      "outcome": "PASS",
      "reasonCode": "PASS_AUTO"
    }
  }
}

Signature Verification (Node.js)

const crypto = require('crypto')
const expected = 'sha256=' + crypto
  .createHmac('sha256', webhookSecret)
  .update(JSON.stringify(payload)).digest('hex')
const valid = crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))

Retry: Immediate → 1min → 3min → 6min (final)

Session State Machine

STARTED
  → DOCUMENTS_UPLOADED
    → OCR_COMPLETE
      → MRZ_PARSED (passport only)
        → NFC_COMPLETE (if NFC attempted)
          → LIVENESS_CREATED → LIVENESS_COMPLETE
            → FACE_MATCH_COMPLETE
              → PASS ✅  |  FAIL ❌  |  MANUAL_REVIEW ⏳

Decision Engine v2.2 — 13-Stage Pipeline

Each stage evaluates independently with its own reason code. First FAIL stops the pipeline. First MANUAL_REVIEW flags for human review. Risk scoring provides a composite 0-100 score.

1.capture_quality

ID front + selfie present and usable

Reason codes: FAIL_IMAGE_UNREADABLE, FAIL_NO_SELFIE

2.ocr_extraction

OCR succeeded via AWS Textract

Reason codes: FAIL_OCR, FAIL_IMAGE_UNREADABLE

3.document_field_validation

Required fields present per document type

Reason codes: FAIL_MISSING_REQUIRED_FIELDS, MANUAL_REVIEW_LOW_CONFIDENCE

4.confidence_completeness

OCR confidence ≥ 70%, field completeness scoring

Reason codes: MANUAL_REVIEW_LOW_CONFIDENCE, FAIL_OCR

5.mrz_extraction

MRZ readable (passport only)

Reason codes: MANUAL_REVIEW_MRZ_UNREADABLE

6.mrz_validation

OCR matches MRZ data

Reason codes: FAIL_OCR_MRZ_MISMATCH, MANUAL_REVIEW_PASSPORT

7.document_validity

Not expired, age ≥ minimum age, valid format

Reason codes: FAIL_PASSPORT_EXPIRED, FAIL_UNDERAGE, FAIL_DOCUMENT_EXPIRED

8.liveness

Confidence ≥ 80%

Reason codes: FAIL_LIVENESS

9.face_match

≥80 pass, 70-79 review, <70 fail

Reason codes: FAIL_FACE_MATCH, MANUAL_REVIEW_BORDERLINE_FACE

10.fraud_detection

Document integrity analysis — tampering score

Reason codes: FAIL_IMAGE_TAMPERED, MANUAL_REVIEW_FRAUD_SUSPECTED

11.risk_scoring
NEW

Composite 0-100 risk score (LOW/MEDIUM/HIGH)

Reason codes: FAIL_HIGH_RISK, MANUAL_REVIEW_MEDIUM_RISK

12.duplicate_check
NEW

Identity + face embedding duplicate detection

Reason codes: MANUAL_REVIEW_DUPLICATE_IDENTITY, MANUAL_REVIEW_DUPLICATE_FACE

13.final_decision

Aggregate result from all stages

Reason codes: PASS_AUTO, FAIL_*, MANUAL_REVIEW_*

Auto-PASS (all stages pass)

  • • Passport: all fields + MRZ match + not expired + age valid + liveness ≥ 80% + face match ≥ 80%
  • • If NFC chip consistent → PASSPORT_NFC_VERIFIED
  • • If no NFC → PASSPORT_ENHANCED_VERIFIED
  • • Non-passport → BASIC_VERIFIED

MANUAL_REVIEW

  • • MRZ partially readable / OCR low confidence / borderline image
  • • Face match 70–79% (borderline)
  • • Partial OCR/MRZ mismatch (non-critical fields)
  • • Risk score 30-60 (MEDIUM) — composite risk triggers review
  • • Duplicate face detected — face embedding match > 90%
  • • Duplicate identity — same name+DOB or document number
  • • Fraud suspected — document tampering signals detected

Auto-FAIL

  • • Passport expired / underage / strong OCR-MRZ mismatch
  • • Liveness failed / face match <70% / no face detected
  • • NFC chip data inconsistent with document
  • • Risk score > 60 (HIGH) — composite risk too high
  • • Document tampered — high fraud tampering score

All Reason Codes

CodeDescription
PASS_AUTOAll checks passed automatically
PASS_NFC_VERIFIEDPassed with NFC chip verification
PASS_REVIEWEDApproved by manual reviewer
FAIL_OCROCR extraction failed
FAIL_LIVENESSLiveness check failed
FAIL_FACE_MATCHFace similarity < 70%
FAIL_PASSPORT_EXPIREDPassport expired
FAIL_DOCUMENT_EXPIREDNon-passport document expired
FAIL_UNDERAGEBelow the configured minimum age
FAIL_OCR_MRZ_MISMATCHStrong mismatch between OCR and MRZ
FAIL_IMAGE_UNREADABLENo usable document image
FAIL_NO_SELFIENo selfie uploaded
FAIL_NO_FACE_DETECTEDNo face in document or selfie
FAIL_NFC_DATA_INCONSISTENTNFC chip data inconsistent
FAIL_PASSPORT_VALIDATIONPassport validation failed
FAIL_MISSING_REQUIRED_FIELDSRequired fields not extracted by OCR
FAIL_IMAGE_TAMPEREDDocument tampering detected (fraud)
FAIL_HIGH_RISKRisk score > 60 (HIGH) — composite risk too high
FAIL_REVIEWEDRejected by reviewer
MANUAL_OCR_PARTIALOCR partially successful
MANUAL_REVIEW_MRZ_UNREADABLEMRZ not readable
MANUAL_REVIEW_POOR_IMAGEBorderline image quality
MANUAL_REVIEW_BORDERLINE_FACEFace match 70-79%
MANUAL_REVIEW_PASSPORTPartial OCR/MRZ mismatch
MANUAL_REVIEW_LOW_CONFIDENCELow OCR confidence or completeness
MANUAL_REVIEW_FRAUD_SUSPECTEDFraud signals detected in document
MANUAL_REVIEW_MEDIUM_RISKRisk score 30-60 (MEDIUM) — needs review
MANUAL_REVIEW_DUPLICATE_IDENTITYDuplicate name+DOB or document number
MANUAL_REVIEW_DUPLICATE_FACEDuplicate face found via embedding match
RETRY_REQUESTEDReviewer requested retry

Verification Levels

PASSPORT_NFC_VERIFIED

Passport + OCR/MRZ match + NFC chip consistent + liveness ≥ 80% + face match ≥ 80%

PASSPORT_ENHANCED_VERIFIED

Passport + OCR/MRZ match + (no NFC or NFC skipped) + liveness ≥ 80% + face match ≥ 80%

BASIC_VERIFIED

Non-passport document + liveness + face match (Phase 1 basic biometric only)

Error Handling

{ "error": "Description of the error" }
CodeDescription
200Success
201Created
400Bad Request
401Unauthorized
403Forbidden
404Not Found
410Session Expired
429Rate Limit Exceeded
500Server Error

eKYC Middleware Platform v3.0.0

13-stage decision pipeline • Risk scoring • Face embedding dedup • AWS Textract OCR