Connection
KYC Widget
A browser-based identity-verification flow: document capture, selfie and liveness (anti-spoofing) checks. There are four ways to integrate it:
<script>tag in a plain JavaScript application —window.KYCWidget.setupKYC({...})- npm package kyc-widget in a React application —
<KycWidget ... /> <script>tag in a React application- Direct link (no integration) — https://kyc.enface.ai
Configuration Options
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| scenarioId | string | Yes* | — | Unique scenario identifier from the «KYC/AML» section of the personal account (*not required when taskId is used) |
| clientKey | string | Yes* | — | Unique string (max 36 characters) that must be passed encrypted; the encryption code sample is available in the personal account under the «KYC/AML» section (*not required when taskId is used) |
| clientUser | string | No | — | Client’s user identifier, max 36 characters. Does not have to be unique: pass the same value across sessions to later find all sessions (attempts) of that user by searching for it |
| taskId | string | No | — | ID of a verification task pre-created via the API. When set, the widget opens that task directly and scenarioId/clientKey are not needed |
| isOpen | boolean | Yes* | — | Widget visibility state (*required only for the React component) |
| theme | light | dark | No | scenario setting |
| stickySession | boolean | No | false | Sticky sessions: the widget remembers the clientKey per scenario (in localStorage, for 15 minutes). Reopening within that window resumes the previous session even if a different clientKey is passed |
| closeCb | function | No | — | Callback triggered when the widget is closed |
| successCb | function | No | — | Callback triggered upon successful verification. Receives the session result as a JSON string |
| finalizedCb | function | No | — | Callback triggered when the widget is opened for a session that has already been finalized earlier. Receives { status } |
| topOffset | number | No | 0 | Top padding in pixels |
| bottomOffset | number | No | 0 | Bottom padding in pixels |
| blurHost | boolean | No | false | If true, the widget background is rendered as frosted glass over the host page (no background image, no right blur panel) — the host page shows through a translucent blurred overlay |
| mountElementId | string | No | — | Script-tag integration only (widget-lib.js). If set, the widget mounts inline inside the element with this id instead of covering the whole page. The widget fills the host element (width/height: 100%), so give the host element explicit dimensions. See example below. Not supported inside a cross-origin iframe — the camera will be blocked; in that case closeCb is invoked so the host can reset its state. Do not call setupKYC from within closeCb — repeated iframe detections will recurse. |
successCb payload
successCb receives the verification result as a JSON string. The exact set of fields depends on the scenario steps (a document step appears as "type": "document", liveness as "type": "liveness", etc.). An abridged example:
{
"sessionId": "098d57-...",
"status": "success",
"errors": [],
"results": [
{
"type": "liveness",
"status": "success",
"errors": [],
"tries": 1,
"startedAt": "2026-07-19T09:41:37.590Z",
"faces": ["https://..."],
"video": "https://..."
}
],
"schemaId": "3676-...",
"clientKey": "46d1c-...",
"clientUser": "",
"createdAt": "2026-07-19T09:41:37.000Z",
"secondsToLive": 0
} 1. Example of Integration in a JavaScript Application via Script Tag (index.html)
- Define a button with an initial loading state.
- Load the script dynamically and enable the button when ready.
- Call
window.KYCWidget.setupKYC()on button click.
File: index.html
<body>
<button id="btn" disabled>Loading...</button>
<script>
const btn = document.getElementById("btn");
const script = document.createElement("script");
script.src = "https://kyc.enface.ai/lib/widget-lib.js";
script.onload = () => {
btn.disabled = false;
btn.textContent = "Open KYC Widget";
};
script.onerror = () => {
btn.textContent = "Failed to load KYC Widget";
};
document.body.appendChild(script);
const openWidget = () => {
window.KYCWidget.setupKYC({
scenarioId: "scenarioId",
clientKey: "clientKey",
clientUser: "clientUser",
theme: "light",
stickySession: true,
topOffset: 0,
bottomOffset: 0,
// Optional. If set, the widget mounts INSIDE the element with this id
// (inline block) instead of covering the whole page. Host element
// must exist in the DOM. On close the host element is cleared.
// ⚠️ Do NOT load the host page inside a cross-origin <iframe> —
// the browser blocks getUserMedia and the camera won't start.
// mountElementId: "kyc-here",
closeCb: () => console.log("CLOSE CALLBACK"),
successCb: (sessionJson) => console.log("SUCCESS CALLBACK", sessionJson),
finalizedCb: ({ status }) => console.log("FINALIZED CALLBACK", status),
});
};
btn.addEventListener("click", openWidget);
</script>
</body> 2. Example of Integration in a React Application via NPM Package
- Install the npm package kyc-widget:
npm i kyc-widget. - Import it into the application:
import { KycWidget } from "kyc-widget". - Define a state variable to control the widget’s visibility.
- Pass props to the
KycWidgetcomponent (see Configuration Options above).
The package does not bundle React — react and react-dom must be installed in your application.
File: App.js
import { useState } from "react";
import { KycWidget } from "kyc-widget";
function App() {
const [isOpen, setIsOpen] = useState(false);
return (
<>
<button onClick={() => setIsOpen(true)}>Open</button>
<KycWidget
scenarioId="scenarioId"
clientKey="clientKey"
clientUser="clientUser"
isOpen={isOpen}
stickySession={true}
theme="light"
topOffset={0}
bottomOffset={0}
closeCb={() => setIsOpen(false)}
successCb={(sessionJson) => console.log("SUCCESS CALLBACK", sessionJson)}
finalizedCb={({ status }) => console.log("FINALIZED CALLBACK", status)}
/>
</>
);
}
export default App; 3. Example of Integration in a React Application via Script Tag
Use this method if you cannot install the npm package and need to load the widget via a script tag.
- Load the widget script dynamically in
useEffect. - Track loading state with
useState. - Show the button only after the script is loaded.
- Call
window.KYCWidget.setupKYC()on button click.
File: App.js
import { useState, useEffect, useCallback } from "react";
function App() {
const [widgetLoaded, setWidgetLoaded] = useState(false);
const openWidgetHandler = () => {
window.KYCWidget.setupKYC({
scenarioId: "scenarioId",
clientKey: "clientKey",
clientUser: "clientUser",
theme: "light",
topOffset: 0,
bottomOffset: 0,
// Optional. If set, the widget mounts INSIDE the element with this id
// (inline block) instead of covering the whole page. Host element
// must exist in the DOM. On close the host element is cleared.
// ⚠️ Do NOT load the host page inside a cross-origin <iframe> —
// the browser blocks getUserMedia and the camera won't start.
// mountElementId: "kyc-here",
closeCb: () => console.log("CLOSE CALLBACK"),
successCb: (sessionJson) => console.log("SUCCESS CALLBACK", sessionJson),
finalizedCb: ({ status }) => console.log("FINALIZED CALLBACK", status),
});
};
const loadWidgetScript = useCallback(() => {
const widgetScript = document.getElementById("kyc-widget-script");
if (widgetScript) return;
const script = document.createElement("script");
script.id = "kyc-widget-script";
script.src = 'https://kyc.enface.ai/lib/widget-lib.js';
script.defer = true;
script.crossOrigin = "anonymous";
script.onload = () => {
setWidgetLoaded(true);
};
script.onerror = () => {
console.error("Failed to load KYC Widget script");
};
document.head.appendChild(script);
}, []);
useEffect(() => {
if (window.KYCWidget) {
setWidgetLoaded(true);
return;
}
loadWidgetScript();
}, [loadWidgetScript]);
return (
<>
{widgetLoaded && (
<button onClick={openWidgetHandler}>Open KYC Widget</button>
)}
</>
);
}
export default App; 4. Verification via Link
To complete the verification process, you can use the service at https://kyc.enface.ai directly.
Following a link of the form below creates a session:
https://kyc.enface.ai/scenarioId/clientKey
https://kyc.enface.ai/scenarioId/clientKey/clientUser - scenarioId: A unique scenario identifier, which must be obtained in the user’s personal account under the «KYC/AML» section.
- clientKey: A unique string (max 36 characters) that must be passed encrypted; the encryption code sample is available in the personal account under the «KYC/AML» section. Since the encrypted key is base64 (it may contain
/and+), URL-encode it when building the link. - clientUser: Optional. Client’s user identifier, max 36 characters. Does not have to be unique — use the same value across sessions to later find all sessions (attempts) of that user.
For verification tasks pre-created via the API, use the task link instead:
https://kyc.enface.ai/taskId
https://kyc.enface.ai/taskId/cu/clientUser