> ## Documentation Index
> Fetch the complete documentation index at: https://docs.smartcomply.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Web SDK

> Integrate Adhere identity verification and liveness detection into your web applications using the SmartComply Web SDK.

# Adhere Web SDK

The Adhere Web SDK enables you to rapidly and securely verify user identities and perform facial liveness checks directly in your web applications.

The SDK mounts a drop-in widget over your application, handling document capture, identity verification, and liveness detection — all in one seamless flow.

## Features

* **Drop-in UI Modal** — Responsive, animated widget that overlays your app via `SmartComplyFlow.open()`.
* **CDN & npm Support** — Install via npm/yarn or load directly from a CDN with zero build steps.
* **Dynamic Routing** — Automatically adapts document and verification requirements from your dashboard configuration.
* **One-Time Use Policy** — Each `clientId` is single-use to prevent duplicate verifications.
* **Nigeria & Global Identity** — Supports BVN, NIN, and International Passport verification.
* **Hardware Agnostic Liveness** — Uses native webcam and MediaRecorder API for cross-platform compatibility.

***

## Installation

### Option 1 — CDN (No build step required)

Add the script tag to your HTML:

```html theme={null}
<!-- Always latest version -->
<script src="https://cdn.jsdelivr.net/npm/smartcomply-web-sdk@latest/dist/smartcomply.browser.js"></script>

<!-- Or pin to a specific version (recommended for production) -->
<script src="https://cdn.jsdelivr.net/npm/smartcomply-web-sdk@1.0.19/dist/smartcomply.browser.js"></script>
```

The SDK is available globally as `window.SmartComplySDK`:

```javascript theme={null}
const { SmartComplyFlow, SmartComply } = window.SmartComplySDK;
```

<Tip>
  Pin to a specific version in production (e.g. `@1.0.19`) to avoid unexpected breaking changes.
</Tip>

### Option 2 — npm / yarn

```bash theme={null}
npm install smartcomply-web-sdk
# or
yarn add smartcomply-web-sdk
```

```javascript theme={null}
import { SmartComplyFlow } from 'smartcomply-web-sdk';
```

***

## Quick Start — Drop-in Widget (Recommended)

The easiest way to integrate is the drop-in widget. It handles the complete verification flow automatically.

```javascript theme={null}
SmartComplyFlow.open({
  apiKey: "your_api_key_here",
  clientId: "your_client_id_here",
  environment: "production", // "production" or "sandbox"

  onComplete: (result) => {
    console.log("Verification complete:", result);
    // result = { entryId, sessionId, status, submittedAt }
  },
  onError: (error) => {
    console.error("Verification failed:", error);
  },
  onClose: () => {
    console.log("Widget closed.");
  }
});
```

