Integration Methods
The IDnow SDK can be seamlessly integrated into your applications through embedded solutions, allowing users to complete identity verification without leaving your app's environment. This section covers how to implement the IDnow verification flow using iframes for web applications and webviews for mobile apps.
Prerequisites
Before implementing embedded integration:
- Authentication: Obtain valid authentication tokens from the IDnow API (Review the API Reference for authentication and token management)
- Permissions: Configure camera and microphone access for your domain/app
- HTTPS: Ensure your application uses HTTPS (required for camera access)
- Origin configuration: Whitelist your domains with IDnow support (for iframe integrations)
Redirection
You can redirect users to the IDnow verification page directly by navigating to the verification URL with the appropriate token. This is the simplest integration method but takes users away from your application.
https://go.idnow.io/docidv?identToken=YOUR_VERIFICATION_TOKEN
Redirecting the User back to your Website
When this feature is activated for your account, the user can be forwarded to a custom URL on your web server after the user has completed the ident verification process. Separate redirection URLs can be configured depending on whether the user completes the verification flow in the app/web app (successURL) or aborts it (failureURL). Success and Failure URLs can be configured separately for each OS (iOS.Success, iOS.Failure or Android.Success and Android.Failure) and separately for our Web app as well.
The redirect URLs support the variable transactionnumber so that you can receive it and match the redirect call to your internal transaction number.
To configure and activate the redirection feature, please contact your technical account manager at IDnow.
https://www.yourcompany.com/ident-success?q={transactionnumber}
Web Integration with iframes
For web applications, you can embed the IDnow verification flow directly into your website using an iframe. This approach provides:
- Seamless user experience: Users stay within your application domain
- Custom styling: Control the look and feel of the surrounding interface
- Real-time communication: Receive status updates via the PostMessage API
- Security: Sandbox the verification process while maintaining communication
Basic iframe Implementation
To ensure proper iFrame integration, add the embedded query parameter in the iFrame URL with the value iframe.
<iframe
id="idnow-iframe"
src="https://go.idnow.io/docidv?identToken=YOUR_VERIFICATION_TOKEN&embedded=iframe"
width="100%"
height="100%"
border="none"
style="border: none;"
allowfullscreen
allow="fullscreen; camera; microphone"
sandbox="allow-scripts allow-same-origin allow-top-navigation allow-modals allow-popups allow-forms"
></iframe>
To ensure that a flow using Facetec is working properly, allowFullScreen attribute must be defined and allow attribute must be allow="fullscreen; camera; microphone;".
Mobile Integration with WebViews
For native mobile applications, use webviews to embed the IDnow verification flow. To ensure proper webview integration, add the embedded query parameter in the iFrame URL with the value webview.
Android WebView
val webView = findViewById<WebView>(R.id.webview)
val webSettings = webView.settings
webSettings.javaScriptEnabled = true
webSettings.mediaPlaybackRequiresUserGesture = false
// Enable camera and microphone permissions
webSettings.domStorageEnabled = true
webView.loadUrl("https://go.idnow.de/docidv?identToken=$token&embedded=webview")
iOS WKWebView
import WebKit
let webView = WKWebView(frame: view.bounds)
let configuration = webView.configuration
configuration.allowsInlineMediaPlayback = true
configuration.mediaTypesRequiringUserActionForPlayback = []
if let url = URL(string: "https://go.idnow.de/docidv?identToken=\(token)&embedded=webview") {
webView.load(URLRequest(url: url))
}
Messages Structure
The IDnow SDK uses the HTML5 PostMessage API to communicate between embedded content (iframes or webviews) and parent applications. This enables:
- Flow completion notifications: Know when verification succeeds or fails
- Error handling: Receive detailed information about technical issues
- File downloads: Handle document downloads from within the embedded flow
- Connection status: Monitor WebSocket connection health
After migration to DocIDV, your existing Video Ident and Auto Ident postMessage handlers keep working. DocIDV continues to emit the legacy events alongside the new ones documented below, so you can upgrade without rewriting your event-handling code up front. See Legacy Iframe and Webview Events for the full legacy reference.
All messages follow a consistent JSON structure with a type property that defines the message format:
{
"type": "<eventType>",
"<prop1>": "<value1>",
"<prop2>": "<value2>"
}
Communication from Web to Host
The IDnow web app uses the PostMessage API to communicate between the web app running inside an iframe or webview and its host (website or native application). This enables:
- Flow completion notifications: Know when verification succeeds or fails
- File downloads: Handle document downloads from within the embedded flow
- Permission requests: Ask for user permissions, like access to a specific folder
Implementation Guide
Setting Up Message Listeners
window.addEventListener("message", (event) => {
// Validate origin for security
if (event.origin !== "https://your-expected-origin.com") {
return;
}
const message = event.data;
switch (message.type) {
case "IDN_DOCIDV_FLOW_END":
handleFlowEnd(message);
break;
default:
console.log("Unknown message type:", message.type);
}
});
function handleFlowEnd(message) {
if (message.status === "SUCCEED") {
// Handle successful completion
console.log("Verification completed successfully");
} else if (message.status === "ABORTED") {
// Handle abortion
const cause = message.cause;
if (cause.source === "USER") {
console.log("User aborted:", cause.reason);
} else if (cause.source === "TECHNICAL") {
console.log("Technical error:", cause.reason);
}
}
}
Security Considerations
Always validate the event.origin to ensure messages are coming from trusted sources:
// Use the origin that matches your regional IDnow deployment:
// DE: https://go.idnow.de | CH: https://go.online-ident.ch | AE: https://go.idnow.ae
const TRUSTED_ORIGINS = ["https://go.idnow.io", "https://go.idnow.de"];
window.addEventListener("message", (event) => {
if (!TRUSTED_ORIGINS.includes(event.origin)) {
console.warn("Message from untrusted origin:", event.origin);
return;
}
// Process message
});
Messages Web -> Host
IDN_DOCIDV_FLOW_END
Sent when a user reaches an end flow screen. This message indicates the completion or termination of the identity verification process.
Properties
| Property | Type | Required | Value | Description |
|---|---|---|---|---|
type | string | Yes | "IDN_DOCIDV_FLOW_END" | Always "IDN_DOCIDV_FLOW_END" |
status | string | No | "SUCCEED" | "ABORTED" | Flow completion status |
retry | boolean | No | If true, indicates that the user asked to retry the process, thus the webview should be reloaded | |
cause | object | No | { "source": "USER" or "TECHNICAL", "reason": string } | Details provided when the flow was aborted |
Examples
Successful completion:
{
"type": "IDN_DOCIDV_FLOW_END",
"status": "SUCCEED"
}
User-initiated abortion:
{
"type": "IDN_DOCIDV_FLOW_END",
"status": "ABORTED",
"cause": {
"source": "USER",
"reason": "USER_ABORTED_LANGUAGE_SELECTOR_CHOOSE"
}
}
Technical error:
{
"type": "IDN_DOCIDV_FLOW_END",
"status": "ABORTED",
"cause": {
"source": "TECHNICAL",
"reason": "API_ERROR"
}
}
Abortion with retry:
{
"type": "IDN_DOCIDV_FLOW_END",
"status": "ABORTED",
"retry": true,
"cause": {
"source": "TECHNICAL",
"reason": "CALL_QUALITY_FAIL"
}
}
IDN_QES_DOWNLOAD_PDFS_AS_ZIP
Sent as part of the QES flow when a user needs to download documents from inside a webview. This message indicates that the native app should make an API call to download all documents as a zip file on the user's device.
Properties
| Property | Type | Required | Value | Description |
|---|---|---|---|---|
type | string | Yes | "IDN_QES_DOWNLOAD_PDFS_AS_ZIP" | Always "IDN_QES_DOWNLOAD_PDFS_AS_ZIP" |
sessionId | string | Yes | User session id | |
clientKey | string | Yes | Client secret key |
Example
{
"type": "IDN_QES_DOWNLOAD_PDFS_AS_ZIP",
"sessionId": "<session id>",
"clientKey": "<client secret key>"
}
IDN_QES_FOLDER_ACCESS_REQUEST
Sent as part of the QES flow when a user needs folder access in order to download documents. This message indicates that the native app should prompt the user for download folder access.
Properties
| Property | Type | Required | Value | Description |
|---|---|---|---|---|
type | string | Yes | "IDN_QES_FOLDER_ACCESS_REQUEST" | Always "IDN_QES_FOLDER_ACCESS_REQUEST" |
Example
{
"type": "IDN_QES_FOLDER_ACCESS_REQUEST"
}
Communication from Host to Web
Host app can send messages to the web app via the MessageEvent API. This enables:
- Graceful exit: When the user closes the webview
- File downloads: Send feedback on download status (failure or success)
- Permission handling: Get feedback on permission requests (Granted or rejected by the user)
Implementation Guide
Host should evaluate a JS snippet whenever it needs to dispatch a message event to the web app.
// snippet example
window.dispatchEvent(new MessageEvent('message', {
data: {} // message type and payload
}))
| Host | Mechanism |
|---|---|
| iOS (WebKit) | WKWebView.evaluateJavaScript(...) |
| Android / Kotlin | WebView.evaluateJavascript(...) |
| React Native | webViewRef.current.injectJavaScript(...) |
| Flutter | WebViewController.runJavaScript(...) |
Example:
// Implementation for iOS
let payload: [String: Any] = [
"type": "QES_DOWNLOAD_STATUS",
"status": "SUCCESS"
]
let json = try! JSONSerialization.data(withJSONObject: payload)
let jsonString = String(data: json, encoding: .utf8)!
let js = """
window.dispatchEvent(new MessageEvent('message', {
data: JSON.parse('\(jsonString)')
}));
"""
WKWebView.evaluateJavaScript(js, completionHandler: nil)
Messages Host -> Web
IDN_CANCEL_IDENT
Sent by the host when the user is dismissing the webview.
Properties
| Property | Type | Required | Value | Description |
|---|---|---|---|---|
type | string | Yes | "IDN_CANCEL_IDENT" | Always "IDN_CANCEL_IDENT" |
Example
{
"type": "IDN_CANCEL_IDENT"
}
IDN_QES_FOLDER_ACCESS_REQUIRED
Sent by the host when folder access is required. The web app will show a specific screen to inform the user why extra permission is required.
Properties
| Property | Type | Required | Value | Description |
|---|---|---|---|---|
type | string | Yes | "IDN_QES_FOLDER_ACCESS_REQUIRED" | Always "IDN_QES_FOLDER_ACCESS_REQUIRED" |
Example
{
"type": "IDN_QES_FOLDER_ACCESS_REQUIRED"
}
IDN_QES_FOLDER_ACCESS
Sent by the host to inform the web app of the results of the folder access request (Granted or Denied by the user)
Properties
| Property | Type | Required | Value | Description |
|---|---|---|---|---|
type | string | Yes | "IDN_QES_FOLDER_ACCESS" | Always "IDN_QES_FOLDER_ACCESS" |
access | string | Yes | "GRANTED" | "DENIED" | Outcome of the folder access request |
Example
{
"type": "IDN_QES_FOLDER_ACCESS",
"access": "GRANTED"
}
IDN_QES_DOWNLOAD_STATUS
Sent by the host to inform the web app of the results of the file download (Success or Failure)
Properties
| Property | Type | Required | Value | Description |
|---|---|---|---|---|
type | string | Yes | "IDN_QES_DOWNLOAD_STATUS" | Always "IDN_QES_DOWNLOAD_STATUS" |
status | string | Yes | "SUCCESS" | "FAILURE" | Outcome of the download |
Example
{
"type": "IDN_QES_DOWNLOAD_STATUS",
"status": "SUCCESS"
}
Support
For questions about embedded integration or to configure domain whitelisting, contact your IDnow representative or visit our support documentation.