Mobile onboarding
Embed the Live ID hosted capture page in a native app — WebView setup and camera permissions for iOS, Android, and .NET MAUI, plus ready-to-run sample apps.
In a native app, you embed the hosted capture page in a WebView rather than building your own camera UI. The WebView runs the same flow as the web — selfie, face match, liveness — and your app reads the verdict by polling the session.
The hosted page sets frame-ancestors 'none', so it cannot be put in a web
iframe. A native WebView is a top-level load, not an iframe, so this is
fine — and the right pattern (locked v1 design).
The pattern
graph TD
A[App: user taps Log in] --> B[Ask your backend to mint a session]
B --> C[Backend returns captureUrl + sessionToken]
C --> D[Open captureUrl in a WebView]
D --> E[WebView: selfie -> face match + liveness]
A --> F[Poll GET …/sessions/sessionToken every 2s]
E --> F
F --> G{status == completed?}
G -->|yes| H[Read matched -> grant or deny, close WebView]
G -->|no| F
Two things every platform needs:
- Mint server-side, hold only the token. The app calls your backend,
which calls Certivant's
POST /sessionswith the Identification Key. The app receives onlycaptureUrl+sessionToken. - Grant the WebView's camera request.
getUserMediainside a WebView is blocked until you explicitly grant it — the hook differs per platform (below).
Camera permission per platform
iOS (WKWebView). Declare NSCameraUsageDescription, allow inline
media, and grant the capture request via WKUIDelegate (iOS 15+):
let config = WKWebViewConfiguration()
config.allowsInlineMediaPlayback = true
config.mediaTypesRequiringUserActionForPlayback = []
// WKUIDelegate:
func webView(_ webView: WKWebView,
requestMediaCapturePermissionFor origin: WKSecurityOrigin,
initiatedByFrame frame: WKFrameInfo,
type: WKMediaCaptureType,
decisionHandler: @escaping (WKPermissionDecision) -> Void) {
decisionHandler(.grant)
}
Android (WebView). Add the CAMERA manifest permission, request it
at runtime, and grant the page's request in WebChromeClient:
webView.settings.javaScriptEnabled = true
webView.settings.mediaPlaybackRequiresUserGesture = false
webView.webChromeClient = object : WebChromeClient() {
override fun onPermissionRequest(req: PermissionRequest) {
runOnUiThread { req.grant(arrayOf(PermissionRequest.RESOURCE_VIDEO_CAPTURE)) }
}
}
.NET MAUI. Customize the shared WebView handler once; each platform
wires its own grant (Android WebChromeClient, iOS/Mac WKUIDelegate,
Windows WebView2 PermissionRequested). Add NSCameraUsageDescription
(iOS/Mac), the CAMERA permission (Android), and the webcam
capability (Windows).
Microsoft.Maui.Handlers.WebViewHandler.Mapper.AppendToMapping(
"LiveIdCamera", (handler, view) => {
#if ANDROID
handler.PlatformView.SetWebChromeClient(new LiveIdChromeClient());
#elif IOS || MACCATALYST
handler.PlatformView.UIDelegate = new LiveIdUIDelegate();
#elif WINDOWS
// CoreWebView2.PermissionRequested -> Allow (Camera)
#endif
});
Reading the result
Poll the status endpoint and stop when it completes:
GET https://app.certivant.com/api/kyc/public/live-id/sessions/{sessionToken}
→ { "status": "completed", "matched": true, … }
matched === true → grant login. Your backend can also subscribe to the
live_id.validation.completed webhook for an authoritative server-side signal —
useful when you want the grant decision to live entirely on your backend.
Sample apps
Complete, runnable references live in the repository under
samples/live-id-validation/:
| Sample | Stack | Targets |
|---|---|---|
android-kotlin/ | Kotlin | Android |
ios-swiftui/ | SwiftUI | iOS 15+ |
maui/ | .NET MAUI | Android · iOS · Windows · macOS |
Each is one screen: tap Verify with selfie → WebView → result. Set your host
and a session source in the sample's LiveIdConfig (your backend endpoint, or a
curl-minted token for a quick test), then run. See each sample's README for
build steps and the exact files that wire up the camera grant and polling.
Live ID API reference
Endpoints for Live ID Validation — issue an Identification Key, mint a capture session, open the hosted capture page, submit a selfie, poll the result, and the validation webhook payload.
MCP Server
Connect an AI assistant to Certivant over the Model Context Protocol — triage the verification queue, send and track forms, chase stalled applicants, explain decisions, and report, all through your existing API key.