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

# Web SDK

> Initialize the Userplane SDK, open recording flows programmatically, and query recording state

The `@userplane/sdk` package provides a JavaScript API for integrating Userplane into your web application. Use it to initialize the SDK, programmatically trigger recording flows, query recording state, and attach custom metadata.

For most setups, you only need the embed script (see [Installation](/developer/installation)). The SDK package is for when you need programmatic control — for example, triggering a recording from a button in your app or attaching user-specific metadata.

## Installation

<CodeGroup>
  ```bash npm theme={null}
  npm install @userplane/sdk
  ```

  ```bash yarn theme={null}
  yarn add @userplane/sdk
  ```

  ```bash pnpm theme={null}
  pnpm add @userplane/sdk
  ```

  ```bash bun theme={null}
  bun add @userplane/sdk
  ```
</CodeGroup>

## Initialization

### `initialize(options?)`

Initializes the Userplane SDK. Call this once when your application loads. Subsequent calls are ignored.

```javascript theme={null}
import { initialize } from '@userplane/sdk';

initialize({
  workspaceId: 'ws_abc123',
});
```

#### Parameters

| Parameter | Type                | Default | Description                      |
| --------- | ------------------- | ------- | -------------------------------- |
| `options` | `InitializeOptions` | `{}`    | Configuration options (optional) |

#### `InitializeOptions`

| Property                  | Type                                                  | Default                                       | Description                                                                                                                                                       |
| ------------------------- | ----------------------------------------------------- | --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `workspaceId`             | `string \| string[]`                                  | Read from `<meta name="userplane:workspace">` | Your workspace ID. Can be a single ID or an array for multi-workspace setups.                                                                                     |
| `openImmediately`         | `boolean \| string`                                   | `true`                                        | Controls auto-open behavior. `true`: auto-open when recording URL params are detected. `false`: don't auto-open. `string`: a recording token to open immediately. |
| `captureEnabled`          | `boolean`                                             | `true`                                        | Whether to mount the background capture iframe for collecting console logs and network requests.                                                                  |
| `parseUserplaneData`      | `(href: string) => SerializableUserplaneData \| null` | Built-in parser                               | Custom function to parse `userplane-action` and `userplane-token` from the URL. Use this if your app uses non-standard URL routing.                               |
| `applyUserplaneData`      | `(data: SerializableUserplaneData) => string`         | Built-in handler                              | Custom function for applying Userplane data to the URL, used during cross-tab sync.                                                                               |
| `excludeCaptureEndpoints` | `string[]`                                            | `[]`                                          | URLs to exclude from network log capture. Merged with Userplane's internal endpoints. Useful for filtering out auth, payment, or analytics calls.                 |

#### Examples

**Basic initialization:**

```javascript theme={null}
import { initialize } from '@userplane/sdk';

initialize({
  workspaceId: 'ws_abc123',
});
```

**Disable auto-open (manual control):**

```javascript theme={null}
initialize({
  workspaceId: 'ws_abc123',
  openImmediately: false,
});

// Later, open the recorder manually
document.getElementById('record-btn').addEventListener('click', () => {
  open();
});
```

**Open with a specific recording token:**

```javascript theme={null}
initialize({
  workspaceId: 'ws_abc123',
  openImmediately: 'rec_token_xyz',
});
```

**Multiple workspaces:**

```javascript theme={null}
initialize({
  workspaceId: ['ws_abc123', 'ws_def456'],
});
```

## Recorder control

### `open(token?)`

Opens the recording flow for the user. Returns `true` if the recorder was opened, `false` otherwise (e.g. if the SDK is not initialized or the recorder is already mounted).

| Parameter | Type     | Default         | Description                                                                                |
| --------- | -------- | --------------- | ------------------------------------------------------------------------------------------ |
| `token`   | `string` | From URL params | Recording token. If omitted, the SDK uses the token from the current URL query parameters. |

Returns: `boolean`

```javascript theme={null}
import { open } from '@userplane/sdk';

// Open using token from URL params
open();

// Open with a specific token
open('rec_token_xyz');
```

### `unmount()`

Closes and unmounts the recorder. If background capture is enabled, the capture iframe is re-mounted after the recorder is removed.

```javascript theme={null}
import { unmount } from '@userplane/sdk';

unmount();
```

### `isInitialized()`

Returns `true` if the SDK has been initialized.

```javascript theme={null}
import { isInitialized } from '@userplane/sdk';

if (isInitialized()) {
  // SDK is ready
}
```

### `isRecorderMounted()`

Returns `true` if the recorder is currently mounted and visible.

```javascript theme={null}
import { isRecorderMounted } from '@userplane/sdk';

if (isRecorderMounted()) {
  // Recorder is open
}
```

## Recording state

### `getRecordingState()`

Returns the current recording state.

Returns: `RecordingState` — one of `'inactive'`, `'active'`, or `'retained'`

| State      | Description                                                           |
| ---------- | --------------------------------------------------------------------- |
| `inactive` | No recording is in progress                                           |
| `active`   | A recording is currently in progress                                  |
| `retained` | A recording session exists but the recorder is not actively recording |

