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

# FormFillingClient

> FormFillingClient constructor, start options, methods, and React bindings for the Form filling SDK

**<Tooltip tip="Main class in the Form filling SDK that opens Form filling sessions in your page." cta="View in Glossary" href="/Glossary/f">FormFillingClient</Tooltip>** is the main entry point for the Form filling SDK. It loads Suki's hosted Form filling interface in a <Tooltip tip="Suki-controlled UI loaded inside your web page for Form filling or Dictation." cta="View in Glossary" href="/Glossary/h">hosted iframe</Tooltip> inside your application.

Create the client once, provide your partner authentication, `form_template_ids`, and any callbacks, then use the same client to start Form filling sessions. The SDK manages the iframe connection, validates template IDs, and delivers session callbacks and events for you.

In React, wrap your app with `FormFillingProvider` and render `FormFilling` when the clinician should see the interface. You do not pass a container element yourself; the component handles that.

## Import

<CodeGroup>
  ```javascript JavaScript theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
  import { FormFillingClient } from "@suki-sdk/form-filling";
  import { SukiAuthManager } from "@suki-sdk/core";
  ```

  ```tsx React theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
  import {
    FormFillingClient,
    FormFillingProvider,
    FormFilling,
    useFormFilling,
  } from "@suki-sdk/form-filling-react";
  import { SukiAuthManager } from "@suki-sdk/core";
  ```
</CodeGroup>

## Create an instance

Create `SukiAuthManager` first, then pass it to `FormFillingClient`. Sign-in must succeed before the Form filling interface can open.

<View title="JavaScript" icon="js">
  ```javascript JavaScript theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
  const authManager = new SukiAuthManager({
    partnerId: "YOUR_PARTNER_ID", // required
    partnerToken: "YOUR_PARTNER_TOKEN", // required
    environment: "staging",
    loginOnInitialize: true,
    autoRegister: false, // optional (default true); when true, providerName and providerOrgId are often required
  });

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

  ```
</View>

<View title="React" icon="react">
  ```tsx React theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
  import { useMemo } from "react";
  import { SukiAuthManager } from "@suki-sdk/core";
  import { FormFillingClient } from "@suki-sdk/form-filling-react";

  const client = useMemo(() => {
    const authManager = new SukiAuthManager({
      partnerId: "YOUR_PARTNER_ID", // required
      partnerToken: "YOUR_PARTNER_TOKEN", // required
      environment: "staging",
      loginOnInitialize: true,
      autoRegister: false, // optional (default true); when true, providerName and providerOrgId are often required
    });
    return new FormFillingClient({
      authManager,
      onError: (err) => console.error(err.code, err.reason, err.message),
    });
  }, []);
  ```
</View>

<Note>
  In React, create `FormFillingClient` inside `useMemo` or at module scope so you do not build a new client on every render.
</Note>

### Constructor options

These are the settings you pass to `new FormFillingClient({ ... })` in JavaScript.

<Expandable title="Constructor fields" defaultOpen="true">
  <ResponseField name="authManager" type="SukiAuthManager" required>
    Sign-in helper from `@suki-sdk/core`. Create once per page and reuse for every session. Refer to [Authentication](/form-filling-sdk/guides/authentication).
  </ResponseField>

  <ResponseField name="onError" type="function">
    **Optional.** Called when the SDK reports a configuration or runtime error. The same error is also available on `form-filling:error`. Refer to [Error handling](/form-filling-sdk/guides/error-handling).
  </ResponseField>
</Expandable>

## Start options

Call `await client.start({ ... })` when the clinician starts a Form filling session.
The SDK validates your `form_template_ids`, loads the Form filling interface, authenticates the session, and prepares it for use.

The `start()` method resolves when the session has been initialized. When the interface is fully loaded and ready for interaction, the `onReady` callback is called.
`start()` does not throw errors. Instead, handle errors with the `onError` callback or the `form-filling:error` event.

If you call `start()` again, the SDK automatically closes the current session and starts a new one. You do not need to call `stop()` first.

<Warning>
  Always implement `onSubmit`. It runs when structured JSON is ready after processing completes, not when the clinician taps submit.
</Warning>

### start() options

