> ## 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.

# Audio Dictation In Web SDK For JavaScript

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

This guide walks you through the process of integrating audio dictation using the Suki Web SDK in a JavaScript application (browser-based) using the JavaScript package provided by Suki.
You will create **Auth Manager** and **Dictation Client**, then start audio dictation by calling **`await dictationClient.show({ ... })`** from your own code when the user is ready.

Let's get started!

## Prerequisites

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

* **Packages:** Install `@suki-sdk/js` and `@suki-sdk/core` packages.
* **Partner credentials:** Obtain `partnerId` and `partnerToken` from Suki after [Partner onboarding](/documentation/partner-onboarding).
* **Browser and layout:** Your app runs in a **browser**, with a real DOM and a dictation **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/dictation 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.
</Tip>

## Step 1: Add container and field HTML

For this example we will assume you are using **`in-field`** mode as your preferred mode.

In **`in-field`** mode you need **two** nodes in the page: a **`div`** (or similar) that you pass as **`rootElement`**, where the dictation controls show up, and a **textarea** (or input) that **`onSubmit`** will update when the user finishes.

The dictation layer **matches the size of** **`rootElement`**, so that node should have a **height** you control. Refer to [Wrapper layout](/dictation-sdk/guides/configuration#wrapper-layout) guide for recommended markup and CSS.

```html HTML theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
<div id="dictation-root"></div>
<label for="clinical-notes">Clinical notes</label>
<textarea id="clinical-notes" rows="8"></textarea>
<button type="button" id="start-dictation">Start dictation</button>
```

## 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/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 dictation client

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

Create **one** dictation client and reuse it for every **`show()`** call on that page.

**Code example for creating dictation client**

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

const dictationClient = new DictationClient({ authManager });
```

## Step 4: Call show() to start dictation

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

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

**Code example for starting dictation**

```javascript JavaScript expandable theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
async function startDictation() {
  const root = document.getElementById("dictation-root");
  const notes = document.getElementById("clinical-notes");

  if (!root || !notes) {
    console.error("Missing dictation-root or clinical-notes in the DOM");
    return;
  }

  try {
    await dictationClient.show({
      mode: "in-field", // replace with your preferred mode - required
      fieldId: "clinical-notes", // often the same string as the textarea id
      rootElement: root, // replace with the DOM element where the dictation controls will be shown - required
      initialText: notes.value ?? "", // replace with the initial text for the dictation session - optional
      onSubmit: ({ fieldId, text }) => { 
        const el = document.getElementById(fieldId);
        if (el) el.value = text;
      },
      onCancel: ({ fieldId }) => {
        console.log("Dictation cancelled", fieldId);
      },
      onDraft: ({ fieldId, text }) => {
        const el = document.getElementById(fieldId);
        if (el) el.value = text; 
      },
    });
  } catch (err) {
    console.error("Dictation show() failed", err);
  }
}

document.getElementById("start-dictation")?.addEventListener("click", () => {
  void startDictation();
});
```

<Note>
  **`onSubmit`** is required for a good user experience. If you omit it, dictation often **closes immediately** after the user acts.
</Note>

## Callbacks

Every callback receives the same shape as shown in the code example below:

```javascript JavaScript theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
{ fieldId: string, 
text: string 
}
```

Refer to [Callbacks](/dictation-sdk/guides/callbacks) guide for more details on the available callbacks and how to use them.

## Switching fields

Calling **`show()`** again **replaces** the active session. You do **not** need to call **`hide()`** manually just to move from one field to another:

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

## Complete code example

Below is a complete code example in JavaScript for in-field mode with a single field.

```javascript JavaScript expandable theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
import { SukiAuthManager } from "@suki-sdk/core";
import { DictationClient } 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 dictationClient = new DictationClient({ authManager });

async function startClinicalNotesDictation() {
  const root = document.getElementById("dictation-root");
  const notes = document.getElementById("clinical-notes");
  if (!root || !notes) return;

  try {
    await dictationClient.show({
      mode: "in-field",
      fieldId: "clinical-notes",
      rootElement: root,
      initialText: notes.value ?? "",
      onSubmit: ({ fieldId, text }) => {
        const el = document.getElementById(fieldId);
        if (el) el.value = text;
      },
      onCancel: ({ fieldId }) => {
        console.log("Cancelled", fieldId);
      },
    });
  } catch (e) {
    console.error(e);
  }
}

document.addEventListener("DOMContentLoaded", () => {
  document
    .getElementById("start-dictation")
    ?.addEventListener("click", () => void startClinicalNotesDictation());
});
```

<Tip>
  This page focuses on **`in-field`** dictation next to a specific input. If you want a **floating dictation panel** instead, set **`mode`** to **`"scratchpad"`** and follow [Scratchpad mode](/dictation-sdk/guides/scratchpad-mode) guide.
</Tip>

## Best practices

<Tip>
  * **Reuse one dictation client.** Build a single **DictationClient** for the page or shell and call it again for each dictation session. Creating a new client on every click or for every field 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 the user commits.** You must supply a submit handler so the SDK can deliver the final text. Without it, dictation often closes right after the user tries to finish.

  * **Pick a clear field label.** Each session needs a stable, unique **fieldId** in callbacks. Using the same value as the target input's **id** is a simple way to know which element to update. Refer to [Field IDs](/dictation-sdk/guides/configuration#field-ids-in-practice) guide for more details.

  * **Open dictation only when the host is ready.** The DOM node you use as the dictation host should exist and have real height before you open. Otherwise the dictation area can look blank. Refer to [Error handling](/dictation-sdk/guides/error-handling) and [In-field mode](/dictation-sdk/guides/in-field-mode) guides for more details.

  * **Catch failures when opening dictation.** Wrap the open call so auth or setup errors show up in your logs instead of disappearing.

  * **Move to another field by opening again.** A new open call replaces the active session. You usually do not need a separate hide step when you are only switching which field is dictating.
</Tip>

## Next steps

Refer to the following guides for more information.

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

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