```javascript theme={null}
import { getRecordingState } from '@userplane/sdk';

const state = getRecordingState();

if (state === 'active') {
  // Show a "recording in progress" indicator
}
```

### `getRecordingContext()`

Returns the full recording context, or `null` if no context is available.

Returns: `RecordingContext | null`

```typescript theme={null}
interface RecordingContext {
  state: RecordingState;
  sessionInfo: RecordingSessionInfo | null;
  tabUnloadEnabled: boolean;
}

interface RecordingSessionInfo {
  workspaceId: string;
  sessionId: string;
  linkId?: string;
}
```

```javascript theme={null}
import { getRecordingContext } from '@userplane/sdk';

const context = getRecordingContext();

if (context?.sessionInfo) {
  console.log('Session:', context.sessionInfo.sessionId);
  console.log('Link:', context.sessionInfo.linkId);
}
```

### `getSessionId()`

Returns the current recording session ID, or `null` if no session is active.

Returns: `string | null`

```javascript theme={null}
import { getSessionId } from '@userplane/sdk';

const sessionId = getSessionId();
```

### `getLinkId()`

Returns the recording link ID for the current session, or `null` if no session is active.

Returns: `string | null`

```javascript theme={null}
import { getLinkId } from '@userplane/sdk';

const linkId = getLinkId();
```

## Tab management

### `getTabRef()`

Returns the unique tab reference for this browser tab. This is persisted in `sessionStorage` for the lifetime of the tab and is used internally to manage cross-tab recording state.

Returns: `string | null`

```javascript theme={null}
import { getTabRef } from '@userplane/sdk';

const tabRef = getTabRef();
```

### `clearTabRef()`

Clears the tab reference from `sessionStorage`. A new reference is generated on the next initialization.

```javascript theme={null}
import { clearTabRef } from '@userplane/sdk';

clearTabRef();
```

## Connection state

### `isBridgeConnected()`

Returns `true` if the bridge connection between the SDK and the recorder iframe is established. Useful for debugging integration issues.

Returns: `boolean`

```javascript theme={null}
import { isBridgeConnected } from '@userplane/sdk';

if (!isBridgeConnected()) {
  console.warn('Userplane bridge not connected');
}
```

## HTML attributes and meta tags

The SDK recognizes HTML attributes and meta tags for configuring blur and workspace identity.

### Blur attributes

Use `data-userplane-blur` to blur sensitive elements in recordings:

```html theme={null}
<div data-userplane-blur>
  <input type="text" placeholder="Credit card number" />
</div>
```

To exclude an element from blur:

```html theme={null}
<div data-userplane-blur="false">
  <p>This content will not be blurred.</p>
</div>
```

You can also use the `.userplane-mask` CSS class or `<meta name="userplane:blur">` tags. See the [Sensitive Data Redaction Developer Guide](/developer/sensitive-data-redaction) for the full list of blur methods and third-party compatibility.

### Workspace meta tag

If you don't pass `workspaceId` in `initialize()`, the SDK reads it from meta tags:

```html theme={null}
<meta name="userplane:workspace" content="ws_abc123" />
```

## URL parameters

When a customer opens a recording link, Userplane appends these query parameters to the URL:

| Parameter             | Description                                           |
| --------------------- | ----------------------------------------------------- |
| `userplane-token`     | The recording session token                           |
| `userplane-action`    | The action type (`recording`, `verify`, or `capture`) |
| `userplane-workspace` | The workspace ID                                      |

The SDK parses these automatically on initialization. If your app uses custom URL routing, you can provide a custom parser via the `parseUserplaneData` option.

## Common patterns

### Trigger recording from a support button

```javascript theme={null}
import { initialize, open, isRecorderMounted } from '@userplane/sdk';

initialize({
  workspaceId: 'ws_abc123',
  openImmediately: false,
});

document.getElementById('help-btn').addEventListener('click', () => {
  if (!isRecorderMounted()) {
    open();
  }
});
```

### Show recording state in your UI

```javascript theme={null}
import { getRecordingState } from '@userplane/sdk';

function updateRecordingIndicator() {
  const state = getRecordingState();
  const indicator = document.getElementById('recording-indicator');

  if (state === 'active') {
    indicator.style.display = 'block';
  } else {
    indicator.style.display = 'none';
  }
}
```

### Correlate recordings with your own analytics

```javascript theme={null}
import { getSessionId, getLinkId } from '@userplane/sdk';

// Send to your analytics tool
analytics.track('recording_started', {
  userplaneSessionId: getSessionId(),
  userplaneLinkId: getLinkId(),
});
```

## Integration with recording links

The SDK works alongside recording links. When a customer opens a recording link on a page where the SDK is initialized, the SDK can provide additional context:

* [Custom metadata](/developer/metadata-sdk) is attached to the recording.
* Blur attributes are respected during capture.
* Domain recording preferences are applied.

## Related articles

* [Metadata SDK](/developer/metadata-sdk) — attach custom metadata to recordings.
* [Installation](/developer/installation) — install and configure the embed script.
* [Sensitive Data Redaction Developer Guide](/developer/sensitive-data-redaction) — configure blur to protect sensitive content.
* [Recording Data Reference](/developer/recording-data-reference) — what data is captured.
