---
title: "Web SDK 2.0 API Reference"
url: "https://developer.incode.com/sdk-reference/web-sdk-2-reference/"
section: "sdk-reference"
group: "Incode Web SDK 2 Reference / Reference"
version: "v1.1"
status: "live"
---
# Web SDK 2.0 API Reference

:::note
This guide is specific to Web SDK 2.0. If you are still using 1.x, you can find documentation [here](/sdk-reference/web-sdk-reference).  Contact your Incode Representative for upgrade information and check if you are a candidate for this upgrade. <br /><br />Full rollout to all clients still TBD.
:::

## Setup

### setup()

Initialize the SDK before using any components.

### Which `setup()` do I call?

**You call one, never both.** Two packages export a `setup()`, and `@incodetech/web`'s version calls `@incodetech/core`'s for you:

```
your app ──▶ setup() from '@incodetech/web' ──calls──▶ setup() from '@incodetech/core'
                adds i18n, uiConfig, theme               apiURL, token, wasm, encryption, …

your app ──▶ setup() from '@incodetech/core'            (headless — the web layer is never loaded)
```

Start from what you render:

| You render                                              | Call                              | Why                                                                                |
| ------------------------------------------------------- | --------------------------------- | ---------------------------------------------------------------------------------- |
| Your own UI, driving headless managers                  | `setup()` from `@incodetech/core` | Nothing in the web layer needs configuring.                                        |
| Web components, and you have the session token          | `setup()` from `@incodetech/web`  | One call wires both layers, including language, branding, and the dashboard theme. |
| Web components, but you need `setup()` before the token | `setup()` from `@incodetech/core` | The web wrapper requires `token`; core's does not. See the trade-off below.        |

The web wrapper forwards every shared option to core unchanged, then adds the four presentation options core has no concept of: `i18n`, `uiConfig`, `flow`, and `theme`.

#### When you deliberately use core's `setup()` with web components

Two things pull integrators back to the core entry point even when they render components:

- **You want `setup()` to run before the session token exists**, so WASM warmup overlaps with your backend creating the session. Core's `apiURL` and `token` are both optional and it pairs with [`initializeSession()`](#initializesession); the web wrapper requires `token` up front.
- **You need an option the web wrapper does not accept** — `encryption`, `hostingApp`, `tri`, `trueSight`, or `videoSelfie`. End-to-end encryption is the common case; see [End-to-End Encryption](/sdk-reference/web-sdk-2-e2ee/).

That combination works, and the examples throughout these docs use it. Just wire the presentation layer yourself, because core's `setup()` cannot:

| What web's `setup()` would have done        | Do this instead                                                                                                                                                                                                                    |
| ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `i18n` — language and translations          | Call `setI18nInstance(createI18n({ lang, translations }))` from `@incodetech/web`. Text still renders without it, in English defaults. See [Internationalization](/sdk-reference/web-sdk-2-i18n/).                                             |
| `uiConfig` — logo, subtitle, assets, loader | Call `setUiConfig({ … })` from `@incodetech/web`. See [Theming & Styling](/sdk-reference/web-sdk-2-theming/).                                                                                                                                  |
| `theme` — the dashboard theme               | `<incode-flow>` and `<incode-workflow>` fetch it themselves from their `config.token`, so they are unaffected. **Standalone module components do not** — they render unbranded. Apply your branding through `setUiConfig` instead. |
| `flow` — Flow-backed standalone config      | Core accepts `flow`, but `preload` and `mergeConfig` only take effect through the web wrapper. See [Individual Modules](/sdk-reference/web-sdk-2-individual-modules/).                                                                         |

The silent case is worth repeating: a standalone `<incode-selfie>` or `<incode-id>` set up through core skips the dashboard theme with no error. If your branding comes from the Incode dashboard rather than `setUiConfig`, use the web `setup()`.

#### setup() from `@incodetech/core`

