An Ambient session is the core of the Suki Platform. The SDK can listen to the patient and provider conversation and generate clinical notes along with transcripts.

As the SDK is designed to be embedded in your application, it will automatically manage user states, recording flows, and error handling, providing a seamless experience for your users.

Since note generation requires predefined sections to organize content, you can configure them using either predefined note types or LOINC codes. The SDK will then generate the note based on the conversation and the configured sections.

LOINC code support is only available in version 2.0 and above of the Suki.js with limited set of codes, refer to the note sections documentation. If you are using an older version, please contact support to configure the note types.

Usage

There are two ways to manage the lifecycle of the ambient session:

  • Uncontrolled: The user interacts only with the buttons/controls within the SDK UI and the SDK manages the session lifecycle automatically.
  • Controlled: In addition to the buttons within the SDK UI, there are triggers from the EHR to manage the session lifecycle, such as starting, stopping, and resuming the session. The SDK will still handle the recording and note generation, but the application will have more control over the session lifecycle.
controlled.js
import { initialize } from "@suki-sdk/js";

let isSukiReady = false;

// replace this with your actual encounter data
const encounterDetails = {
  identifier: "6ec3920f-b0b1-499d-a4e9-889bf788e5ab",
  patient: {
    identifier: "905c2521-25eb-4324-9978-724636df3436",
    name: {
      use: "official",
      family: "Doe",
      given: ["John"],
      suffix: ["MD"],
    },
    birthDate: "1990-01-01",
    gender: "Male",
  },
};

const sukiInstance = initialize({
  partnerId: "f80c8db8-a4d0-4b75-8d63-56c82b5413f0", // Replace with your actual partner ID
  partnerToken:
    "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.KMUFsIDTnFmyG3nMiGM6H9FNFUROf3wh7SmqJp-QV30", // Replace with your actual partner token
  providerName: "John doe", // Replace with the full name of the provider
  providerOrgId: "1234", // Replace with the provider's organization ID
});

const unsubscribeInit = sdkClient.on("init:change", (isInitialized) => {
  if (isInitialized) {
    sdkClient.mount({
      rootElement: document.getElementById("suki-root"), // The root element to mount the SDK into
      encounter: encounterDetails,
      ambientOptions: {
        sections: [
          { loinc: "51848-0	" },
          { loinc: "11450-4" },
          { loinc: "29545-1" },
        ],
      },
    });
  } else {
    isSukiReady = false; // Reset the ready state if initialization fails
  }
});

const unsubscribeReady = sdkClient.on("ready", () => {
  isSukiReady = true;
});

function startAmbient() {
  if (isSukiReady) {
    sdkClient.startAmbient();
  } else {
    console.error("Suki SDK is not ready yet.");
  }
}

function pauseAmbient() {
  if (isSukiReady) {
    sdkClient.pauseAmbient();
  } else {
    console.error("Suki SDK is not ready yet.");
  }
}

function cancelAmbient() {
  if (isSukiReady) {
    sdkClient.cancelAmbient();
  } else {
    console.error("Suki SDK is not ready yet.");
  }
}

function resumeAmbient() {
  if (isSukiReady) {
    sdkClient.resumeAmbient();
  } else {
    console.error("Suki SDK is not ready yet.");
  }
}

function submitAmbient() {
  if (isSukiReady) {
    sdkClient.submitAmbient();
  } else {
    console.error("Suki SDK is not ready yet.");
  }
}

document
  .getElementById("start-ambient")
  .addEventListener("click", startAmbient);
document
  .getElementById("cancel-ambient")
  .addEventListener("click", cancelAmbient);
document
  .getElementById("submit-ambient")
  .addEventListener("click", submitAmbient);
document
  .getElementById("pause-ambient")
  .addEventListener("click", pauseAmbient);
document
  .getElementById("resume-ambient")
  .addEventListener("click", resumeAmbient);

// destroy function to clean up the SDK and event listeners
// call this function when you no longer need the SDK
function destroy() {
  isSukiReady = false;
  unsubscribeInit();
  unsubscribeReady();
  sdkClient.destroy();
  document
    .getElementById("start-ambient")
    .removeEventListener("click", startAmbient);
  document
    .getElementById("cancel-ambient")
    .removeEventListener("click", cancelAmbient);
  document
    .getElementById("submit-ambient")
    .removeEventListener("click", submitAmbient);
  document
    .getElementById("pause-ambient")
    .removeEventListener("click", pauseAmbient);
  document
    .getElementById("resume-ambient")
    .removeEventListener("click", resumeAmbient);
  document.getElementById("suki-root").innerHTML = ""; // Clear the root element
}

