> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://www.truework.com/docs/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://www.truework.com/docs/_mcp/server.

## Embedding the Truework widget into your workflow

Truework.js is a JavaScript library that allows you to easily integrate [Truework Direct](https://www.truework.com/products/direct) into your online application or web portal, simplifying the process to verify consumer's income and employment data securely and efficiently.

Use `Truework.direct` to initialize the widget. `Truework.credentials` is also supported for backward compatibility, but `Truework.direct` is the preferred API.

## Minimal example

Load the script, create a session token on your backend (see [Create a Truework Direct order](/docs/guides/truework-direct/getting-started); that guide focuses on the backend order/token flow and currently shows the legacy `Truework.credentials` initializer), then initialize and open the widget on the frontend using `Truework.direct` as shown below:

```html
<head>
  <script src="https://js.truework.com/v1"></script>
</head>
<body>
  <button id="verify">Verify</button>
  <script>
    document.getElementById('verify').addEventListener('click', async () => {
      const { token } = await getToken() // depends on implementation

      const direct = Truework.direct.init({
        publishableKey: 'tw_pk_...',
        sessionToken: token,
        env: Truework.direct.Env.Sandbox,
      });

      direct.onComplete(() => {
        console.log('Session complete')
      });

      direct.onError((e) => {
        console.error('Error', e.code, e.message);
      });

      await direct.open();
    });
  </script>
</body>
```

## Load the script

Include the Truework.js script once on the page where the widget will be used:

```html
<script src="https://js.truework.com/v1"></script>
```

After the script loads, `Truework` is available on the global object.

## Integration flow

1. **Backend:** Create a Truework Direct order (POST `/orders/truework-direct`) and obtain a session token. See [Make your first Truework Direct order](/docs/guides/truework-direct/getting-started) for how to create an order and get the token; that guide currently uses the legacy `Truework.credentials` widget initializer, but the order/token creation steps are the same when using `Truework.direct`.
2. **Frontend:** Load the script (above), call `Truework.direct.init({ publishableKey, sessionToken, env })`, then call `direct.open()`.
3. **Events:** Use `onComplete` when the user finishes the flow, `onClose` when the widget closes, and `onError` to handle errors.

**Best practices:** Use one session token per widget open; do not reuse the same token for multiple opens. Use `Truework.direct.Env.Sandbox` and sandbox publishable keys for testing.

## `Truework.direct.init(config)`

Initializes the Truework Direct widget. Accepts one required argument, a `config` object. Returns a widget instance with methods to open/close the widget and subscribe to events.

```html
<head>
    <script src="https://js.truework.com/v1"></script>
</head>
...
<script>
    (async () => {
      const { token } = await getToken(); // depends on implementation

      var direct = Truework.direct.init({
        publishableKey: 'tw_pk_gJbHD7tEwWUoZ8H_KQWKn4rEESHeNhabiosvcij9i0Q', // example key
        sessionToken: token,
        env: Truework.direct.Env.Production
      });
    })();
</script>
```

### `config` object

<ParamField path="publishableKey" type="string" required={true}>
    Publishable key that provides the configuration of this instance of the
    Truework Direct widget.
</ParamField>
<ParamField path="sessionToken" type="string" required={true}>
    Applicant-specific token referencing the Truework Direct session created
    using the backend API.
</ParamField>
<ParamField
    path="env"
    type="string enum"
    default="Truework.direct.Env.Production"
    required={false}
>
    Environment the session should be initialized in, one of:

    | Value       | Enum object property                    | Description                                                                                   |
    |-------------|-----------------------------------------|-----------------------------------------------------------------------------------------------|
    | `production`| `Truework.direct.Env.Production`   | For production publishable keys (`tw_pk_`), and session tokens created by api.truework.com    |
    | `sandbox`   | `Truework.direct.Env.Sandbox`      | For test publishable keys (`tw_pk_test_`), and session tokens created by api.truework-sandbox.com |
</ParamField>
<ParamField path="metadata" type="object" required={false}>
    Optional key-value data passed through to the widget (e.g. for internal tracking). Opaque to the widget; use at your discretion.
</ParamField>
<ParamField path="autoComplete" type="boolean" required={false}>
    Optional. Defaults to `true`. Controls auto-complete behavior in the widget.
</ParamField>

### `Truework.direct` object

Represents an initialized instance of the Truework Direct widget. This object has methods to control the widget and subscribe to widget events. All event registration methods return **a function you can call to remove the listener** (e.g. `const removeListener = direct.onComplete(fn); removeListener();`).

```javascript
const direct = Truework.direct.init(...);

direct.onOpen(() => {
  console.log("The widget is open!");
});

direct.onClose(data => {
  console.log("Widget closed. Tasks:", data.tasks);
});

// onSuccess is deprecated; use onComplete instead
direct.onComplete(() => {
  console.log("Verification flow complete.");
});

direct.onError(function (e) {
  console.log("Error", e.code, e.message);

  if (e.code === Truework.direct.ErrorCode.Critical) {
    /* widget closed */
  }
});

await direct.open();
// some other application logic here...
await direct.close();
```

#### `Truework.direct.open()`

Opens the widget modal window over the current page. Returns a **Promise**; you can `await direct.open()`.

#### `Truework.direct.close()`

Closes the widget modal window. Returns a **Promise**; you can `await direct.close()`.

#### `Truework.direct.onOpen(fn)`

Registers a callback to be called after the modal window is opened. Returns a function you can call to remove the listener.

#### `Truework.direct.onClose(fn)`

Registers a callback to be called when the widget is closed. The callback receives a **close payload** object: `{ tasks: TaskStatus[] }`. Each `TaskStatus` has:

- `completed` (boolean)
- `employer_name` (string | null)
- `task_type` (string | null)

Use this to show the user which tasks were completed when the widget closes. Returns a function you can call to remove the listener.

#### `Truework.direct.onComplete(fn)`

Registers a callback to be called when the user has successfully completed the verification flow. Prefer this over `onSuccess`. Returns a function you can call to remove the listener.

#### `Truework.direct.onSuccess(fn)` (deprecated)

Deprecated. Use `onComplete` instead. Registers a callback to be called after the flow completes successfully.

#### `Truework.direct.onError(fn)`

Registers a callback to be called when an error occurs. The callback receives a **TrueworkError** instance (subclass of `Error`) with:

- `code` — an `ErrorCode` value (see Error handling below)
- `message` — a string (safe for logging; PII is not exposed)
- `name` — `'TrueworkError'`

Returns a function you can call to remove the listener.

For advanced use, you can also subscribe with the generic **`on(type, handler)`** method for events `'open'`, `'close'`, `'complete'`, and `'error'`.

## Error handling

`Truework.direct.onError` callbacks are called when:

- Any API errors come from our API
- Handled or unhandled errors from our credentials partners
- Truework.js internal errors

There are two behavioral types:

- **Critical errors:** The widget closes, then `onError` is called.
- **Non-critical errors:** The widget may remain open while `onError` is called.

The `ErrorCode` value on the error object obscures the root cause (preventing PII exposure) while letting you handle errors appropriately.

### `ErrorCode` (integer enum)

The error object passed to `onError` has a `code` property equal to one of:

| Value | Enum object property                        | Description |
|------:|---------------------------------------------|-------------|
| 0     | `Truework.direct.ErrorCode.Critical`   | Critical error; widget will close. |
| 1     | `Truework.direct.ErrorCode.Error`      | General error. |
| 2     | `Truework.direct.ErrorCode.Display`   | Non-critical display message. |
| 3     | `Truework.direct.ErrorCode.Network`   | Network or API failure. |
| 4     | `Truework.direct.ErrorCode.Unauthorized` | Session unauthorized. |

For network errors (`code === ErrorCode.Network`), the widget may attach a more specific `NetworkErrorCode` on the error object when available, for finer-grained handling.

Example:

```javascript
direct.onError(function (e) {
  switch (e.code) {
    case Truework.direct.ErrorCode.Critical:
      console.log("A critical Truework Direct error occurred");
      // widget has closed
      break;
    case Truework.direct.ErrorCode.Network:
      console.log("Network error", e.message);
      break;
    default:
      // handle Error, Display, Unauthorized, etc. as needed
      break;
  }
});
```

## Browser support

We do our best to support all recent versions of major browsers.

For the sake of security and providing the best experience to the majority of customers, we do not support browsers that are no longer receiving security updates and represent a small minority of traffic.

- We support the latest 3 versions of the following desktop and mobile browsers: Chrome, Firefox, Safari, and Edge
- Internet Explorer 11 (IE11) support ended on May 15, 2022

Visit [our Help Center](https://help.truework.com/hc/en-us/articles/5549968612759-Supported-Internet-Browsers) for more information.