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

# Form Filling Implementation In Web SDK For JavaScript

> Learn how to use Form filling in the Suki Web SDK for JavaScript applications

This guide shows how to integrate Form filling capabilities into a browser-based JavaScript application with the Suki Web SDK. You will create the **Auth Manager** and **Form filling Client**, then start a Form filling session by calling **`await formFillingClient.start({ ... })`** from your own code when the clinician is ready.

Use this approach if you are building with vanilla JavaScript, or another non-React framework, and want to control when and where Form filling appears in your interface.

Let's get started!

## Prerequisites

Before you begin, you must have the following requirements met:

* **Packages:** Install **`@suki-sdk/js`** and **`@suki-sdk/core`** (Web SDK **`v3.2.0`** or later).
* **Partner credentials:** Obtain **`partnerId`** and **`partnerToken`** from Suki after [Partner onboarding](/documentation/get-started/partner-onboarding).
* **Template IDs:** **`template_id`** UUIDs from your Suki support team for **`form_template_ids`**.
* **Encounter ID:** Pass your encounter ID as **`correlation_id`**. Refer to [Configuration](/form-filling-sdk/guides/configuration#correlation_id-your-encounter-id) for more details.
* **Browser and layout:** Your app runs in a **browser** over HTTPS, with microphone access and a Form filling **container** that has height.

Refer to [Prerequisites](/web-sdk/prerequisites) guide for more details.

## Install the packages

Add both packages to the same project you load in the browser:

<CodeGroup title="Install the @suki-sdk/js and @suki-sdk/core Packages">
  ```shell pnpm theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
  pnpm add @suki-sdk/core @suki-sdk/js
  ```

  ```shell npm theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
  npm install @suki-sdk/core @suki-sdk/js
  ```

  ```shell yarn theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
  yarn add @suki-sdk/core @suki-sdk/js
  ```
</CodeGroup>

<Tip>
  After you install, pull the SDK into your files with **`import`**, the same way as in the examples below. Use whatever approach your project already uses for other npm libraries. Import **`FormFillingClient`** from **`@suki-sdk/js`**. You do not need **`@suki-sdk/form-filling`**.
</Tip>

## Step 1: Add container HTML

The hosted Form filling UI mounts inside the element you pass as **`rootElement`**. That node must have **real height**, or the iframe looks blank.

```html HTML theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
<div id="suki-form-container" style="width: 100%; height: 600px;"></div>
<button type="button" id="fill-forms-btn">Fill Forms with Suki</button>
```

<Tip>
  Refer to [Configuration](/form-filling-sdk/guides/configuration#container-sizing) for recommended CSS.
</Tip>

## Step 2: Create auth manager

Now you need to create the **Auth Manager** for your application. To create the Auth Manager, you must have the **`partnerId`** and **`partnerToken`** credentials from Suki.
Refer to [Partner onboarding](/documentation/get-started/partner-onboarding) guide to learn how to get these credentials.

Once you have all the required credentials, create **one** auth manager for the page (or app shell).

**Code example for creating auth manager**

```javascript JavaScript expandable theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
import { SukiAuthManager } from "@suki-sdk/core";

const authManager = new SukiAuthManager({
  partnerId: "YOUR_PARTNER_ID", // replace with your partner ID - required
  partnerToken: "YOUR_PARTNER_TOKEN", // replace with your partner token - required
  environment: "staging", // optional: "staging" | "production"
  loginOnInitialize: true, // optional: sign in as soon as this runs
  autoRegister: false, // optional: enable provider auto-registration
  providerId: "YOUR_PROVIDER_ID", // optional: provider identifier in your system
  providerName: "YOUR_PROVIDER_NAME", // optional: full provider display name
  providerOrgId: "YOUR_PROVIDER_ORG_ID", // optional: organization identifier for the provider in your system
  providerSpecialty: "YOUR_PROVIDER_SPECIALTY", // optional: clinical specialty
});
```

## Step 3: Create Form filling client

After you have created the auth manager, you can create the **Form filling client** for your application. The Form filling Client is the object that will be used to start the Form filling session.

Create **one** Form filling client and reuse it for every **`start()`** call on that page.

**Code example for creating Form filling client**

```javascript JavaScript expandable theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
import { FormFillingClient } from "@suki-sdk/js";

const formFillingClient = new FormFillingClient({
  authManager,
  onError: (err) => console.error(err.code, err.reason, err.message),
});
```

## Step 4: Call start() to open Form filling

Now you can start the Form filling session by calling the **`start()`** method on the Form filling client.

Call **`await formFillingClient.start({ ... })`** from a click handler (or similar) when the DOM is ready.
Pass **`rootElement`**, **`form_template_ids`**, **`onSubmit`**, and any optional fields you need. Refer to [Configuration](/form-filling-sdk/guides/configuration) guide for more details on the available options and how to use them.

**Code example for starting Form filling**

```javascript JavaScript expandable theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
async function openFormFilling() {
  const root = document.getElementById("suki-form-container");

  if (!root) {
    console.error("Missing suki-form-container in the DOM");
    return;
  }

  try {
    await formFillingClient.start({
      rootElement: root, // replace with the DOM element where Form filling mounts - required
      form_template_ids: ["YOUR_TEMPLATE_ID"], // template_id UUIDs from Suki support - required
      correlation_id: "YOUR_ENCOUNTER_ID", // your encounter or appointment ID - optional but recommended
      onReady: () => {
        console.log("Form UI ready");
      },
      onSubmit: (result) => {
        console.log("Session:", result.ambient_session_id);
        console.log("Correlation:", result.correlation_id);
        console.log("Forms:", result.structured_data.generated_values);
      },
      onCancel: () => {
        console.log("Form filling cancelled");
      },
    });
  } catch (err) {
    console.error("Form filling start() failed", err);
  }
}

document.getElementById("fill-forms-btn")?.addEventListener("click", () => {
  void openFormFilling();
});
```

<Note>
  **`onSubmit`** is required. It runs when structured JSON is ready after processing, not when the clinician taps submit in the hosted UI.
</Note>

## Callbacks

You can pass **`onReady`**, **`onSubmit`**, and **`onCancel`** on **`start()`**, or listen with **`formFillingClient.on()`** for handlers that stay active across many sessions:

```javascript JavaScript theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
formFillingClient.on("form-filling:submitted", (result) => {
  console.log(result.ambient_session_id);
});
```

Refer to [Callbacks](/form-filling-sdk/guides/callbacks) for the **`FormFillingResult`** shape and [Events](/form-filling-sdk/api-reference/events) for every event and payload.

## Starting another session

Calling **`start()`** again **replaces** the active session. You do **not** need to call **`stop()`** manually just to open Form filling again:

```javascript JavaScript theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
await formFillingClient.start({ /* encounter A options */ });
await formFillingClient.start({ /* encounter B options */ });
```

## Complete code example

Below is a complete code example in JavaScript for Form filling with a single container and button.

```javascript JavaScript expandable theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
import { SukiAuthManager } from "@suki-sdk/core";
import { FormFillingClient } from "@suki-sdk/js";

const authManager = new SukiAuthManager({
  partnerId: "YOUR_PARTNER_ID", // replace with your partner ID - required
  partnerToken: "YOUR_PARTNER_TOKEN", // replace with your partner token - required
  environment: "staging", // optional: "staging" | "production"
  loginOnInitialize: true, // optional: sign in as soon as this runs
  autoRegister: false, // optional: enable provider auto-registration
  providerId: "YOUR_PROVIDER_ID", // optional: provider identifier in your system
  providerName: "YOUR_PROVIDER_NAME", // optional: full provider display name
  providerOrgId: "YOUR_PROVIDER_ORG_ID", // optional: organization identifier for the provider in your system
  providerSpecialty: "YOUR_PROVIDER_SPECIALTY", // optional: clinical specialty
});

const formFillingClient = new FormFillingClient({
  authManager,
  onError: (err) => console.error(err.code, err.message),
});

async function openFormFilling() {
  const root = document.getElementById("suki-form-container");
  if (!root) return;

  try {
    await formFillingClient.start({
      rootElement: root,
      form_template_ids: ["YOUR_TEMPLATE_ID"],
      correlation_id: "YOUR_ENCOUNTER_ID",
      onReady: () => console.log("Form UI ready"),
      onSubmit: (result) => {
        for (const form of result.structured_data.generated_values) {
          console.log(form.form_template_id, form.data);
        }
      },
      onCancel: () => {
        console.log("Cancelled");
      },
    });
  } catch (e) {
    console.error(e);
  }
}

document.addEventListener("DOMContentLoaded", () => {
  document
    .getElementById("fill-forms-btn")
    ?.addEventListener("click", () => void openFormFilling());
});
```

Your integration is working when the Form filling UI appears, the microphone is active, and **`onSubmit`** returns **`structured_data`**.

## Best practices

<Tip>
  * **Reuse one Form filling client.** Build a single **`FormFillingClient`** for the page or shell and call it again for each session. Creating a new client on every click often resets the hosted UI and feels flaky.

  * **Reuse one auth manager.** Create **`SukiAuthManager`** once and pass that same instance into the client, the same pattern as in the steps above.

  * **Handle when structured results arrive.** You must supply **`onSubmit`** so the SDK can deliver **`structured_data`**. Map **`generated_values`** to your EHR or backend.

  * **Pass `correlation_id`.** Use your encounter ID so callbacks and Partner webhooks match the correct record.

  * **Register a partner webhook** for production saves on your server, not browser **`onSubmit`** alone.

  * **Open Form filling only when the host is ready.** The DOM node you use as **`rootElement`** should exist and have real height before you open. Otherwise the Form filling area can look blank.

  * **Catch failures when opening Form filling.** Wrap the **`start()`** call so auth or setup errors show up in your logs instead of disappearing.

  * **Open again to start another session.** A new **`start()`** call replaces the active session. You usually do not need a separate **`stop()`** step first.
</Tip>

## Next steps

Refer to the following guides for more information.

<Icon icon="file-lines" iconType="solid" /> Follow [Configuration](/form-filling-sdk/guides/configuration) to learn about the available options and how to use them.

<Icon icon="file-lines" iconType="solid" /> Follow [React integration](/web-sdk/guides/form-filling-react) to learn how to integrate Form filling in a React application using the Suki Web SDK.