<Expandable title="start() fields" defaultOpen="true">
  <ResponseField name="rootElement" type="HTMLElement" required>
    Container for the Form filling iframe. JavaScript only. Give this element explicit height before `start()`. In React, `FormFilling` passes its own container automatically.
  </ResponseField>

  <ResponseField name="form_template_ids" type="string[]" required>
    One or more `template_id` UUIDs from your Suki support team. The SDK validates each ID before the iframe opens. Unsupported IDs are dropped. If no valid IDs remain, the SDK returns `SUKI_FF_001`. Refer to [Form filling templates](/documentation/concepts/form-filling/form-filling-templates).
  </ResponseField>

  <ResponseField name="correlation_id" type="string">
    **Optional.** Your encounter or appointment ID. Echoed on callbacks, events, and webhook payloads. Strongly recommended so results map to the correct patient record. If you omit it, the hosted UI generates a UUID when it creates the session.
  </ResponseField>

  <ResponseField name="onSubmit" type="function" required>
    Called when structured results are ready after processing. Receives a `FormFillingResult`. For a foreground session, the iframe is removed after this runs.
  </ResponseField>

  <ResponseField name="onReady" type="function">
    **Optional.** Called when the Form filling interface is loaded and interactive. Same moment as `form-filling:ready`.
  </ResponseField>

  <ResponseField name="onCancel" type="function">
    **Optional.** Called when the clinician cancels during form selection or recording without submitting. Same moment as `form-filling:cancelled`.
  </ResponseField>
</Expandable>

Refer to [Configuration](/form-filling-sdk/guides/configuration) for container sizing and `correlation_id` details.

## Methods and getters

In JavaScript, you can use the following methods and getters to manage the Form filling session.

<Expandable title="Methods and getters" defaultOpen="true">
  <ResponseField name="stop()" type="method">
    Ends the active session and removes the iframe. Keeps the client, auth state, and template cache so you can call `start()` again. React calls this when `FormFilling` unmounts.
  </ResponseField>

  <ResponseField name="destroy()" type="method">
    Removes the iframe, tears down internal wiring, and clears the template cache. Does not destroy `SukiAuthManager`.
  </ResponseField>

  <ResponseField name="on(event, handler)" type="method">
    Subscribe to `form-filling:*` events. Returns an unsubscribe function. Refer to [Events](/form-filling-sdk/api-reference/events).
  </ResponseField>

  <ResponseField name="isReady" type="boolean">
    `true` after the Form filling interface reports that it is loaded and interactive.
  </ResponseField>

  <ResponseField name="isVisible" type="boolean">
    `true` while the Form filling iframe is displayed in your container.
  </ResponseField>
</Expandable>

## React bindings and components

In React, you can use the following components and provider to manage the Form filling session.

### FormFillingProvider

Wrap components that render `FormFilling` or call `useFormFilling()`. Pass the same `FormFillingClient` instance you created in `useMemo`.

```tsx React theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
<FormFillingProvider client={client}>
  {/* children */}
</FormFillingProvider>
```

The provider listens for `form-filling:error` and exposes the latest error through `useFormFilling()`.

### FormFilling

Render `FormFilling` when the clinician should see the Form filling interface. Mounting starts a session; unmounting calls `client.stop()`.

Props match `start()` options, except you do not pass `rootElement`.

<Expandable title="FormFilling props" defaultOpen="true">
  <ResponseField name="form_template_ids" type="string[]" required>
    Same as `start()`. Template IDs from Suki support.
  </ResponseField>

  <ResponseField name="correlation_id" type="string">
    Same as `start()`. Your encounter ID.
  </ResponseField>

  <ResponseField name="onSubmit" type="function" required>
    Same as `start()`. Required handler for structured results.
  </ResponseField>

  <ResponseField name="onReady" type="function">
    Same as `start()`.
  </ResponseField>

  <ResponseField name="onCancel" type="function">
    Same as `start()`.
  </ResponseField>

  <ResponseField name="onBackgroundSubmit" type="function">
    **React only.** Called for **`form-filling:background-submitted`** when results arrive for a session that is no longer the foreground session while the iframe is still open. Same payload shape as `onSubmit`.
  </ResponseField>
