Skip to main content

Overview

An ambient session is the core of the Suki Platform. The SDK listens to patient-provider conversations and generates clinical notes along with transcripts in real-time. The SDK is designed to be embedded in your application and automatically manages user states, recording flows, and error handling, providing a seamless experience for your users. Note generation requires predefined sections to organize content. You can configure sections using either predefined note types or LOINC codes. The SDK generates notes based on the conversation and configured sections.
LOINC code support is available in version 2.0 and above of Suki.js with a limited set of codes. Refer to the note sections documentation for the complete list. If you are using an older version, contact support to configure note types.

What Will You Learn?

In this guide, you will learn how to:
  • Implement ambient sessions using the Suki web SDK.
  • Ambient event lifecycle management.
  • Problem-based charting support.
  • Offline mode support.

Session Management

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

Uncontrolled Mode

The user interacts only with buttons and controls within the SDK UI. The SDK manages the session lifecycle automatically.

Controlled Mode

In addition to SDK UI controls, external triggers from your EHR system manage the session lifecycle (starting, stopping, resuming). The SDK handles recording and note generation while your application maintains control over the session lifecycle.

Implementation

Controlled Session Management

The following example shows how to implement controlled session management in JavaScript and React.
  • JavaScript
  • React
controlled.js
import { initialize } from "@suki-sdk/js";

let isSukiReady = false;

// Replace 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...", // 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;
});

// Ambient session control functions
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 resumeAmbient() {
  if (isSukiReady) {
    sdkClient.resumeAmbient();
  } 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 submitAmbient() {
  if (isSukiReady) {
    sdkClient.submitAmbient();
  } else {
    console.error("Suki SDK is not ready yet.");
  }
}

// Attach event listeners to buttons
document.getElementById("start-ambient").addEventListener("click", startAmbient);
document.getElementById("pause-ambient").addEventListener("click", pauseAmbient);
document.getElementById("resume-ambient").addEventListener("click", resumeAmbient);
document.getElementById("cancel-ambient").addEventListener("click", cancelAmbient);
document.getElementById("submit-ambient").addEventListener("click", submitAmbient);

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

Update Encounter and Ambient Options

You can dynamically update encounter data or ambient options when a new encounter is loaded in the EHR.
  • JavaScript
  • React
JavaScript
// Update encounter data
sdkClient.setEncounter({
  identifier: "qsc2393g-b0b1-499d-a4e9-983cq125g5op",
  patient: {
    identifier: "25eb905-1232-082132-aw12320do4r",
    name: {
      use: "official",
      family: "Smith",
      given: ["Jane"],
      suffix: [],
    },
    birthDate: "1985-05-15",
    gender: "Female",
  },
});

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

Ambient Session Status

The SDK provides real-time status monitoring for ambient sessions. You can listen for various events related to the ambient session lifecycle. The ambient:update event is now emitted with ambientId field. This field is the unique identifier for the ambient session. You can use this identifier to track the ambient session lifecycle in web SDK. For more information, refer to the emitterevents-type section.

Ambient Session Lifecycle Events

The following events are emitted when the ambient session lifecycle changes: You can use these events to track the ambient session lifecycle in your application.
  • ambient:start - Emitted when a new ambient session is started.
  • ambient:pause - Emitted when the ambient session is paused.
  • ambient:resume - Emitted when the ambient session is resumed.
  • ambient:cancel - Emitted when the ambient session is cancelled.
  • ambient:submit - Emitted when the ambient session is submitted.
  • JavaScript
  • React
JavaScript
sdkClient.on("ambient:update", (flags) => {
  console.log("Ambient in progress:", flags.isAmbientInProgress);
  console.log("Ambient paused:", flags.isAmbientPaused);
});
// lifecycle events supported by the Web SDK
sdkClient.on("ambient:start", (ambientSessionId) => {  // New in v2.0.4
console.log("Ambient started:", ambientSessionId);
});

Status Flags

isAmbientInProgress
boolean
Returns true if an ambient session is currently active (started and not cancelled or submitted).
isAmbientPaused
boolean
Returns true if 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 patient 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 defines which section should be treated as the Problem-Based Note (PBN).

Supported PBN LOINC Sections

View the complete list of PBN-supported LOINC sections in the note sections documentation.

Implementation

  • JavaScript
  • React
JavaScript
sdkClient.mount({
  rootElement: document.getElementById("suki-root"),
  encounter: encounterDetails,
  ambientOptions: {
    sections: [
      { loinc: "51848-0", isPBNSection: true }, // Assessment and Plan as PBN
      { loinc: "11450-4" },
      { loinc: "29545-1" },
    ],
  },
});

Configuration Rules

1

Single PBN Section

Only one section can have isPBNSection: true. If multiple sections are marked as PBN, the ambient session will fail to start.
2

Explicit Flag Values

You can explicitly pass true or false for the isPBNSection flag. The value provided will be respected as-is.
3

Default Behavior

If no section includes the isPBNSection flag (i.e., left undefined) and the Assessment & Plan section (51847-2) is present, that section will automatically be treated as the PBN.
4

Override Default

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

The SDK supports offline mode to ensure session robustness during connectivity disruptions. When a session enters offline mode, the SDK continues functioning seamlessly.
New:Instead of entering offline mode immediately when it detects a network issue, the Web SDK now uses a 15-second buffer to handle temporary connection problems. This new mechanism gives you time to show a notification in your UI, like Connection unstable, before the session goes fully offline.

Connectivity Issues That Trigger Offline Mode

A session may switch to offline mode due to various connectivity-related issues:
  • Network interruptions
  • Temporary backend unavailability
  • Latency in audio packet transmission
  • Socket connection drops
  • Token-related authentication failures

Offline Mode Behavior

When the session enters offline mode, the SDK automatically:

Continues Recording

Audio recording continues without interruption during network issues.

Local Storage

Audio and metadata are stored locally on the device.

Automatic Upload

Stored data is automatically uploaded once connection is restored.

User Notification

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

Re-Ambient Sessions

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:
1

Open Existing Note

Open the existing note in the SDK UI.
2

Initiate Re-Ambient

Start a re-ambient session from the note interface.
3

Intelligent Merge

The SDK intelligently merges the new session content with existing note content, allowing seamless continuation.

Session Recovery

In the event of application crashes, unexpected terminations, or abandoned sessions (neither cancelled nor submitted), the SDK automatically attempts to recover the last ambient session upon next load.

Recovery Process

The SDK recovery includes:
The last recorded audio is restored and made available for processing.
Session metadata (encounter details, timestamps, configuration) is reattached to maintain continuity.
The user is prompted to either generate the note or discard the session. If the user chooses to generate the note, the SDK proceeds with note generation in the background.

Best Practices

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

Next Steps

Read more about the Note Management and Advanced Configuration to learn more about the SDK and how to use it.