```typescript
import { setup } from '@incodetech/core';

await setup({
  apiURL?: string;                                     // API base URL
  token?: string;                                      // Session token (one-shot convenience — delegates to initializeSession)
  customHeaders?: Record<string, string>;
  timeout?: number;                                    // Request timeout (ms). No deadline when omitted.
  wasm?: WasmConfig | false;                           // WASM warmup (see WASM Configuration)
  encryption?: boolean | { mgf1?: 'sha1' | 'sha256' }; // End-to-end encryption (locked at boot)
  hostingApp?: string;                                 // Optional fingerprint hosting-app identifier
  ipLookup?: boolean;                                  // Default true. Set false to skip the third-party IP lookup (api.ipify.org).
  fingerprint?: boolean;                               // Default true. Set false to skip device-fingerprint submission (transition flag).
  flow?: false | { preload?: boolean; mergeConfig?: boolean }; // Flow-backed config for standalone modules
  devMode?: boolean;                                   // Default false. Set true in local development to silence the devtools detector.
  tri?: { token: string; apiURL: string; autostart?: boolean }; // Optional TRI telemetry config
  trueSight?: { enabled?: boolean };                   // Default enabled. Set { enabled: false } to opt out of diagnostics.
  featureManagement?: boolean | FeatureManagementSetupOptions; // Default true. Set false to opt out entirely.
  environment?: 'development' | 'staging' | 'production';      // Default 'production'. Feature-management targeting only.
});
```

