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

# SDKs & Widget

> Embed Vouchmark's KYB verification flow into your product with a single line of code.

The Vouchmark Widget is an embeddable verification flow that guides applicants through your configured KYB checks — CAC, TIN, bank, directors, AML screening and more — without them leaving your app.

You configure a widget in the [dashboard](https://vouchmark.com) or via the [Widget API](/api-reference/onboarding/create-widget), then integrate it client-side with one of our SDKs.

## How it works

<Steps>
  <Step title="Create a widget">
    Configure which modules to run, set branding, flow order, risk thresholds, and allowed domains from the dashboard or API.
  </Step>

  <Step title="Install the SDK">
    Add the script tag (vanilla HTML) or install the React / React Native / Flutter package.
  </Step>

  <Step title="Open the widget">
    Call `Vouchmark.open()` (or render the component) when the applicant clicks your CTA. The widget handles the entire flow.
  </Step>

  <Step title="Handle results">
    Listen for `onSuccess`, `onAbandon`, and `onError` client-side. Verify the final decision server-side via webhooks.
  </Step>
</Steps>

## Available SDKs

<CardGroup cols={2}>
  <Card title="HTML / Vanilla JS" icon="code" href="/sdks/html">
    Drop a script tag and call `Vouchmark.open()`. Zero dependencies.
  </Card>

  <Card title="React" icon="react" href="/sdks/react">
    `@vouchmark/widget-react` — a single component with full TypeScript support.
  </Card>

  <Card title="React Native" icon="mobile" href="/sdks/react-native">
    `@vouchmark/widget-react-native` — native WebView wrapper with full-screen and modal presentation.
  </Card>

  <Card title="Flutter" icon="mobile" href="/sdks/flutter">
    `vouchmark_widget` — Dart package that renders the flow in a WebView with a JavaScript bridge.
  </Card>

  <Card title="Node.js (Server)" icon="server" href="/sdks/node">
    `@vouchmark/node` — create sessions, verify webhooks, and manage widgets server-side.
  </Card>
</CardGroup>

## Widget modules

Every widget is composed of **modules** — individual checks you toggle on or off. The full catalog:

| Category                   | Modules                                                                                    |
| -------------------------- | ------------------------------------------------------------------------------------------ |
| **Business identity**      | Business profile, Industry classification                                                  |
| **Verification**           | CAC, TIN, SCUML, Tax clearance, Business licence, Address, Bank account, Operational proof |
| **People & ownership**     | Directors KYC, Shareholders KYC, Beneficial ownership, Liveness check                      |
| **Documents**              | Document vault                                                                             |
| **Screening & compliance** | AML screening, PEP screening, Sanctions screening, Adverse media                           |

See [Pricing](/pricing) for per-module costs.

## Environments

Every widget runs in one of two **widget environments**:

| Environment | Purpose                                 | Billing            |
| ----------- | --------------------------------------- | ------------------ |
| `sandbox`   | Testing — mock results, no real lookups | Free               |
| `live`      | Production — real verification lookups  | Charged per module |

When you integrate with an SDK, you pass three values that must **all refer to the same environment**:

| Value                         | Sandbox                                      | Live                                      |
| ----------------------------- | -------------------------------------------- | ----------------------------------------- |
| `environment` prop            | `"sandbox"`                                  | `"live"`                                  |
| Publishable key (`publicKey`) | `test_pk_…`                                  | `live_pk_…`                               |
| Widget ID (`widgetId`)        | Widget created with `environment: "sandbox"` | Widget created with `environment: "live"` |

<Warning>
  Mixing environments fails. A `test_pk_` key with `environment: "live"`, or a live widget ID with `environment: "sandbox"`, returns an error such as **Environment mismatch** or **Widget is live; use a live API key and widget ID**.
</Warning>

### Where to find each value

1. **Publishable key** — [Developer settings](/api-reference/developers/list-api-keys) in the dashboard. Sandbox keys start with `test_pk_`; live keys start with `live_pk_`.
2. **Widget ID** — [Onboarding → Widgets](/api-reference/onboarding/list-widgets). Each widget has an `environment` field; use an ID from the same environment as your key.
3. **`environment` prop** — Set `"sandbox"` when using `test_pk_…`, and `"live"` when using `live_pk_…`.

### API and widget hosts

| Service           | URL                            |
| ----------------- | ------------------------------ |
| API base URL      | `https://api.vouchmark.com/v1` |
| Widget embed host | `https://widget.vouchmark.com` |

The same API base URL is used for staging and production. Sandbox vs live is determined by your **credentials** (`test_pk_` / `live_pk_`, widget environment), not by a different hostname.

SDKs load the widget from `widget.vouchmark.com` by default. That page bootstraps the session against `api.vouchmark.com`.

Switch environments from the dashboard when creating widgets, or pass `environment` when opening the widget in your app.

## Security

* **Domain allowlisting** — restrict which origins can render the widget.
* **Signed requests** — optionally require an HMAC signature on the session token so only your server can initiate flows.
* **IP allowlisting** — lock down to specific server IPs for API-initiated sessions.

## Events & webhooks

The widget emits lifecycle events that you can listen to client-side:

| Event                       | When                                |
| --------------------------- | ----------------------------------- |
| `applicant.created`         | Session initialised                 |
| `applicant.started`         | Applicant begins the first module   |
| `applicant.step_completed`  | A module finishes                   |
| `applicant.submitted`       | All modules done, awaiting decision |
| `applicant.approved`        | Passed all thresholds               |
| `applicant.rejected`        | Failed risk thresholds              |
| `applicant.requires_review` | Needs manual review                 |
| `applicant.abandoned`       | User closed without finishing       |

Server-side webhook delivery is the source of truth. See [Webhooks](/webhooks).
