📘 Public beta · Endpoints are stable; OpenAPI specs and SDKs ship monthly. See changelog →
Products
Identity Platform
Overview
Identity Platform

Identity Platform

KYC onboarding and continuous step-up authentication, purpose-built for the Indonesian KTP.

What it does

Identity Platform handles two distinct jobs that share the same biometric stack:

  1. Onboarding KYC. Capture a customer's KTP, run anti-spoof and tamper checks, extract OCR fields, enroll a face reference. Outputs a verified Customer with a KYC tier (none → basic → standard → premium).
  2. Continuous step-up authentication. On every sensitive action (large transfer, password change, new device login), run a live selfie against an enrolled reference. Sub-second match decision. Use your own client-supplied reference image if you have one.

What we explicitly do NOT do

  • We do not issue or validate non-KTP documents (passport, driver's license, etc.). KTP only.
  • We do not call Dukcapil from our side. You call Dukcapil and post the verdict to us — see Dukcapil verdict ingest.

Core concepts

ConceptWhat it is
CustomerYour end-user. Persistent across all verifications and KYC tier transitions.
VerificationA single check (NIK format, KTP capture, face liveness, face match, Dukcapil verdict). Immutable.
CaptureBundleA signed bundle of frames + sensor data submitted by the SDK. Sealed at rest, hash-attested.
FaceEnrollmentA reference embedding for a customer (ArcFace v3, 512-dim). Sources: dukcapil (best), ktp_extract, onboarding_selfie, step_up_promotion.
KYC tiernone · basic · standard · premium. Computed from verification history.
Flash challengeA short single-use color sequence the SDK shows on screen. Used to defeat replay attacks.

KYC tier ladder

TierRequiresCommon use case
noneNothingAccount exists, nothing verified
basicValid NIK formatOpen a pre-funded wallet
standardKTP capture passed (anti-spoof + tamper) OR Dukcapil verdict receivedTransact under regulated tier-1 limits
premiumstandard + face liveness + face match to enrolled referenceWithdraw to bank, large transfer, mortgage open

Common integration shape

A typical Indonesian fintech wires Identity Platform this way:

Onboarding

  1. 1
    POST/api/customers
    Create the customer.
  2. 2
    POST/api/identity/document/ktp/challenge
    Issue a flash challenge — the SDK uses it during capture.
  3. 3
    POST/api/identity/document/ktp/capture
    SDK posts captured frames + OCR fields.
  4. 4
    POST/api/identity/nik/dukcapil
    Post your client-side Dukcapil verdict.
    Optional, but bumps the tier to standard.
  5. 5
    GET/api/identity/kyc/{customerId}
    Check the resulting KYC tier.

Step-up auth (per sensitive action)

  1. 1
    POST/api/identity/face/flash-challenge
    Issue a selfie challenge.
  2. 2
    POST/api/identity/auth/step-up
    Atomic liveness + match decision.
    Returns `{ allow: true | false }`.

Endpoints at a glance

GroupEndpoints
AuthPOST /api/auth/login · POST /api/auth/logout · GET /api/auth/me
WebAuthn / passkeyPOST /api/auth/webauthn/register/{begin,finish} · POST /api/auth/webauthn/auth/{begin,finish}
CustomersGET/POST /api/customers · GET /api/identity/customers/{id} · POST /api/identity/customers/{id}/erase (UU PDP)
KTPPOST /api/identity/document/ktp/challenge · POST /api/identity/document/ktp/capture
FacePOST /api/identity/face/flash-challenge · POST /api/identity/face/liveness · POST /api/identity/face/match
Step-up authPOST /api/identity/auth/step-up
DukcapilPOST /api/identity/nik/dukcapil
KYCGET /api/identity/kyc/{customerId} · POST /api/identity/kyc/{customerId}/upgrade
EnrollmentsGET /api/identity/face/enrollments
DevicesPOST /api/identity/devices/register (called by native SDKs, not directly by your service)
AttemptsGET /api/identity/attempts · GET /api/identity/customers/{id}/attempts
Search (dashboard)GET /api/identity/search?q=... — analyst-only, free-text across customer name / NIK / email
Review queue (dashboard)GET /api/identity/review-queue · POST /api/identity/review-queue/{id}/decision
Tier events (dashboard)GET /api/identity/tier-events — KYC tier history feed
Exports (dashboard)GET /api/identity/export/customers.csv · GET /api/identity/export/verifications.csv
Audit logGET /api/identity/audit-log
WebhooksGET/POST /api/identity/webhooks · POST /api/identity/webhooks/{id}/test
API keysGET/POST /api/identity/api-keys
HealthGET /api/healthz

Routes marked (dashboard) are intended for analyst UI use and require an internal-scope key; integrations consuming the public API don't typically need them.

Production considerations

ConcernAnswer
Data residencyAll biometric captures, embeddings, and KTP frames live in id-jkt-1. Sealed at rest with AES-256-GCM. Never replicated cross-border.
Biometric modelFace matcher is ArcFace v3 (modelId: qe-face-v3); 512-dim embeddings. Default match threshold 0.45 for step-up (tunable per-org for target FAR ~1e-4).
RetentionOnboarding capture frames: 3 years (OJK requirement). Step-up frames: 90 days. Verification rows + audit log: 7 years (regulated record). Embeddings retired on erasure but the row stays for the regulated window.
Rate limitsKTP challenge: 10/min/customer. KTP capture: 5/min/customer. Face liveness: 20/min/customer. Step-up: 60/min/customer. Erasure: 10 per 5 min per org.
IdempotencyCapture bundles dedupe on the bundle nonce within 24h. Repeated submits with the same nonce return the original verification ID.
Right to erasurePOST /api/identity/customers/{id}/erase — UU PDP-compliant, irreversible. See Data deletion →.
AuditEvery customer action, KYC transition, capture, match, dukcapil submit, erasure is audit-logged. Immutable, 7 years.
Webhook signingHMAC-SHA256 over the raw body, header X-Identity-Signature: sha256=<hex>. A suite-wide migration to X-Quantum-Signature is on the 2026 roadmap — accept both for forward compatibility.

Read next