Update Encounter and Ambient Options

To update the encounter data or the ambient options, you can use the setEncounter and setAmbientOptions methods provided by the SDK. This allows you to change the encounter details or the sections for note generation dynamically whenever a new encounter is loaded in the EHR.

// Update encounter data
sdkClient.setEncounter({
  identifier: "qsc2393g-b0b1-499d-a4e9-983cq125g5op",
  patient: {
    identifier: "25eb905-1232-082132-aw12320do4r",
    name: {
      use: "official",
      family: "Doe",
      given: ["John"],
      suffix: ["MD"],
    },
    birthDate: "1990-01-01",
    gender: "Male",
  },
});

// Update ambient options
sdkClient.setAmbientOptions({
  sections: [{ loinc: "48765-2" }, { loinc: "10157-6" }, { loinc: "10164-2" }],
});

Ambient status

The SDK provides a way to monitor the status of the ambient session. You can listen for various events related to the ambient session, such as when it starts, pauses, resumes, or submits.

sdkClient.on("ambient:update", (flags) => {
  console.log("Status flags", flags.isAmbientInProgress, flags.isAmbientPaused);
});
  • isAmbientInProgress returns true if an ambient session is currently active—meaning it has been started and has not been cancelled or successfully submitted.
  • isAmbientPaused indicates whether the ambient session is currently in a paused state.

Problem based charting

Problem-based charting is a structured approach to clinical documentation that focuses on the patient’s problems and their management.

The Suki SDK supports problem-based charting by allowing you to pass an isPBNSection boolean flag along with LOINC codes in the ambientOptions. This helps define which section of the note should be treated as the Problem-Based Note (PBN). To view list of PBN supported LOINC sections, refer to the note sections documentation.

Example

sdkClient.mount({
  rootElement: document.getElementById("suki-root"),
  encounter: encounterDetails,
  ambientOptions: {
    sections: [
      { loinc: "51848-0", isPBNSection: true },
      { loinc: "11450-4" },
      { loinc: "29545-1" },
    ],
  },
});

Important Notes

  • You can explicitly pass true or false for the isPBNSection flag. The value provided will be respected as-is.
  • Only one section can have isPBNSection: true. If more than one section is marked as PBN, the ambient session will fail to start.
  • If no section includes the isPBNSection flag: (i.e. leave it undefined)
    • And if the Assessment & Plan section (51847-2) is present without an explicit flag, then that section will automatically be treated as the PBN
  • If you explicitly set isPBNSection: false on the Assessment & Plan section, the automatic default behavior will not apply.

For a given ambient session, only one section can have isPBNSection: true. If more than one section is marked as PBN, the ambient session will fail to start.

Offline Mode

To ensure session robustness, the SDK supports an offline mode that allows it to continue functioning seamlessly even during connectivity disruptions. When a session enters offline mode, the SDK will:

  • Continue recording audio
  • Store the audio and metadata locally
  • Automatically attempt to upload the stored data once the connection is restored

During offline mode, session submission is temporarily paused. The user will be notified about the offline status, and the SDK will continuously attempt to reconnect and submit the note once connectivity is reestablished.

A session may switch to offline mode due to various connectivity-related issues, such as:

  • Network interruptions
  • Temporary backend unavailability
  • Latency in audio packet transmission
  • Socket connection drops
  • Token-related authentication failures

Re-Ambient

Each note is associated with a specific patient and encounter. Even if the identifiers remain the same, starting a new ambient session will always create a new note.

To continue working on an existing note, providers can open it in the SDK UI and initiate a re-ambient session. The SDK will intelligently merge the new session with the existing content, allowing seamless continuation.

Session Recovery

In the event of application crashes or unexpected terminations or user abandoning the session(session neither cancelled nor submitted), the SDK will automatically attempt to recover the last ambient session upon next load. This includes:

  • Restoring the last recorded audio
  • Reattaching the last session’s metadata

In such scnearios, the user will be prompted to either generate the note or discard the session. If the user chooses to generate the note, the SDK will proceed with the note generation process as usual in the background.

Always ensure the active ambient session is properly submitted or cancelled when the user is navigating away from the current encounter context. This helps maintain a clean state and prevents unintended session recoveries. We recommend showing a confirmation dialog to the user before navigating away, allowing them to decide whether to continue or discard the session.