🚀 Getting Started
See the Web SDK in action right now on the live camera demo page — document auto-capture, face active liveness, face verification, and passive liveness, all running in your browser.
The iApp eKYC SDK is a free, open-source (Apache-2.0) set of client SDKs for iApp Technology's enterprise eKYC APIs — automatic Thai ID card / passport capture, face active liveness, face verification, and passive liveness — for Web (HTML5/JavaScript), Flutter (Android/iOS), native iOS (Swift/Objective-C), native Android (Kotlin/Java), and React Native.
The Web and Flutter packages run the capture engine directly on-device. The native iOS, Android, and React Native packages are thin shells around the same production web engine — identical capture quality everywhere, with almost no added binary size. See iOS, Android & React Native for those platforms.
The SDKs themselves cost nothing. API calls are billed per request to your iApp API key at the same rates as calling the APIs directly — see each capability page for its credit cost.
Source code: https://github.com/iapp-technology/iapp-ekyc-sdk
What the SDK does for you
| Capability | What the SDK does | API charged |
|---|---|---|
| 🪪 ID Card auto-capture | Detects the card boundary, waits for a sharp stable frame, perspective-corrects, submits | 1.25 IC front / 0.75 IC back |
| 🛂 Passport auto-capture | Same engine tuned for the passport data page (MRZ) | 0.75 IC |
| 📇 Official card auto-capture | Driver license, bank book, ID card with signature | 1.0–1.25 IC/page |
| 🙂 Face Active Liveness | Randomized on-device challenges, best-frame selection, server-signed verdict | 1 IC |
| 👥 Face Verification | One-call comparison of two face images | 0.3 IC |
| 🛡️ Face Passive Liveness | Single-image spoof check | 0.3 IC |
Installation
Flutter
Add the SDK as a git dependency in pubspec.yaml:
dependencies:
iapp_ekyc_sdk:
git:
url: https://github.com/iapp-technology/iapp-ekyc-sdk.git
path: flutter
import 'package:iapp_ekyc_sdk/iapp_ekyc_sdk.dart';
final client = IappEkycClient(apiKey: 'YOUR_API_KEY');
Web
Install from npm:
npm install @iapp-technology/ekyc-sdk
import { IappEkyc } from '@iapp-technology/ekyc-sdk';
const ekyc = new IappEkyc({ apiKey: 'YOUR_API_KEY' });
Or load the UMD bundle via a script tag, which exposes the
window.IappEkyc namespace (the class lives inside it):
<script src="https://unpkg.com/@iapp-technology/ekyc-sdk"></script>
<script>
const ekyc = new window.IappEkyc.IappEkyc({ apiKey: 'YOUR_API_KEY' });
</script>
iOS (Swift / Objective-C)
Xcode → File → Add Package Dependencies… → https://github.com/iapp-technology/iapp-ekyc-sdk → product IappEkyc:
import IappEkyc
let config = IappEkycConfig(apiKey: "YOUR_API_KEY", flow: .documentCapture)
config.documentType = .thaiIdFront
IappEkycSdk.present(from: self, config: config) { result in /* ... */ }
Full setup (permissions, Objective-C, results): iOS, Android & React Native.
Android (Kotlin / Java)
Via JitPack:
// app/build.gradle.kts — plus maven("https://jitpack.io") in repositories
dependencies { implementation("com.github.iapp-technology:iapp-ekyc-sdk:v0.2.0") }
val ekyc = registerForActivityResult(IappEkycContract()) { result -> /* ... */ }
ekyc.launch(IappEkycRequest.DocumentCapture(config, EkycDocumentType.THAI_ID_FRONT))
Full setup (Java callback API, results): iOS, Android & React Native.
React Native
git clone https://github.com/iapp-technology/iapp-ekyc-sdk
npm install ./iapp-ekyc-sdk/react-native react-native-webview
<IappEkycFlow flow="documentCapture" documentType="thaiIdFront"
apiKey="YOUR_API_KEY" onResult={...} onError={...} onCancel={...} />
Full setup (permissions, Modal usage): iOS, Android & React Native.
API Key Setup
Get an API key from the API Key Management page.
Any key that ships in a client app can be extracted (APK decompilation, browser dev tools). For production, use the backend-proxy pattern: point the SDK at your own backend and keep the iApp key server-side.
IappEkycClient(apiKey: '', baseUrl: 'https://your-backend.example.com/ekyc')
When apiKey is empty the SDK sends no apikey header; your proxy attaches the real key and forwards to https://api.iapp.co.th. At minimum, create a dedicated restricted key per app so a leaked key can be revoked independently. Full guidance: SECURITY.md on GitHub.
Theming
All platforms ship the same professional light-blue default theme and accept full overrides. Token names and default values are identical across platforms (native wrappers pass the same tokens through their config objects):
| Token | Default | Used for |
|---|---|---|
primary | #0284C7 | buttons, active guide frame, progress |
primaryDark | #0C4A6E | headings, instruction text |
primaryLight | #BAE6FD | idle guide frame, subtle accents |
surface | #F0F9FF | sheets, instruction chips |
onPrimary | #FFFFFF | text/icons on primary |
success | #22C55E | quad locked, challenge passed |
warning | #F59E0B | hold still / too blurry |
error | #EF4444 | failures |
overlayScrim | #0C4A6E at 60% | camera overlay outside the guide |
brandDeep | #113F7B | optional iApp brand accent |
borderRadius | 16 | chips, buttons, result cards |
guideStrokeWidth | 3 | guide frame stroke |
fontFamily | platform default | optional override |
Flutter — EkycTheme is a plain immutable class (no dependency on Theme.of):
const theme = EkycTheme.lightBlue; // default
final custom = EkycTheme.lightBlue.copyWith(
primary: Color(0xFF113F7B),
borderRadius: 12,
);
DocumentCaptureView.start(context, theme: custom, ...);
Web — tokens are injected as CSS custom properties on the mount element:
new IappEkyc({ apiKey, theme: { primary: '#113F7B', borderRadius: 12 } });
/* or override with plain CSS */
#ekyc-mount { --iapp-ekyc-primary: #113f7b; --iapp-ekyc-border-radius: 12px; }
More detail: THEMING.md on GitHub.
Localization
All UI strings ship in English, Thai, and Chinese:
// Flutter
DocumentCaptureView.start(context, client: client,
documentType: DocumentType.thaiIdFront, locale: EkycLocale.th);
// Web: 'en' | 'th' | 'zh'
await ekyc.captureDocument({ mount, documentType: 'thaiIdFront', locale: 'th' });
The native wrappers accept the same locales: config.locale = .th (iOS), .locale(EkycLocale.TH) (Android), locale="th" (React Native).
Platform Requirements
Flutter
- Flutter ≥ 3.32 / Dart ≥ 3.8
- Android:
minSdk 24 - iOS: 15.5+ and an
NSCameraUsageDescriptionentry inInfo.plist(see theflutter/exampleapp in the repo for the required permission strings)
Web
- Modern browsers with WebAssembly and
getUserMedia - HTTPS required (or
localhost) — browsers block camera access on insecure origins - OpenCV/MediaPipe assets are lazy-loaded only when a capture flow starts; self-host them via the
assetBaseUrloption if your CSP forbids CDN requests
iOS / Android / React Native (native wrappers)
- iOS: 15+ · Swift Package Manager ·
NSCameraUsageDescriptionin Info.plist - Android: minSdk 24 · up-to-date Android System WebView (Chrome/WebView ≥ 100 recommended)
- React Native: RN ≥ 0.72 ·
react-native-webview≥ 13.6 - Internet access to
https://iapp.co.th/sdk/webview.htmlat runtime