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

# KYC Widget SDK reference

> Reference for the @uphold/enterprise-kyc-widget-web-sdk package, including the KycWidget class, constructor options, methods, and lifecycle events.

Complete reference documentation for the `@uphold/enterprise-kyc-widget-web-sdk` package.

The main class for creating and managing KYC Widget instances is `KycWidget`. It requires a `KycWidgetSession` object that must be created through the API before instantiating the Widget.

## Constructor

```typescript theme={null}
new KycWidget(
  session: KycWidgetSession,
  options?: KycWidgetOptions
)
```

**Parameters:**

| Parameter | Type | Required | Description |
| - | - | - | - |
| `session` | `KycWidgetSession` | Yes | KYC session object obtained from the [Create session](/rest-apis/widgets-api/kyc/create-session) endpoint |
| `options` | `KycWidgetOptions` | No | Configuration options for the Widget. See [Options](#options) |

### Options

We recommend setting the Widget options in the [Create session](/rest-apis/widgets-api/kyc/create-session) request rather than in the constructor — see [Create a session on your backend](/widgets/kyc/installation-and-setup#1-create-a-session-on-your-backend). The constructor accepts the following options:

```typescript theme={null}
type KycWidgetOptions = {
  debug?: boolean;
  layout?: WidgetLayout;
  theme?: WidgetThemeOption;
};
```

| Property | Type | Default | Description |
| - | - | - | - |
| `debug` | `boolean` | `false` | **SDK only.** Enable verbose SDK console logging. Has no effect in the Create session request or the `init` message |
| `layout` | `WidgetLayout` | `'boxed'` | Control how the Widget is laid out on larger viewports. See [WidgetLayout](#widgetlayout) for details |
| `theme` | `WidgetThemeOption` | System preference | Control the visual appearance of the Widget. See [WidgetThemeOption](#widgetthemeoption) for details |

<Note>
  **Temporary workaround:** If you set `theme` or `layout` in Create session, also pass the same values to the constructor to avoid a brief change in appearance while the Widget loads. See [Theme and layout setup](/widgets/kyc/installation-and-setup#theme-and-layout-setup).
</Note>

**layout option:**

The `layout` option controls how the Widget is laid out when there is enough room to frame it — on viewports that are both at least `md` wide (≥768px) and at least 600px tall, i.e. tablets and up. On smaller viewports — narrower or shorter, including phones in landscape — the Widget always fills its container regardless of this option.

* `'boxed'` (default): on viewports that are ≥768px wide and ≥600px tall, centers the Widget and frames its content as a fixed-size card; on smaller viewports it fills its container. Use this when the Widget takes up the whole page (e.g. mounted into a full-page container).
* `'fluid'`: renders the Widget so it fills its container, with no frame or centering, so your own container (e.g. a modal or a sized panel) acts as the frame.

Most integrations should rely on the default `'boxed'` and only set `layout: 'fluid'` when embedding the Widget in your own framed container.

```http theme={null}
POST /widgets/kyc/sessions
{
  "flow": "verify",
  "processes": ["identity", "profile", "proof-of-address"],
  "options": {
    "layout": "fluid"
  }
}
```

<Note>Use `'fluid'` when you already provide a centered container or modal around the Widget, to avoid a card-within-a-card appearance on larger viewports.</Note>

**theme option:**

The `theme` option lets you control the visual appearance of the Widget. By default, the Widget automatically detects and matches the user's browser or OS appearance preference (`light` or `dark`). Use this option when you want to enforce a specific theme regardless of the user's system settings.

```http theme={null}
POST /widgets/kyc/sessions
{
  "flow": "verify",
  "processes": ["identity", "profile", "proof-of-address"],
  "options": {
    "theme": {
      "appearance": "dark",
      "primary": { "light": "#6200EA", "dark": "#BB86FC" }, // Or a single color for both appearances, e.g. "#6200EA"
      "fontFamily": "Inter, sans-serif",
      "components": {
        "button": { "borderRadius": "8px" }
      }
    }
  }
}
```

## Methods

### `mountIframe()`

Mounts the KYC Widget iframe to the specified DOM element.

**Parameters:**

* `element`: The HTML element where the Widget should be mounted

**Example:**

```javascript theme={null}
// Ensure the container has appropriate sizing
const container = document.getElementById('kyc-container');

widget.mountIframe(container);
```

<Info>The container element should have explicit dimensions set via CSS. The Widget will fill the entire container. Minimum recommended size is 400px width × 600px height for optimal user experience.</Info>

### `unmount()`

Unmounts and cleans up the KYC Widget iframe.

**Example:**

```javascript theme={null}
widget.unmount();
```

<Warning>The Widget will not unmount itself when a flow is finished, either by successful completion, user cancellation, or unrecoverable error, so it must always be called manually.</Warning>

### `on()`

Registers an event listener for Widget events.

**Parameters:**

* `event`: The event name to listen for
* `callback`: Function to execute when the event is triggered

**Example:**

```javascript theme={null}
widget.on('complete', () => {
  console.log('KYC completed');
});
```

### `off()`

Removes an event listener for KYC Widget events.

**Parameters:**

* `event`: The event name to stop listening for
* `callback`: The specific function to remove (must be the same reference as used in `on()`)

**Example:**

```javascript theme={null}
const handleComplete = () => {
  console.log('KYC completed');
};

// Register the listener
widget.on('complete', handleComplete);

// Remove the listener
widget.off('complete', handleComplete);
```

## Events

The KYC Widget emits several events during its lifecycle that you can listen to using the `on()` method.

### `complete`

Fired when all KYC processes have been submitted.

```typescript theme={null}
type KycWidgetCompleteEvent = {
  detail: {};
};
```

**Example:**

```javascript theme={null}
widget.on('complete', () => {
  console.log('KYC processes submitted');

  widget.unmount();
});
```

<Note>The `complete` event signals submission, not approval. Final verification outcomes are delivered asynchronously via [KYC webhooks](/rest-apis/core-api/kyc/introduction). Monitor those server-side to update your user's status.</Note>

### `cancel`

Fired when the user cancels the KYC flow.

```typescript theme={null}
type KycWidgetCancelEvent = {
  detail: {};
};
```

**Example:**

```javascript theme={null}
widget.on('cancel', () => {
  console.log('KYC cancelled by user');

  widget.unmount();
});
```

### `error`

Fired when an unrecoverable error occurs during the KYC flow.

```typescript theme={null}
type WidgetError = {
  name: string;
  code: string;
  message: string;
  details?: Record<string, unknown>;
  cause?: WidgetError; // The original underlying error, when this error wraps one
  httpStatusCode?: number;
};

type KycWidgetErrorEvent = {
  detail: {
    error: WidgetError;
  };
};
```

**Example:**

```javascript theme={null}
widget.on('error', (event) => {
  const { error } = event.detail;
  console.error('KYC error:', error.code, error.message);

  widget.unmount();
});
```

The Widget also fires `error` when it can't load its session, for example when the `sessionToken` in `session.url` is expired or invalid. Create a new session to try again.

### `ready`

Fired when the KYC Widget has finished loading.

```typescript theme={null}
type KycWidgetReadyEvent = {
  detail: {};
};
```

**Example:**

```javascript theme={null}
widget.on('ready', () => {
  console.log('KYC Widget is ready');
});
```

## Types

### KycWidgetSession

The session object returned by the [Create session](/rest-apis/widgets-api/kyc/create-session) endpoint.

```typescript theme={null}
type KycWidgetSession = {
  url: string;
};
```

Only `url` is required. It carries a `sessionToken` query parameter the Widget uses to load its session, so pass it unmodified, including its query string.

<Note>The Create session response may still include `token`, `flow`, and `data`. These fields are deprecated: the Widget loads them itself from `url`, and the SDK doesn't use them.</Note>

### WidgetLayout

Controls how the Widget is laid out on larger viewports.

```typescript theme={null}
type WidgetLayout = 'boxed' | 'fluid';
```

| Value | Description |
| - | - |
| `'boxed'` | Default. On viewports that are ≥768px wide and ≥600px tall (tablets and up), centers the Widget and frames its content as a fixed-size card; on smaller viewports it fills its container |
| `'fluid'` | Renders the Widget so it fills its container, with no frame or centering, so your own container acts as the frame |

### WidgetThemeOption

Controls the visual appearance of the Widget.

```typescript theme={null}
type WidgetThemeOption = {
  appearance?: 'light' | 'dark';
  primary?: ColorTokenValue;
  primaryForeground?: ColorTokenValue;
  foreground?: ColorTokenValue;
  emphasisForeground?: ColorTokenValue;
  background?: ColorTokenValue;
  fontFamily?: FontFamily;
  components?: {
    button?: { borderRadius?: string };
    input?: { borderRadius?: string };
    card?: { borderRadius?: string };
  };
};
```

| Property | Type | Description |
| - | - | - |
| `appearance` | `'light' \| 'dark'` | Forces light or dark mode, overriding the user's system preference |
| `primary` | `ColorTokenValue` | Primary brand color, used for buttons and key interactive elements |
| `primaryForeground` | `ColorTokenValue` | Text color rendered on top of the primary color |
| `foreground` | `ColorTokenValue` | Main text color |
| `emphasisForeground` | `ColorTokenValue` | Emphasized text color |
| `background` | `ColorTokenValue` | Widget background color |
| `fontFamily` | `FontFamily` | Font family applied across the Widget. See [FontFamily](#fontfamily) for details |
| `components` | `object` | Per-component style overrides for `button`, `input`, and `card` (each accepts `borderRadius?: string`) |

### ColorTokenValue

A color value that can be a single string applied to both light and dark modes, or separate values per mode.

```typescript theme={null}
type ColorTokenValue = string | { light: string; dark: string };
```

### FontFamily

A font family that can be a single string applied to all slots, or separate values per slot (`mono`, `sans`, `serif`).

```typescript theme={null}
type FontFamily = string | Partial<Record<'mono' | 'sans' | 'serif', string>>;
```

## Complete usage example

Here's an end-to-end example showing how to use the KYC Widget with all events:

```typescript theme={null}
import { KycWidget } from '@uphold/enterprise-kyc-widget-web-sdk';

// Create a KYC Widget session from your backend, with the Widget options in the request `options`
const session = await createKycWidgetSession();

// Initialize the Widget
const widget = new KycWidget(session, {
  debug: true // SDK only
});

// Handle ready event
widget.on('ready', () => {
  console.log('KYC Widget is ready');
});

// Handle completion (monitor final outcomes via webhooks)
widget.on('complete', () => {
  console.log('KYC processes submitted');
  widget.unmount();
});

// Handle cancellation
widget.on('cancel', () => {
  console.log('KYC cancelled by user');
  widget.unmount();
});

// Handle errors
widget.on('error', (event) => {
  console.error('KYC error:', event.detail.error);
  widget.unmount();
});

// Mount the Widget's iframe to a DOM element
widget.mountIframe(document.getElementById('kyc-container'));
```
