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

# Build Problem-Based Charting Using Web SDK

> Use-case tutorial: Mount Web SDK Ambient with a PBN section, seed EMR diagnoses, and handle note submit for problem-based charting

<Callout icon="info-circle" color="#FFE148">
  **What you will build**

  <p className="doc-tutorial-meta" aria-label="20 min, Intermediate">
    <Badge size="sm" color="gray" icon="clock">20 min</Badge> |
    <Badge size="sm" color="gray" icon="user-graduate">Intermediate</Badge>
  </p>

  * A Web SDK ambient encounter with problem-based charting enabled
  * One Assessment and Plan section marked as the Problem-Based Note (PBN)
  * EMR diagnoses seeded into the first session of the encounter
  * A note submit handler that reads sectioned note content
</Callout>

<Tip>
  **Using an AI coding tool?**

  Copy the following prompt to add the Suki developer documentation as a skill and [MCP server](/documentation/references/mcp) to your tool for better AI-assisted coding during the integration process. For all AI options (contextual menu, `llms.txt`, and `skill.md`), refer to [AI-optimized documentation](/documentation/references/ai-optimized-documentation).
</Tip>

<Prompt description="Install the Suki developer docs as a skill to get context on Suki's developer tools, APIs, and SDKs. Add the [MCP server](/documentation/references/mcp) for documentation search." icon="gear" iconType="regular" actions={["copy", "cursor"]}>
  Install the Suki developer docs as skill to get context on Suki's developer tools, APIs, and SDKs.

  npx skills add [https://developer.suki.ai](https://developer.suki.ai)

  Then add the Suki developer docs MCP server for access to documentation search. Follow the MCP instructions at [https://developer.suki.ai/documentation/references/mcp](https://developer.suki.ai/documentation/references/mcp).
</Prompt>

In this use-case tutorial, you build a React Web SDK ambient page for [problem-based charting](/web-sdk/guides/ambient-problem-based-charting). You wrap with <strong><code>SukiProvider</code></strong>, authenticate with <strong><code>SukiAuthManager</code></strong>, call <strong><code>init</code></strong>, then mount <strong><code>SukiAssistant</code></strong> with <strong><code>ambientOptions</code></strong>: exactly one LOINC section with <strong><code>isPBNSection: true</code></strong>, EMR <strong><code>diagnoses</code></strong> for the first session, and <strong><code>onNoteSubmit</code></strong> to receive the note.

By the end of this tutorial, documentation follows problems, merges visit discussion with diagnoses you already know, and your app receives sectioned note content on submit.

<span id="prerequisites" />

## Prerequisites

Before you begin, make sure you have:

* Completed [Partner onboarding](/documentation/get-started/partner-onboarding) and received your <code>partnerId</code> and <code>partnerToken</code>.
* A React 18+ app that can host the Web SDK UI.
* Host URLs on the Suki allowlist and a partner JWT that meets [Web SDK prerequisites](/web-sdk/prerequisites).
* Web SDK <strong>v2.1.2+</strong> for the <strong><code>diagnoses</code></strong> block (EMR merge).
* LOINC section codes from [Note sections](/documentation/concepts/ambient-clinical-notes/note-sections). This tutorial uses Assessment and Plan (<code>51847-2</code>) as the PBN.

<Tip>
  If you are new to Web SDK ambient, complete [Build a Web SDK ambient session](/documentation/tutorials/web-sdk-ambient-react) first, then return here to add PBC.
</Tip>

<Warning>
  Only one section can have <code>isPBNSection: true</code>. If more than one section is marked as PBN, the ambient session fails to start. Seed diagnoses only on the <strong>first</strong> session in an encounter. Later re-ambient cannot seed diagnoses.
</Warning>

<span id="architecture" />

## Architecture

```mermaid actions={false} theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
%%{init: {'theme':'base', 'themeVariables': { 'primaryColor':'#FFE148','primaryTextColor':'#111827','primaryBorderColor':'#D4A017','lineColor':'#6F5410','secondaryColor':'#FFF394','tertiaryColor':'#FFFADE','tertiaryTextColor':'#111827','tertiaryBorderColor':'#D4A017','arrowheadColor':'#6F5410','fontSize':'14px','edgeLabelBackground':'#FFFADE'}}}%%
flowchart LR
  A[SukiProvider] --> B[SukiAuthManager + init]
  B --> C[PBN section + diagnoses]
  C --> D[SukiAssistant]
  D --> E[onNoteSubmit]
```

<span id="project-setup" />

## Project setup

1. Use a React 18+ app that meets Web SDK prerequisites (see Prerequisites). Use Web SDK **v2.1.2+** for diagnoses seeding.
2. Install the required dependencies:

```shell theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
# pnpm
pnpm add @suki-sdk/react @suki-sdk/core

# npm
npm install @suki-sdk/react @suki-sdk/core
```

3. Configure your credentials:

   <Callout icon="gear" color="#929292">
     * Keep `partnerId` and `partnerToken` ready for `SukiAuthManager`.
     * Confirm host URLs meet [Web SDK prerequisites](/web-sdk/prerequisites).
     * Have LOINC section codes ready. This tutorial uses Assessment and Plan (`51847-2`) as the PBN.
   </Callout>

<span id="tutorial-steps" />

## Tutorial steps

Work through each step in order. Read the explanation, review the code example, then continue to the next step. The full code example is available in the accordion below.

<Steps>
  <Step title="Wrap Your App with SukiProvider">
    In Web SDK v3, wrap your tree with `SukiProvider`. Run `init` in a child component, not on the provider.

    ```tsx theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
    import { SukiProvider } from "@suki-sdk/react";

    function App() {
    return (
    <SukiProvider>
      <PbcAmbientPage />
    </SukiProvider>
    );
    }
    ```
  </Step>

  <Step title="Create SukiAuthManager and Call Init">
    Create one `SukiAuthManager` with `useMemo`, then call `init` from `useSuki()` when the SDK is not initialized yet.

    ```tsx theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
    import { useEffect, useMemo } from "react";
    import { SukiAuthManager } from "@suki-sdk/core";
    import { useSuki } from "@suki-sdk/react";

    function PbcAmbientPage() {
    const authManager = useMemo(
    () =>
      new SukiAuthManager({
        partnerId: "YOUR_PARTNER_ID",
        partnerToken: "YOUR_PARTNER_TOKEN",
        providerName: "Dr. Jane Smith", // Example only — replace with the provider's full name
        providerOrgId: "YOUR_ORG_ID",
        environment: "staging", // Example — staging | production
        loginOnInitialize: true,
      }),
    [],
    );

    const { init, isInitialized } = useSuki();

    useEffect(() => {
    if (!isInitialized) {
      init({ authManager });
    }
    }, [init, isInitialized, authManager]);

    if (!isInitialized) {
    return <p>Initializing Suki Web SDK...</p>;
    }

    // Continue with encounter + ambientOptions in the next steps
    return null;
    }
    ```
  </Step>

  <Step title="Mark Assessment and Plan as the PBN">
    Build `ambientOptions.sections` with LOINC codes. Set `isPBNSection: true` on Assessment and Plan (`51847-2`) only. Use supported codes from [Note sections](/documentation/concepts/ambient-clinical-notes/note-sections).

    ```tsx theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
    const ambientOptions = {
    sections: [
    {
      loinc: "51847-2", // Assessment and Plan
      isPBNSection: true, // Exactly one PBN section
    },
    {
      loinc: "10164-2", // History of Present Illness
    },
    {
      loinc: "10187-3", // Review of Systems
    },
    ],
    };
    ```
  </Step>

  <Step title="Seed Existing Patient Diagnoses">
    Add `diagnoses` under `ambientOptions` for the first session in the encounter. Use ICD-10 only, exactly one code per diagnosis, and at least one of `code` or `description`. A seeded diagnosis appears in the note only if discussed during the visit. Refer to [Existing patient diagnoses](/web-sdk/guides/ambient-problem-based-charting#existing-patient-diagnoses).

    ```tsx theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
    const ambientOptions = {
    sections: [
    { loinc: "51847-2", isPBNSection: true },
    { loinc: "10164-2" },
    { loinc: "10187-3" },
    ],
    diagnoses: {
    values: [
      {
        codes: [
          {
            code: "I10", // Example ICD10 — replace with your EMR diagnosis code
            description: "Essential hypertension", // Example only
            type: "ICD10",
          },
        ],
        diagnosisNote: "Hypertension", // Example only
      },
    ],
    },
    };
    ```
  </Step>

  <Step title="Mount SukiAssistant and Handle Note Submit">
    Pass `encounter` (patient identifier required; gender `MALE` | `FEMALE` | `UNKNOWN`), `ambientOptions`, and `onNoteSubmit`. Keep identifiers at most 36 characters. Note submit returns the same shape whether or not you seed diagnoses (`noteId`, `encounterId`, `contents`).

    ```tsx theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
    import { useEffect, useMemo } from "react";
    import { SukiAuthManager } from "@suki-sdk/core";
    import { useSuki, SukiAssistant } from "@suki-sdk/react";

    function PbcAmbientPage() {
    const authManager = useMemo(
    () =>
      new SukiAuthManager({
        partnerId: "YOUR_PARTNER_ID",
        partnerToken: "YOUR_PARTNER_TOKEN",
        providerName: "Dr. Jane Smith", // Example only — replace with the provider's full name
        providerOrgId: "YOUR_ORG_ID",
        environment: "staging", // Example — staging | production
        loginOnInitialize: true,
      }),
    [],
    );

    const { init, isInitialized } = useSuki();

    const encounter = useMemo(
    () => ({
      identifier: "6ec3920f-b0b1-499d-a4e9-889bf788e5ab", // Example only — replace with your encounter ID
      patient: {
        identifier: "905c2521-25eb-4324-9978-724636df3436", // Example only — replace with your patient ID
        name: {
          use: "official", // Example patient demographics — replace with real data
          family: "Doe",
          given: ["John"],
          suffix: [], // Required by Patient.name even when empty
        },
        birthDate: "1990-01-01", // Example only — YYYY-MM-DD
        gender: "MALE", // Example — must be "MALE" | "FEMALE" | "UNKNOWN"
      },
    }),
    [],
    );

    const ambientOptions = useMemo(
    () => ({
      sections: [
        { loinc: "51847-2", isPBNSection: true },
        { loinc: "10164-2" },
        { loinc: "10187-3" },
      ],
      diagnoses: {
        values: [
          {
            codes: [
              {
                code: "I10", // Example ICD10 — replace with your EMR diagnosis code
                description: "Essential hypertension", // Example only
                type: "ICD10",
              },
            ],
            diagnosisNote: "Hypertension", // Example only
          },
        ],
      },
    }),
    [],
    );

    useEffect(() => {
    if (!isInitialized) {
      init({ authManager });
    }
    }, [init, isInitialized, authManager]);

    const handleNoteSubmit = (data) => {
    console.log("Note submitted:", data.noteId);
    data.contents.forEach((section) => {
      console.log(`${section.title}: ${section.content}`);
    });
    };

    if (!isInitialized) {
    return <p>Initializing Suki Web SDK...</p>;
    }

    return (
    <SukiAssistant
      encounter={encounter}
      ambientOptions={ambientOptions}
      onNoteSubmit={handleNoteSubmit}
    />
    );
    }
    ```
  </Step>
</Steps>

<span id="full-example" />

## Full code example

<div className="doc-tutorial-full-code" data-doc-tutorial-full-code data-active-lang="react">
  <Columns cols={1}>
    <Tile href="#full-example-react">
      <span className="doc-tutorial-tile-lang-icon" data-icon="react" aria-hidden="true" />
    </Tile>
  </Columns>

  <div id="full-example-react" className="doc-tutorial-lang-panel is-active" data-lang-panel="react">
    ```tsx React theme={"theme":{"light":"github-dark","dark":"material-theme-darker"}}
    // Use-case tutorial: Problem-Based Charting with Web SDK Ambient (React)
    // Copy this file into a React app, replace YOUR_* placeholders, then render <App />.
    // Flow: SukiProvider → auth → init → ambientOptions (one PBN + diagnoses) → SukiAssistant + onNoteSubmit

    import { useEffect, useMemo } from "react";
    import { SukiAuthManager } from "@suki-sdk/core";
    import { SukiProvider, useSuki, SukiAssistant } from "@suki-sdk/react";

    // 1) Wrap once at the root. Call init() in a child under SukiProvider.
    function App() {
      return (
        <SukiProvider>
          <PbcAmbientPage />
        </SukiProvider>
      );
    }

    function PbcAmbientPage() {
      // 2) One long-lived auth manager. Recreating it every render breaks login state.
      const authManager = useMemo(
        () =>
          new SukiAuthManager({
            partnerId: "YOUR_PARTNER_ID", // Required: from partner onboarding
            partnerToken: "YOUR_PARTNER_TOKEN", // Required: keep off public clients in production
            providerName: "Dr. Jane Smith", // Example only — replace with the provider's full name
            providerOrgId: "YOUR_ORG_ID", // Required — replace with your org ID
            environment: "staging", // Example — use "production" only when ready
            loginOnInitialize: true,
          }),
        [],
      );

      const { init, isInitialized } = useSuki();

      // 3) Encounter + patient. Identifiers at most 36 characters.
      const encounter = useMemo(
        () => ({
          identifier: "6ec3920f-b0b1-499d-a4e9-889bf788e5ab", // Example only — replace with your encounter ID (max 36 chars)
          patient: {
            identifier: "905c2521-25eb-4324-9978-724636df3436", // Example only — replace with your patient ID (max 36 chars)
            name: {
              use: "official", // Example name fields — replace with real patient name data
              family: "Doe",
              given: ["John"],
              suffix: [], // Required by Patient.name even when empty
            },
            birthDate: "1990-01-01", // Example only — YYYY-MM-DD
            gender: "MALE", // Example — must be "MALE" | "FEMALE" | "UNKNOWN"
          },
        }),
        [],
      );

      // 4) PBC: exactly one isPBNSection: true. Seed diagnoses on the first session only.
      //    Assessment and Plan LOINC is 51847-2 (not 51848-0 Assessment alone).
      const ambientOptions = useMemo(
        () => ({
          sections: [
            { loinc: "51847-2", isPBNSection: true }, // Assessment and Plan (PBN)
            { loinc: "10164-2" }, // History of Present Illness
            { loinc: "10187-3" }, // Review of Systems
          ],
          diagnoses: {
            values: [
              {
                codes: [
                  {
                    code: "I10", // Example ICD10 — replace with your EMR diagnosis code
                    description: "Essential hypertension", // Example only
                    type: "ICD10", // Input codes must be ICD10
                  },
                ],
                diagnosisNote: "Hypertension", // Example only — optional note
              },
            ],
          },
        }),
        [],
      );

      // 5) Initialize the SDK once when the provider tree is ready.
      useEffect(() => {
        if (!isInitialized) {
          init({ authManager });
        }
      }, [init, isInitialized, authManager]);

      // 6) Receive sectioned note content when the clinician submits.
      const handleNoteSubmit = (data) => {
        console.log("Note submitted:", data.noteId, data.encounterId);
        data.contents.forEach((section) => {
          console.log(`${section.title}: ${section.content}`);
        });
      };

      if (!isInitialized) {
        return <p>Initializing Suki Web SDK...</p>;
      }

      // 7) Mount Ambient with PBN options and the submit handler.
      return (
        <SukiAssistant
          encounter={encounter}
          ambientOptions={ambientOptions}
          onNoteSubmit={handleNoteSubmit}
        />
      );
    }

    export default App;
    ```
  </div>
</div>

<span id="troubleshooting" />

## Troubleshooting

<AccordionGroup>
  <Accordion title="Session Fails to Start">
    Only one section may have `isPBNSection: true`.
  </Accordion>

  <Accordion title="Diagnoses Missing Later">
    Seed diagnoses only on the **first** session in an encounter.
  </Accordion>

  <Accordion title="Wrong Assessment and Plan Code">
    Use LOINC **`51847-2`** for Assessment and Plan (not `51848-0`).
  </Accordion>
</AccordionGroup>

<span id="summary" />

## Summary

In this tutorial, you:

* Mounted Web SDK ambient with one PBN section.
* Seeded EMR diagnoses on the first session in an encounter.
* Handled note submit to receive sectioned note content.

Use [problem-based charting](/web-sdk/guides/ambient-problem-based-charting) for deeper guidance.

<span id="other-tutorials" />

## Other tutorials

Continue with another end-to-end tutorial.

<div className="hp-io-method-grid tut-hub-card-grid">
  <a className="hp-io-method-card tut-hub-method-card" href="/documentation/tutorials/web-sdk-ambient-react">
    <div className="tut-hub-card-media tut-hub-card-media--blue" aria-hidden="true" />

    <div className="hp-io-method-card-body">
      <span className="hp-wn-badge hp-wn-badge-new">Ambient</span>
      <h3 className="hp-io-method-card-title">Build a Web SDK Ambient Session</h3>

      <p className="hp-io-method-card-desc">
        Authenticate, initialize the Web SDK in React, and mount SukiAssistant for an ambient encounter.
      </p>

      <div className="hp-io-method-card-meta tut-hub-card-foot" aria-label="15 min, Intermediate">
        <div className="tut-hub-card-foot-meta">
          <span className="hp-io-method-card-meta-time">15 min</span>
          <span className="tut-hub-level">Intermediate</span>
        </div>
      </div>
    </div>
  </a>

  <a className="hp-io-method-card tut-hub-method-card" href="/documentation/tutorials/webhook-notification-receiver">
    <div className="tut-hub-card-media tut-hub-card-media--blue" aria-hidden="true" />

    <div className="hp-io-method-card-body">
      <span className="hp-wn-badge hp-wn-badge-new">APIs</span>
      <h3 className="hp-io-method-card-title">Build a Webhook Notification Receiver</h3>

      <p className="hp-io-method-card-desc">
        Verify HMAC signatures, parse partner notifications, and handle success and failure events.
      </p>

      <div className="hp-io-method-card-meta tut-hub-card-foot" aria-label="10 min, Beginner">
        <div className="tut-hub-card-foot-meta">
          <span className="hp-io-method-card-meta-time">10 min</span>
          <span className="tut-hub-level">Beginner</span>
        </div>
      </div>
    </div>
  </a>
</div>