</Expandable>

### useFormFilling()

Call inside `FormFillingProvider` to read the client, session state, or the latest error from sibling components.

<Expandable title="useFormFilling() return values" defaultOpen="true">
  <ResponseField name="client" type="FormFillingClient">
    The same client instance you passed to `FormFillingProvider`.
  </ResponseField>

  <ResponseField name="isSessionActive" type="boolean">
    `true` after `form-filling:ready`. Returns to `false` after submit, cancel, close, or error.
  </ResponseField>

  <ResponseField name="error" type="SukiFormFillingError | null">
    The latest SDK error from `form-filling:error`, if any. The provider does not clear this when a later session becomes ready, so prefer `isSessionActive` over returning early on `error` alone.
  </ResponseField>
</Expandable>

## Code examples

<View title="JavaScript" icon="js">
  The following example shows how to create a Form filling client, start a session, and handle the session events in JavaScript.

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

  const authManager = new SukiAuthManager({
    partnerId: "YOUR_PARTNER_ID", // required
    partnerToken: "YOUR_PARTNER_TOKEN", // required
    environment: "staging",
    loginOnInitialize: true,
    autoRegister: false, // optional (default true); when true, providerName and providerOrgId are often required
  });

  const client = new FormFillingClient({ authManager });

  document.getElementById("start-forms").addEventListener("click", async () => {
    await client.start({
      rootElement: document.getElementById("suki-form-container"),
      form_template_ids: ["YOUR_TEMPLATE_ID"],
      correlation_id: "c3d4e5f6-a7b8-9012-cdef-123456789012",
      onReady: () => console.log("Form filling ready"),
      onSubmit: (result) => {
        console.log(result.ambient_session_id, result.structured_data);
      },
      onCancel: () => console.log("Cancelled"),
    });
  });
  ```

  Refer to [JavaScript integration](/form-filling-sdk/javaScript-integration/javaScript) for a full step-by-step guide.
</View>

<View title="React" icon="react">
  The following example shows how to create a Form filling client, wrap it with `FormFillingProvider`, and mount `FormFilling` when the clinician opens Form filling in React.

  ```tsx React theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
  import { useMemo, useState } from "react";
  import { SukiAuthManager } from "@suki-sdk/core";
  import {
    FormFillingClient,
    FormFillingProvider,
    FormFilling,
  } from "@suki-sdk/form-filling-react";

  export function EncounterPage({ encounterId }: { encounterId: string }) {
    const client = useMemo(() => {
      const authManager = new SukiAuthManager({
        partnerId: "YOUR_PARTNER_ID", // required
        partnerToken: "YOUR_PARTNER_TOKEN", // required
        environment: "staging",
        loginOnInitialize: true,
        autoRegister: false, // optional (default true); when true, providerName and providerOrgId are often required
      });
      return new FormFillingClient({ authManager });
    }, []);

    const [isFormOpen, setIsFormOpen] = useState(false);

    return (
      <FormFillingProvider client={client}>
        <button type="button" onClick={() => setIsFormOpen(true)} disabled={isFormOpen}>
          Start Form filling
        </button>
        {isFormOpen && (
          <FormFilling
            form_template_ids={["YOUR_TEMPLATE_ID"]}
            correlation_id={encounterId}
            onSubmit={(result) => {
              console.log(result.structured_data);
              setIsFormOpen(false);
            }}
            onCancel={() => setIsFormOpen(false)}
            onBackgroundSubmit={(result) => console.log(result.structured_data)}
          />
        )}
      </FormFillingProvider>
    );
  }
  ```

  Refer to [React integration](/form-filling-sdk/react-integration/react) for a full step-by-step guide.
</View>

## Next steps

<Icon icon="file-lines" iconType="solid" /> Refer to [Events](/form-filling-sdk/api-reference/events) for `client.on()` payloads and lifecycle

<Icon icon="file-lines" iconType="solid" /> Refer to [Callbacks](/form-filling-sdk/guides/callbacks) for `onSubmit` and `FormFillingResult`

<Icon icon="file-lines" iconType="solid" /> Refer to [Configuration](/form-filling-sdk/guides/configuration) for auth, container sizing, and `correlation_id`
