Skip to main content
Quick Summary
An ambient session captures patient-provider conversations and generates clinical notes in real-time. The SDK handles recording, note generation, and error handling automatically.

You can manage sessions in two ways: uncontrolled mode where users interact only with SDK UI controls, or controlled mode where your EHR system controls when sessions start and stop through external triggers.

Overview

An ambient session captures patient-provider conversations and generates clinical notes in real-time. The SDK handles recording, note generation, and error handling automatically. To generate notes, you must configure sections that organize the content. You can use either predefined note types or LOINC codes. The SDK creates notes from the conversation using these configured sections.
LOINC code support is available in version 2.0 and above. See the note sections documentation for supported codes. For older versions, contact support to configure note types.

What You’ll Learn

  • How to implement ambient sessions
  • How to manage session lifecycle events
  • How to configure problem-based charting
  • How offline mode works

Session Management

You can manage ambient sessions in two ways:

Uncontrolled Mode

Users interact only with SDK UI controls. The SDK manages the session lifecycle automatically.

Controlled Mode

Your EHR system controls the session lifecycle (start, stop, resume) through external triggers. The SDK handles recording and note generation while your app controls when sessions start and stop.

Implementation

Controlled Session Management

The following example shows how to implement controlled session management in JavaScript and 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
  providerSpecialty: "FAMILY_MEDICINE", // Replace with the provider's specialty
});

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

Update encounter data or ambient options when a new encounter loads in your EHR.
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 emits events to track ambient session status in real-time. The ambient:update event includes an ambientId field, which is the unique identifier for the session. Use this ID to track the session lifecycle. For details, see emitter events types.

Lifecycle Events

The SDK emits these events when the session state changes:
  • 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
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 organizes clinical documentation around patient problems and their management. The SDK supports this by letting you mark a section as the Problem-Based Note (PBN) using the isPBNSection flag with LOINC codes in ambientOptions.

Supported PBN LOINC Sections

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

Implementation

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 keep sessions running during connectivity issues. When offline, the SDK continues recording and processing seamlessly.
New: The SDK uses a 15-second buffer before entering offline mode. This gives you time to show a “Connection unstable” notification before the session goes fully offline.

What Triggers Offline Mode

A session enters offline mode due to:
  • Network interruptions
  • Backend unavailability
  • High latency in audio transmission
  • Socket connection drops
  • 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 ambient session creates a new note, even if the patient and encounter identifiers are the same. To continue working on an existing note:
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

If the app crashes or a session is abandoned (not cancelled or submitted), the SDK automatically recovers the last ambient session when the app loads again.

What Gets Recovered

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 submit or cancel the active ambient session when users navigate away from the encounter. This prevents unintended session recoveries.Recommendation: Show a confirmation dialog before navigation so users can 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.