The canonical activation pattern is two calls — `setup({ apiURL })` first, then `initializeSession({ token })` once the session token is known. See [`initializeSession()`](#initializesession) below. Passing `token` to `setup` is a one-shot convenience that delegates to `initializeSession` internally.

| Option              | Type                                                     | Required | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| ------------------- | -------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `apiURL`            | `string`                                                 | ❌        | API base URL. Omit when every API actor is overridden via `.provide()` (advanced).                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `token`             | `string`                                                 | ❌        | Session token. One-shot convenience that delegates to `initializeSession({ token, hostingApp })`. Prefer the explicit two-call form: `setup({ apiURL })` then [`initializeSession({ token })`](#initializesession). The two-call form lets you start `setup` (including WASM warmup) before the token is known.                                                                                                                                                                                                                             |
| `customHeaders`     | `Record<string, string>`                                 | ❌        | Headers to attach to every SDK request.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `timeout`           | `number`                                                 | ❌        | Request timeout in milliseconds. **There is no default deadline** — omit it and a request runs until it succeeds, fails at the network layer, or the API gateway ends it. That keeps large uploads alive on slow mobile connections, where a fixed timeout cut them off mid-transfer. Set this when your integration needs a bounded request.                                                                                                                                                                                               |
| `wasm`              | `WasmConfig \| false`                                    | ❌        | WASM warmup. Omit to skip preload (loads lazily on first selfie/ID capture). Pass an object to warm up with CDN defaults plus any overrides. Pass `false` to explicitly disable. See [WASM Configuration](/sdk-reference/web-sdk-2-wasm/).                                                                                                                                                                                                                                                                                                              |
| `encryption`        | `boolean \| { mgf1?: 'sha1' \| 'sha256' }`               | ❌        | Enable end-to-end encryption for SDK traffic. Independent of `token` — can be enabled before a session token is known. Not a self-serve flag — your Incode account team provisions the environment and gives you the dedicated `apiURL` and `mgf1` scheme. Locked at boot (call `reset()` to change later) and requires the WASM binary transport. See [End-to-End Encryption](/sdk-reference/web-sdk-2-e2ee/) for the full walkthrough including API-key transmission, MGF1 schemes, and failure modes.                                                |
| `hostingApp`        | `string`                                                 | ❌        | Hosting app identifier forwarded to the fingerprinting service.                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `ipLookup`          | `boolean`                                                | ❌        | Controls the third-party public-IP lookup (`api.ipify.org`). Default `true` (lookup enabled). Set `false` to opt out — no external call to ipify, at the cost of a less-precise fingerprint. Privacy-friendly for deployments where outbound calls to third-party services are restricted.                                                                                                                                                                                                                                                  |
| `fingerprint`       | `boolean`                                                | ❌        | Controls client-side device-fingerprint submission (`POST /omni/add/device-fingerprint`). Default `true`. Set `false` to skip it entirely — also blanks the fingerprint hash captured during selfie/ID/authentication verification. **Transition flag:** with `fingerprint: false`, the SDK does not auto-inject the mandatory-consent step in `flow`/`workflow` (no regulation data to base it on) — handle consent yourself if this applies to your integration.                                                                          |
| `devMode`           | `boolean`                                                | ❌        | Disables the browser devtools detector for local development. Default `false`. Set `true` only during local development — the detector feeds an anti-fraud signal and must stay on in production. **Do not ship `devMode: true`.** WASM console logging is a separate flag (`wasm.showLogs`). See [WASM Configuration](/sdk-reference/web-sdk-2-wasm/).                                                                                                                                                                                        |
| `tri`               | `{ token: string; apiURL: string; autostart?: boolean }` | ❌        | Transactional Risk Intelligence (TRI) telemetry. Provide `token` (a short-lived SDK token from `createTRISession`, not the org API key) and `apiURL` (the TRI ingest endpoint). TRI starts automatically unless `autostart: false` — use `false` to defer collection until after a consent gate, then call `startTRI()` from `@incodetech/core/tri`. Omitting this field opts out; no collectors start.                                                                                                                                     |
| `flow`              | `false \| { preload?: boolean; mergeConfig?: boolean }`  | ❌        | Controls whether standalone modules resolve their configuration from your dashboard Flow. Omit it (or pass `{}`) for lazy resolution on mount. `preload: true` fetches Flow during `setup()`. `mergeConfig: true` merges the config you supply over the Flow config. `false` disables Flow-backed resolution. See [Individual Modules](/sdk-reference/web-sdk-2-individual-modules/) for the full matrix.                                                                                                                                               |
| `trueSight`         | `{ enabled?: boolean }`                                  | ❌        | Incode-internal SDK-health diagnostics, used to debug capture issues you report. **Enabled by default.** During a session the SDK buffers sanitized diagnostic breadcrumbs — no personal data and no captured images — and uploads a single encrypted record when the session ends. Fire-and-forget: it never blocks or affects your flow. Set `{ enabled: false }` to opt out entirely. Incode can also disable collection remotely. The value is fixed by the first `setup()` of the lifecycle; call `reset()` to change it.              |
| `featureManagement` | `boolean \| FeatureManagementSetupOptions`               | ❌        | Controls the feature-management integration, which decides gate and experiment values for the session. **Enabled by default**, loaded as a separate chunk, and served by a third party — see [Third-Party Dependencies](/sdk-reference/web-sdk-2-third-party-dependencies/). Pass `false` for a full opt-out: no chunk, no feature-management network traffic. Reads from `@incodetech/core/feature-management` keep working when disabled and resolve to their defaults. Only the first enabling `setup()` initializes it. See the option table below. |
| `environment`       | `'development' \| 'staging' \| 'production'`             | ❌        | Coarse deployment tier used for feature-management targeting, with no finer granularity. Default `'production'`. Read by the first enabling `setup()` only, and inert when `featureManagement` is `false`.                                                                                                                                                                                                                                                                                                                                  |

##### `FeatureManagementSetupOptions`

Pass this object form instead of `true` to configure identity and privacy. The defaults are already conservative: no customer API key is used, and identity starts from an SDK-generated ID rather than anything you supply.

| Option               | Type                                | Default                  | Description                                                                                                                                                                                             |
| -------------------- | ----------------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `clientExperimentId` | `string`                            | —                        | Integrator-scoped targeting unit, agreed with your Incode representative. Use it to bucket gates for one integrator, such as a pilot rollout.                                                           |
| `disableStableId`    | `boolean`                           | `false`                  | Stops the integration generating a per-user ID at all. The strongest privacy control — evaluations resolve to control values until session identity arrives later in the flow.                          |
| `disablePersistence` | `boolean`                           | `false`                  | Keeps identity in memory only, so it is never linkable across page loads. Trades away the local bootstrap cache, so every session fetches on boot.                                                      |
| `custom`             | `Record<string, unknown>`           | —                        | Attributes attached for targeting rules and analytics. They do not bucket experiments. Keep personal data and secrets out — these reach the provider's logs as-is.                                      |
| `redactedUserInfo`   | `FeatureManagementRedactedUserInfo` | `ip`, `country` redacted | Which auto-collected fields to blank before they leave the browser. IP address and country are redacted by default; pass `false` for either to send it, or `true` for another field to redact that too. |

#### setup() from `@incodetech/web`

Use this one with the web components. `apiURL` and `token` are both required here, so create the session before you call it.

```typescript
import { setup } from '@incodetech/web';

await setup({
  apiURL: string;                                    // Required
  token: string;                                     // Required: session token from createSession()
  customHeaders?: Record<string, string>;
  timeout?: number;
  wasm?: WasmConfig | false;
  ipLookup?: boolean;
  fingerprint?: boolean;
  devMode?: boolean;
  featureManagement?: boolean | FeatureManagementSetupOptions;
  environment?: 'development' | 'staging' | 'production';
  i18n?: I18nOptions;                                // Language and translation overrides
  uiConfig?: UiConfig;                               // Logo, subtitle, asset/animation and loader overrides
  flow?: false | { preload?: boolean; mergeConfig?: boolean };
  theme?: false | { preload?: boolean };             // Dashboard theme, independent of flow
});
```

| Option                                                                                                               | Type                             | Required | Description                                                                                                                                                                                                                 |
| -------------------------------------------------------------------------------------------------------------------- | -------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `apiURL`                                                                                                             | `string`                         | ✅        | API base URL.                                                                                                                                                                                                               |
| `token`                                                                                                              | `string`                         | ✅        | Session token from `createSession()`. Unlike the core `setup()`, the web wrapper needs it up front.                                                                                                                         |
| `i18n`                                                                                                               | `I18nOptions`                    | ❌        | Language selection and translation overrides. See [Internationalization](/sdk-reference/web-sdk-2-i18n/).                                                                                                                               |
| `uiConfig`                                                                                                           | `UiConfig`                       | ❌        | Global branding and presentation: logo, subtitle, asset and animation overrides, loader presentation. See [Asset Overrides](/sdk-reference/web-sdk-2-asset-overrides/) and [Theming & Styling](/sdk-reference/web-sdk-2-theming/).                  |
| `theme`                                                                                                              | `false \| { preload?: boolean }` | ❌        | Controls the dashboard theme independently of `flow`. Omit for lazy loading, `{ preload: true }` to fetch and apply during `setup()`, or `false` to disable it. See [Individual Modules](/sdk-reference/web-sdk-2-individual-modules/). |
| `customHeaders`, `timeout`, `wasm`, `ipLookup`, `fingerprint`, `devMode`, `featureManagement`, `environment`, `flow` | same as core                     | ❌        | Forwarded to the core `setup()` unchanged — see the table above.                                                                                                                                                            |

### createSession()

Create a verification session (call from your backend for production):

```typescript
import { createSession } from '@incodetech/core/session';

const session = await createSession(apiKey, {
  configurationId: string;   // Required: Flow configuration ID from dashboard
  language?: string;         // Optional: Language code (e.g., 'en-US')
  externalId?: string;       // Optional: Your user reference ID
});

// Returns: { token: string; interviewId: string; ... }
```

### initializeSession()

Activate a session by attaching the token to the HTTP client and pre-loading session-scoped state (feature flags, device fingerprint, analytics flush). Call once you have a session token — typically right after `createSession()` (or after your backend returns the token).

```typescript
import { initializeSession } from '@incodetech/core/session';

await initializeSession({
  token: string;            // Required in application code: the session token from createSession()
  hostingApp?: string;      // Optional: hosting-app identifier forwarded to fingerprinting
  signal?: AbortSignal;     // Optional: abort the activation (e.g. on unmount)
});

// Returns: { features, disableIpify, fingerprintSuccess, fingerprintResult }
```

| Option       | Type          | Required | Description                                                                                                                                                                                                                                                                                                                                  |
| ------------ | ------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `token`      | `string`      | ✅        | Session token returned by `createSession()`. Application code should always pass this explicitly.                                                                                                                                                                                                                                            |
| `hostingApp` | `string`      | ❌        | Hosting-app identifier forwarded to the fingerprinting service.                                                                                                                                                                                                                                                                              |
| `signal`     | `AbortSignal` | ❌        | Cancellation signal — useful for unmount-aborts in single-page apps.                                                                                                                                                                                                                                                                         |

Results are cached per token: calling `initializeSession` again with the same token is a no-op; calling with a different token resets the cache and re-initializes from scratch. Idempotent across concurrent callers — a second in-flight call with the same arguments awaits the first.

## Feature management

`@incodetech/core/feature-management` is the read surface for the gates, experiments, layers, and dynamic configs evaluated for the current session. The SDK handles initialization and identity itself during `setup()` and session activation — this subpath only reads. It ships as a separate subpath so integrations that never read a gate do not pay for it.

Incode agrees the gate and experiment keys with you; they are not self-serve.

```typescript
import {
  getFeatureGate,
  getExperiment,
  getLayer,
  getFeatureDynamicConfig,
  subscribeFeatureManagement,
} from '@incodetech/core/feature-management';

if (getFeatureGate('your_gate_key').enabled) {
  // gated behavior
}

const experiment = getExperiment('your_experiment_key');
const variant = experiment.get('variantName', 'control');

const layer = getLayer('your_layer_key');
const timeoutMs = layer.get('timeoutMs', 10_000);
```

| Function                               | Returns                           | Description                                                                  |
| -------------------------------------- | --------------------------------- | ---------------------------------------------------------------------------- |
| `getFeatureGate(key)`                  | `FeatureManagementGate`           | Reads a boolean gate. Check `.enabled`.                                      |
| `getExperiment(key)`                   | `FeatureManagementExperiment`     | Reads an experiment. Call `.get(param, fallback)` per parameter.             |
| `getLayer(key)`                        | `FeatureManagementLayer`          | Reads a layer. Call `.get(param, fallback)` per parameter.                   |
| `getFeatureParameterStore(key, opts?)` | `FeatureManagementParameterStore` | Reads a parameter store.                                                     |
| `getFeatureDynamicConfig(key)`         | object or `null`                  | Reads a dynamic config.                                                      |
| `subscribeFeatureManagement(fn)`       | unsubscribe function              | Notifies you when values change during the session, as identity is enriched. |
| `updateFeatureManagementUser(update)`  | `void`                            | Adds your own custom IDs to the evaluation identity.                         |
| `getIsFeatureManagementInitialized()`  | `boolean`                         | Whether initialization has finished.                                         |
| `logEvent(...)`                        | `void`                            | Records a custom event against the current identity.                         |

**Every function here is graceful and none of them throw.** Before `setup()` finishes, and whenever `setup({ featureManagement: false })` disabled the integration, reads resolve to documented defaults: gates return `false`, experiments and layers return your fallback, and dynamic configs return `null`. Code that reads a gate stays correct with the integration switched off, so you can disable it without branching.

## Components

### `<incode-flow>`

Complete verification flow as a standard Web Component.

```ts
// Side-effect import registers the custom element
import '@incodetech/web/flow';
import '@incodetech/web/flow/styles.css';
```

| Property   | Type                                                       | Required | Description                 |
| ---------- | ---------------------------------------------------------- | -------- | --------------------------- |
| `config`   | `FlowConfig`                                               | ✅        | Flow configuration object   |
| `onFinish` | `(result?: FinishStatus) => void`                          | ✅        | Called when flow completes  |
| `onError`  | `(error: string \| undefined, errorCode?: number) => void` | ❌        | Called when an error occurs |

#### FlowConfig

`apiURL` is configured via `setup()`, not in `FlowConfig`.

| Property                                     | Type                            | Required | Description                                                                    |
| -------------------------------------------- | ------------------------------- | -------- | ------------------------------------------------------------------------------ |
| `token`                                      | `string`                        | ✅        | Session token from `createSession()` (token-based variant)                     |
| `apiKey` (or `clientId`) + `configurationId` | `string`                        | ✅ (alt)  | Self-loading variant — component creates its own session. Avoid in production. |
| `lang`                                       | `string`                        | ❌        | Language code (e.g. `'en-US'`)                                                 |
| `enableHome`                                 | `boolean`                       | ❌        | Show the SDK's built-in home screen                                            |
| `authHint`                                   | `string`                        | ❌        | QR/auth hint when re-entering a flow                                           |
| `urlUuid`                                    | `string`                        | ❌        | QR anti-phishing token from URL                                                |
| `wasmConfig`                                 | `WasmConfig`                    | ❌        | WASM configuration for ML features                                             |
| `spinnerConfig`                              | `SpinnerConfig`                 | ❌        | Loading spinner customization                                                  |
| `disableDashboardTheme`                      | `boolean`                       | ❌        | Disable dashboard theme                                                        |
| `onFlowEvent`                                | `(event: FlowEvent) => void`    | ❌        | Curated flow milestones                                                        |
| `onModuleLoading`                            | `(moduleKey: string) => void`   | ❌        | Called when module starts loading                                              |
| `onModuleLoaded`                             | `(moduleKey: string) => void`   | ❌        | Called when module finishes loading                                            |
| `onWasmWarmup`                               | `(pipelines: string[]) => void` | ❌        | Called when WASM warmup begins                                                 |
| `onUrlUuidRefreshed`                         | `(urlUuid: string) => void`     | ❌        | New `urlUuid` available                                                        |

### Other components

The SDK ships 20+ web components in addition to `IncodeFlow` — selfie, ID capture, phone, email, signature, consent, eKYC/eKYB orchestrators, and more. Rather than duplicate them here, see:

- [Individual Modules](/sdk-reference/web-sdk-2-individual-modules/): complete catalog of every web component and headless manager with import paths
- [Web Components](/sdk-reference/web-sdk-2-web-components/): tag-table reference for vanilla / framework-agnostic usage
- [Module: Selfie](/sdk-reference/web-sdk-2-module-selfie-1/), [Module: ID](/sdk-reference/web-sdk-2-module-id-capture/), [Module: Phone](/sdk-reference/web-sdk-2-module-phone/), [Module: Email](/sdk-reference/web-sdk-2-module-email/): deep-dive reference pages for the four most-used capture modules, including config tables, state machines, and full API surfaces

## Headless Managers

Every module ships a corresponding `createXxxManager` factory for headless integrations. The full catalog (manager name, core import, what it does) lives in [Individual Modules](/sdk-reference/web-sdk-2-individual-modules/); detailed lifecycle, state, and method documentation for each manager lives in [Headless Mode](/sdk-reference/web-sdk-2-headless-mode/).

For the four most-used headless APIs, see:

- [Module: Selfie § API Methods](/sdk-reference/web-sdk-2-module-selfie-1/#api-methods)
- [Module: ID § API Methods](/sdk-reference/web-sdk-2-module-id-capture/#api-methods)
- [Module: Phone § API Methods](/sdk-reference/web-sdk-2-module-phone/#api-methods)
- [Module: Email § API Methods](/sdk-reference/web-sdk-2-module-email/#api-methods)

## See Also

- [TypeScript Types](/sdk-reference/web-sdk-2-typescript-types/): Type definitions
- [Headless Mode](/sdk-reference/web-sdk-2-headless-mode/): Detailed headless API
- [Individual Modules](/sdk-reference/web-sdk-2-individual-modules/): Complete module catalog