Skip to content

Web SDK Integration ​

Setup and face scanning for FaceAuthen with the CAKE eKYC Web SDK. Executing bundle.js creates the global object window.ekyc.

Prerequisites ​

WhatDescription
Assets folderSomewhere to serve the /ekyc assets folder from.
HTTPSRequired for camera access.
WebView permissionsOn iOS WebViews, enable allowsInlineMediaPlayback.

HTML Setup ​

The container element with id cake-ekyc-sdk-container is required and must exist before initialization.

html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>FaceAuth Integration</title>
    <style>
      #cake-ekyc-sdk-container {
        width: 100%;
        height: 100vh;
        position: relative;
      }
    </style>
  </head>
  <body>
    <div class="overlay" id="cake-ekyc-sdk-container"></div>

    <script src="/ekyc/bundle.js"></script>

    <script>
      // SDK initialization code goes here
    </script>
  </body>
</html>

Initialize ​

typescript
type SDKConfigParams = {
  resourcePath?: string
  baseUrl: string
  token: string
  headers?: Record<string, string>
}
javascript
const sdk = await window.ekyc.initialize('cake-ekyc-sdk-container', {
  baseUrl: '<BASE_URL>',
  token: '<ACCESS_TOKEN>',
  resourcePath: '/ekyc/resources',
  headers: {
    'X-Client-Version': '1.0.0',
    'X-Platform': 'web'
  }
})
javascript
async function initializeSDK() {
  try {
    const container = document.getElementById('cake-ekyc-sdk-container');
    if (!container) {
      throw new Error('SDK container element not found');
    }

    if (!window.ekyc) {
      throw new Error('eKYC SDK not loaded. Ensure bundle.js is included.');
    }

    return await window.ekyc.initialize('cake-ekyc-sdk-container', {
      baseUrl: '<BASE_URL>',
      token: await fetch('/your-backend/ekyc-token').then((r) => r.text()), // fetched at runtime, never bundled
      resourcePath: '/ekyc/resources'
    });
  } catch (error) {
    console.error('SDK initialization failed:', error);
    throw error;
  }
}

Scan a Face ​

javascript
// New-to-Bank customer — first enrolment
const enrolResult = await window.ekyc.scanStart(['face'], {
  isNTB: true,
  faceauthClientId: 'user_00000001',
  faceauthRefId: 'ref_00000001'
})

// Returning customer — authentication
const authResult = await window.ekyc.scanStart(['face'], {
  isNTB: false,
  faceauthClientId: 'user_00000001',
  faceauthRefId: 'ref_00000001'
})

Parameters:

ParamTypeRequiredDefaultDescription
typesstring[]Yes—Pass ['face'] for a FaceAuthen flow.
opts.isNTBbooleanNo—true for a first enrolment, false to authenticate an existing profile.
opts.faceauthClientIdstringNo—Client ID for face authentication.
opts.faceauthRefIdstringNo—Reference ID for face authentication.
opts.timeoutDurationnumberNo—Timeout in milliseconds.

Response ​

typescript
interface FaceScanResult {
  faces: FaceData[];
  sanityResult: SanityResult[];
  livenessResult: LivenessResult;
}
FieldTypeDescription
facesFaceData[]Captured faces, each with image and gesture (left, right, portrait).
sanityResultSanityResult[]Portrait sanity verdict and score per image.
livenessResultLivenessResultis_live, score, per-image results and main_image_id.

Each faces[].image carries id, label, bitmap and the upload response. Take the id values and pass them as the faces array to Register Faces or Verify Face Authen.

Converting bitmaps ​

bitmap is an ImageData object with two helpers attached:

javascript
const blob   = await bitmap.toBlob('image/jpeg')
const base64 = bitmap.toBase64('image/jpeg')

Scan Status ​

javascript
const status = window.ekyc.getScanStatus()
console.log('Face scan completed:', status.faceCompleted)
FieldTypeDescription
faceCompletedbooleanWhether the face scan finished.
faceDataanyThe face scan result, populated after the scan.
timestampstringOptional timestamp.

The front, back and qrcode fields exist on the same object but stay false in a FaceAuthen flow.

Face Authentication Call ​

The class-based API exposes the verification directly, rather than going through scanStart.

typescript
const authResponse = await ekycSDK.verifyFaceAuthentication(authParams);

verifyFaces(faceImages, isFaceAuth) takes an isFaceAuth flag that switches the verification between a plain liveness check and a FaceAuthen authentication.

WARNING

Do not treat the browser's result as the decision. It runs on a device you do not control. Redeem the authentication_key from Verify Face Authen on your backend, then close the transaction with Verify Transaction Key.

Terminate ​

javascript
await ekyc.terminateScanner();

Releases the camera and cleans up. Call it when the flow ends.

INFO

The method may be exposed as terminate or terminateScanner depending on the bundle — check which your bundle exposes.

Error Handling ​

javascript
try {
  const result = await window.ekyc.scanStart(['face'], { isNTB: false })
  // Send the result to your backend; never log it — it holds biometric data.
} catch (error) {
  console.error('Scan failed:', error.message)
}

Scan responses keep the same shape on failure and put detail in the error array, with an optional sdkError carrying the SDK's own verdict. See Web SDK Overview § SDK Error Codes.

Common issues ​

WhatDescription
SDK not loadingCheck the script path and that it loads before use.
Camera accessEnsure HTTPS and that camera permissions are granted.
Container not foundVerify the container element exists in the DOM.
Network issuesCheck the internet connection and API endpoints.
typescript
if (typeof window.ekyc === 'undefined') {
    console.error('eKYC SDK not loaded');
}

navigator.mediaDevices.getUserMedia({ video: true })
    .then(stream => {
        stream.getTracks().forEach(track => track.stop());
    })
    .catch(error => {
        console.error('Camera access denied:', error);
    });

Next Steps ​

Developers