<Note>
  Get your **API Key** and generate a **Client ID** from your [Adhere Dashboard](https://adhere.smartcomply.com). Each `clientId` is single-use and tied to one verification session.
</Note>

### Configuration Parameters

| Parameter     | Type     | Required | Description                                             |
| ------------- | -------- | -------- | ------------------------------------------------------- |
| `apiKey`      | string   | ✅ Yes    | Your API key from the Adhere Dashboard                  |
| `clientId`    | string   | ✅ Yes    | Single-use client ID generated per user                 |
| `environment` | string   | No       | `"production"` or `"sandbox"` (default: `"sandbox"`)    |
| `onComplete`  | function | No       | Callback fired when verification completes successfully |
| `onError`     | function | No       | Callback fired on error                                 |
| `onClose`     | function | No       | Callback fired when the widget is closed                |

### Environment URLs

| Environment  | Base URL                             |
| ------------ | ------------------------------------ |
| `production` | `https://adhere-api.smartcomply.com` |
| `sandbox`    | `https://dev-adhere.smartcomply.com` |

***

## Framework Examples

### React

```jsx theme={null}
import { SmartComplyFlow } from 'smartcomply-web-sdk';

export default function VerifyButton() {
  const handleVerify = () => {
    SmartComplyFlow.open({
      apiKey: process.env.REACT_APP_API_KEY,
      clientId: process.env.REACT_APP_CLIENT_ID,
      environment: "production",
      onComplete: (result) => console.log("Done:", result),
      onError: (err) => console.error("Error:", err),
    });
  };

  return <button onClick={handleVerify}>Verify Identity</button>;
}
```

### Vue

```vue theme={null}
<template>
  <button @click="handleVerify">Verify Identity</button>
</template>

<script setup>
import { SmartComplyFlow } from 'smartcomply-web-sdk';

const handleVerify = () => {
  SmartComplyFlow.open({
    apiKey: import.meta.env.VITE_API_KEY,
    clientId: import.meta.env.VITE_CLIENT_ID,
    environment: "production",
    onComplete: (result) => console.log("Done:", result),
    onError: (err) => console.error("Error:", err),
  });
};
</script>
```

### Plain HTML (CDN)

```html theme={null}
<!DOCTYPE html>
<html>
<head>
  <script src="https://cdn.jsdelivr.net/npm/smartcomply-web-sdk@1.0.19/dist/smartcomply.browser.js"></script>
</head>
<body>
  <button onclick="startVerification()">Verify Identity</button>

  <script>
    const { SmartComplyFlow } = window.SmartComplySDK;

    function startVerification() {
      SmartComplyFlow.open({
        apiKey: "your_api_key_here",
        clientId: "your_client_id_here",
        environment: "production",
        onComplete: (result) => console.log("Done:", result),
        onError: (err) => console.error("Error:", err),
      });
    }
  </script>
</body>
</html>
```

***

## Headless API (Advanced)

For full control over the UI, use the `SmartComply` class directly without the modal.

```typescript theme={null}
import { SmartComply } from 'smartcomply-web-sdk';

const sdk = new SmartComply({
  apiKey: "your_api_key_here",
  clientId: "your_client_id_here",
  environment: "production",
});

const run = async () => {
  // 1. Create a session
  await sdk.createSession();

  // 2. Fetch SDK configuration
  const config = await sdk.initializeConfig();
  console.log("Verification type:", config.verification_type);

  // 3. Verify identity (BVN/NIN/Passport)
  await sdk.onboarding.verify({
    identity_type_id: 1,  // from config.channels
    fields: { bank_verification_number: "12345678901" }
  });

  // 4. Run liveness check — requires an HTMLElement container for the camera
  const container = document.getElementById("camera-container") as HTMLElement;
  const liveness = await sdk.liveness.startCheck(container, {
    identifier: "user-unique-id",
    identifier_type: "bvn",
    country: "NG",
  });
  console.log("Liveness status:", liveness.status);
};

run();
```

***

## onComplete Payload

```json theme={null}
{
  "entryId": 365,
  "sessionId": "da7623bd-9158-4b56-a9e4-4bccf3c0133f",
  "status": "passed",
  "submittedAt": "2026-06-05T23:11:22.873161+00:00"
}
```

***

## Security Notes

* **Single-use Client IDs** — Each `clientId` expires immediately after a completed verification. Generate a fresh one per user session from your backend.
* **API Key** — Never expose your API key in client-side code in production. Use environment variables.
* **Session Tokens** — Session tokens are automatically managed by the SDK and expire after 30 minutes.

***

## Troubleshooting

| Error                    | Cause                           | Fix                                         |
| ------------------------ | ------------------------------- | ------------------------------------------- |
| `CLIENT_ID_ALREADY_USED` | `clientId` was already used     | Generate a new `clientId` from your backend |
| `SESSION_EXPIRED`        | Session exceeded 30 min timeout | Call `createSession()` again                |
| `401 Unauthorized`       | Invalid or missing API key      | Check your `apiKey` value                   |
| `Camera not available`   | Browser blocked camera access   | Ensure HTTPS and camera permissions granted |
