The EkycClient
EkycClient is the top-level type. Construct it once with an EkycConfig and share it across your app.
import 'package:drukverify_flutter/drukverify_flutter.dart';
final client = EkycClient(
config: EkycConfig(
host: 'https://api.drukverify.com',
apiKey: 'pk_live_…',
tokenProvider: () async => await myBackend.fetchToken(),
),
);
EkycConfig
| Field | Type | Default | Notes |
|---|---|---|---|
host | String | https://api.drukverify.com | Base URL of the gateway. Override for staging (https://staging.api.drukverify.com) or a local stack. |
apiKey | String (required) | — | Your public tenant key (pk_test_… or pk_live_…). The environment is encoded in the key — there are no separate sandbox URLs. |
tokenProvider | Future<String> Function() (required) | — | Async callback returning a dv_tok_… session token minted by your server. |
apiVersion | String | '2026-04-26' | Pinned wire-format date. Override only if you know your gateway accepts a different one. |
timeout | Duration | 30s | Per-request HTTP timeout (connect + receive). Bump to 90s for the demo or for slow mobile networks where OCR uploads can stretch. |
Multipart upload helpers
The three most-used endpoints take multipart/form-data bodies that the OpenAPI spec doesn't fully describe. The SDK ships hand-rolled helpers on EkycClient so callers don't need to construct FormData themselves:
// /v1/ocr/scan — extract fields from a Bhutanese CID or passport
final ocr = await client.ocrScanImages(
image: File('/path/to/front.jpg'),
backImage: File('/path/to/back.jpg'), // optional, for two-sided IDs
);
// /v1/face/verify — 1:1 selfie vs ID portrait
final match = await client.faceVerifyImages(
imageA: File('/path/to/id_portrait.jpg'),
imageB: File('/path/to/selfie.jpg'),
);
// /v1/liveness/check — single-frame anti-spoof + deepfake check
final live = await client.livenessCheckImage(File('/path/to/frame.jpg'));
Each helper goes through the SDK's auth, version, and error interceptors. Errors surface as typed EkycException subclasses — EkycValidationException on a 400, EkycAuthException on a 401, etc.
Sub-API accessors
For endpoints with JSON bodies, the SDK exposes the codegen'd sub-APIs:
client.sessions // mint, revoke
client.face // register, search, dedupe, list registrations
client.ocr // list past scans, get by id, delete
client.liveness // create challenge, get check by id
client.diagnostics // ping
Each sub-API's methods correspond 1:1 with the operations in the API reference.
Custom UI primitives
For apps that want their own UI on top of the camera — different overlay design, a specialized document capture screen, headless burst flows — v2.2.0 ships six composable primitives covering permissions, camera, face quality, image preprocessing, and the burst face-verify loop. See Custom UI primitives.
Test seam
For unit tests, construct the client with a pre-configured Dio:
final dio = Dio()..httpClientAdapter = MyFakeAdapter();
final client = EkycClient.withDio(dio);
EkycClient.withDio is marked @visibleForTesting — production code paths always go through EkycClient(config:).