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

# Headless Web SDK Ambient Interoperability

> Share one clinical note across Headless Web SDK, Mobile SDK, Web SDK, and Ambient APIs by passing emrEncounterId on session.create

<div className="quick-summary-wrapper">
  <div className="quick-summary-header">
    <span className="quick-summary-icon" aria-hidden="true" />

    <span className="quick-summary-title">Quick summary</span>
  </div>

  <div className="quick-summary-content">
    Ambient interoperability lets clinicians continue the same clinical note across the Headless Web SDK, Mobile SDK, Web SDK, and Ambient APIs. In the Headless Web SDK, pass `emrEncounterId` on `session.create()` so the note is shared. Pass and reuse `encounterId` for every re-ambient session on that note.
  </div>

  <div className="quick-summary-footer">
    <span className="quick-summary-footer-icon" aria-hidden="true" />

    <span className="quick-summary-footer-text">Last updated:</span>
    <span className="quick-summary-footer-date">September 2026</span>
  </div>
</div>

<Warning>
  * Interoperability applies only to **Ambient workflows**. It is not supported for Dictation or Form filling.
  * Versions **`v0.3.0`** and later of `@suki-sdk/platform` and `@suki-sdk/platform-react` support interoperability for the Headless Web SDK.
</Warning>

Ambient interoperability lets you use multiple Suki products that support ambient workflows with the same clinical note for a patient encounter.

Before ambient interoperability, each ambient session belonged to the Suki product where it was created. For example, if you started a session with the Headless Web SDK, you could only continue or retrieve that session from the Headless Web SDK.

With <Tooltip tip="Interoperability is the ability of different systems, devices, or software applications to communicate, exchange data, and use that information seamlessly." cta="View in Glossary" href="/Glossary/i">interoperability</Tooltip>, you can create and access ambient sessions across Ambient APIs, Mobile SDK, Headless Web SDK, and Web SDK for the same patient encounter. Pass `emrEncounterId` to make the note interoperable. For re-ambient workflows, pass `encounterId` (maps to Ambient API `encounter_id`) and reuse it for every session on that note.

In the Headless Web SDK, you can:

* Start an interoperable ambient session by passing `emrEncounterId` on `session.create()`.
* Continue a clinical note in Headless that started in the Mobile SDK, Web SDK, or Ambient APIs.
* Continue a clinical note that started in Headless in another Suki product.
* Clear a remote session conflict, then retry create. Refer to [Handle ambient session conflicts](/headless-web-sdk/guides/handle-ambient-session-conflicts).
* Keep recording UI in sync when another Suki product cancels or ends the live session. Refer to [Handle ambient session conflicts](/headless-web-sdk/guides/handle-ambient-session-conflicts#what-happens-when-another-suki-product-ends-the-live-session).
* List shared notes and seed patient context for Web SDK review. Refer to [Read shared ambient notes](/headless-web-sdk/guides/read-shared-ambient-notes).

## How Ambient interoperability works in the Headless Web SDK

When you call `session.create()`, pass `emrEncounterId` to identify the patient's EMR or EHR encounter and make the note interoperable. Pass `encounterId` on every create. For re-ambient workflows, reuse the same `encounterId` for every session on that note.

The table below shows how Headless Web SDK identifiers map to the corresponding Ambient API fields.

| Headless Web SDK                                      | Ambient APIs             | Available                                           | Description                                                                                                                                                                                                                                             |
| ----------------------------------------------------- | ------------------------ | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`emrEncounterId`**                                  | **`emr_encounter_id`**   | Passed to `session.create()`                        | Identifies the patient encounter in your EMR or EHR. Required to enable ambient interoperability. Accepts a **UUID or non-UUID** value, at most **36 characters**.                                                                                      |
| **`encounterId`**                                     | **`encounter_id`**       | Passed to `session.create()` (required)             | Groups re-ambient sessions for the same note. Reuse the same value for every session on that note.                                                                                                                                                      |
| **`ambientSessionId`** (create response / hook state) | **`ambient_session_id`** | Returned on every successful create                 | Identifies the current ambient session. Pass this value to `useAmbientSession`.                                                                                                                                                                         |
| **`noteId`** (create response / hook state)           | **`note_id`**            | Returned on every successful create                 | Identifies the shared clinical note. Store this value for note-level Ambient APIs.                                                                                                                                                                      |
| **`blockingSessionId`** (on `sessionAlreadyExists`)   | **`ambient_session_id`** | Returned only when a remote session conflict occurs | Identifies the active ambient session running in another Suki product. Pass this value to `cancelRemote` or `endRemote` before retrying create. Refer to [Handle ambient session conflicts](/headless-web-sdk/guides/handle-ambient-session-conflicts). |

<Warning>
  Do not confuse these fields:

  | Headless field         | Maps to                                              | Does not map to                    |
  | ---------------------- | ---------------------------------------------------- | ---------------------------------- |
  | **`emrEncounterId`**   | Ambient API **`emr_encounter_id`**                   | Ambient API **`encounter_id`**     |
  | **`encounterId`**      | Ambient API **`encounter_id`** (re-ambient grouping) | Ambient API **`emr_encounter_id`** |
  | **`ambientSessionId`** | Ambient API **`ambient_session_id`**                 | Ambient API **`encounter_id`**     |
  | **`noteId`**           | Ambient API **`note_id`**                            | Ambient API **`encounter_id`**     |
</Warning>

<Note>
  **Product differences:**

  * **Web SDK** uses `encounter.identifier` for `emr_encounter_id` only. It does not take `encounter_id` on create.
  * **Mobile SDK** uses `SukiAmbientConstant.kEmrEncounterId` and `SukiAmbientConstant.kSessionId` (where `kSessionId` maps to Ambient API `encounter_id`).
  * **Headless Web SDK** requires `encounterId` on every create, and uses optional `emrEncounterId` for interoperability.
</Note>

Ambient interoperability shares the clinical note, not the audio recording. Each ambient session adds content to the same note. The audio for each session stays tied to that session's `ambientSessionId`.

<Warning>
  If you omit `emrEncounterId` on `session.create()`, the Headless Web SDK still creates an ambient session, but the clinical note is not shared with other Suki products.
</Warning>

## Common integration patterns

Use these patterns when you build interoperable ambient workflows with the Headless Web SDK.

<CardGroup cols={2}>
  <Card title="Capture in Headless, Review on Web" icon="react" href="/headless-web-sdk/guides/read-shared-ambient-notes#seed-patient-context-for-web-sdk-handoff" cta="Learn more">
    Start the clinical note in the Headless Web SDK with `emrEncounterId`, then open it in the Web SDK for review, edit, and submission. Seed patient context before the Web SDK opens the note.
  </Card>

  <Card title="Capture on Mobile, Continue in Headless" icon="mobile">
    Start the clinical note in the Mobile SDK, then continue it in Headless with the same EMR encounter id as `emrEncounterId` and the same re-ambient value as `encounterId`.
  </Card>

  <Card title="Capture in Headless, Continue with APIs" icon="code" href="/headless-web-sdk/guides/read-shared-ambient-notes" cta="Learn more">
    Start the clinical note in Headless, then continue or retrieve it through Ambient APIs using `emr_encounter_id`, `encounter_id`, and `note_id`.
  </Card>

  <Card title="Capture with APIs, Continue in Headless" icon="arrow-right-arrow-left">
    Start the clinical note through Ambient APIs, then continue it in Headless with the same shared encounter values.
  </Card>

  <Card title="Resolve a Cross-Product Conflict" icon="triangle-exclamation" href="/headless-web-sdk/guides/handle-ambient-session-conflicts" cta="Learn more">
    On `sessionAlreadyExists`, read `blockingSessionId` from `error.additionalProperties`, cancel or end the blocking session, then retry create.
  </Card>

  <Card title="Keep the UI in Sync on Remote End" icon="bell" href="/headless-web-sdk/guides/handle-ambient-session-conflicts#what-happens-when-another-suki-product-ends-the-live-session" cta="Learn more">
    Handle `onSessionTerminatedByPeer` to update recording UI when another Suki product cancels or ends the live session.
  </Card>

  <Card title="List Notes for the Visit" icon="list" href="/headless-web-sdk/guides/read-shared-ambient-notes" cta="Learn more">
    Call `useGetEncounterInfo` with `emrEncounterId`, then use Ambient API note-level endpoints with `noteId` for content, context, and structured data.
  </Card>

  <Card title="Seed Context for Web SDK Review" icon="user" href="/headless-web-sdk/guides/read-shared-ambient-notes#seed-patient-context-for-web-sdk-handoff" cta="Learn more">
    When the session may later open in the Web SDK, set patient identity and name on session context so the patient profile stays consistent.
  </Card>
</CardGroup>

## How to enable interoperability in the Headless Web SDK

Pass a stable EMR encounter id to make the note interoperable. Use a **UUID or non-UUID** value, at most **36 characters**. Pass `encounterId` on every create, and reuse the same value for every re-ambient session on that note.

### Create parameters

Pass these values to `session.create()` on `useAmbient`.

<ResponseField name="encounterId" type="string" required>
  Groups re-ambient sessions for the same clinical note. Maps to Ambient API **`encounter_id`**. Pass this on every create. Reuse the same value for every re-ambient session on that note. Do not pass the EMR visit id here, and do not use **`noteId`** as this value.
</ResponseField>

<ResponseField name="emrEncounterId" type="string">
  **Optional**: EMR or EHR encounter id for the patient visit. Maps to Ambient API **`emr_encounter_id`**. Accepts a **UUID or non-UUID** value, at most **36 characters**. Required to enable ambient interoperability. Without this field, create still succeeds, but the note is not shared across Suki products.
</ResponseField>

<ResponseField name="multilingual" type="boolean">
  **Optional**: Enables multilingual ambient capture when supported for your integration.
</ResponseField>

### Create response and hook state

After a successful create, read these values from the promise result or from the `useAmbient` hook when `session.isSuccess` is `true`.

<ResponseField name="ambientSessionId" type="string | null">
  Identifies the current ambient recording session. Maps to Ambient API **`ambient_session_id`**. Pass this value to **`useAmbientSession`**. The hook value is `null` until create succeeds.
</ResponseField>

<ResponseField name="noteId" type="string | null">
  Identifies the shared clinical note. Maps to Ambient API **`note_id`**. Store this value for note-level Ambient APIs. The hook value is `null` until create succeeds. This is **`noteId`**, not **`compositionId`**.
</ResponseField>

### Interop actions on useAmbient

<ResponseField name="session.create" type="(params: { encounterId: string; emrEncounterId?: string; multilingual?: boolean }) => Promise<{ ambientSessionId: string; noteId: string }>">
  Creates a new ambient session. Pass **`emrEncounterId`** when the note must be interoperable. Status flags on `session` update while the request runs.
</ResponseField>

<ResponseField name="cancelRemote" type="(params: { ambientSessionId: string }) => Promise<void>">
  Cancels a remote ambient session that is blocking create in another Suki product. Pass the **`blockingSessionId`** from a `sessionAlreadyExists` error. Available on `useAmbient` before a local session exists. For the full recovery flow, refer to [Handle ambient session conflicts](/headless-web-sdk/guides/handle-ambient-session-conflicts).
</ResponseField>

<ResponseField name="endRemote" type="(params: { ambientSessionId: string }) => Promise<void>">
  Ends a remote ambient session that is blocking create in another Suki product so captured audio can be processed. Pass the **`blockingSessionId`** from a `sessionAlreadyExists` error. For the full recovery flow, refer to [Handle ambient session conflicts](/headless-web-sdk/guides/handle-ambient-session-conflicts).
</ResponseField>

<Steps>
  <Step title="Pass the EMR Encounter ID">
    Set **`emrEncounterId`** to the Ambient API **`emr_encounter_id`**. Use a **UUID or non-UUID** value, at most **36 characters**.
  </Step>

  <Step title="Pass encounterId">
    Set **`encounterId`** to the Ambient API **`encounter_id`** on every create. For re-ambient workflows, store and reuse the same value for every session on that note. Do not use **`noteId`** as this value.
  </Step>

  <Step title="Store the Create Response">
    On success, store **`ambientSessionId`** and **`noteId`**. Use **`ambientSessionId`** with **`useAmbientSession`**. Use **`noteId`** with note-level Ambient APIs. Refer to [Read shared ambient notes](/headless-web-sdk/guides/read-shared-ambient-notes).
  </Step>

  <Step title="Continue Across Products">
    Pass the same shared encounter values through each product's fields. In Headless, keep using **`emrEncounterId`** and **`encounterId`**. Refer to [Use ambient across modalities](/documentation/how-to/ambient-clinical-notes/use-ambient-across-modalities).
  </Step>
</Steps>

### Code example for creating an interoperable session

Use the following code example to start an interoperable ambient session in the Headless Web SDK.

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

export function StartInteroperableSession() {
  const {
    ambientSessionId,
    noteId,
    session,
  } = useAmbient();

  // Reuse the same encounterId for every re-ambient session on this note.
  const existingEncounterId = "visit-note-1";

  const startInteroperableSession = async () => {
    try {
      const result = await session.create({
        encounterId: existingEncounterId,
        emrEncounterId: "6ec3920f-b0b1-499d-a4e9-889bf788e5ab",
        multilingual: true, // optional
      });

      // result.ambientSessionId and result.noteId
      // When session.isSuccess is true, ambientSessionId and noteId are also on the hook return.
      return result;
    } catch (error) {
      // Handle sessionAlreadyExists and other create errors.
      // See Handle ambient session conflicts.
      console.error(error);
      throw error;
    }
  };

  return (
    <button type="button" onClick={() => void startInteroperableSession()}>
      Start interoperable session
    </button>
  );
}
```

<Note>
  Wire mapping for create:

  * `encounterId` → Ambient API `encounter_id`
  * `emrEncounterId` → Ambient API `emr_encounter_id` (required for interoperability)
</Note>

## Available cookbooks

<div className="hp-io-method-grid tut-hub-card-grid" data-cookbook-related-grid>
  <a className="hp-io-method-card tut-hub-method-card" href="/documentation/cookbooks/create-interoperable-headless-session">
    <div className="tut-hub-card-media" aria-hidden="true" />

    <div className="hp-io-method-card-body">
      <div className="tut-hub-card-badges">
        <span className="hp-wn-badge hp-wn-badge-new">Ambient</span>
        <span className="hp-wn-badge cookbook-hub-badge-surface cookbook-hub-badge-surface--sdk">Headless Web SDK</span>
      </div>

      <h3 className="hp-io-method-card-title">Create an Interoperable Headless Session</h3>

      <p className="hp-io-method-card-desc cookbook-hub-card-desc">
        Pass emrEncounterId on Headless create.
      </p>

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

  <a className="hp-io-method-card tut-hub-method-card" href="/documentation/cookbooks/pass-emr-encounter-id">
    <div className="tut-hub-card-media tut-hub-card-media--blue" aria-hidden="true" />

    <div className="hp-io-method-card-body">
      <div className="tut-hub-card-badges">
        <span className="hp-wn-badge hp-wn-badge-new">Ambient</span>
        <span className="hp-wn-badge cookbook-hub-badge-surface cookbook-hub-badge-surface--api">API</span>
      </div>

      <h3 className="hp-io-method-card-title">Share One Note Across Products</h3>

      <p className="hp-io-method-card-desc cookbook-hub-card-desc">
        Share one note with emr\_encounter\_id.
      </p>

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

## Next steps

<Icon icon="file-lines" iconType="solid" /> Refer to [Handle ambient session conflicts](/headless-web-sdk/guides/handle-ambient-session-conflicts) for `sessionAlreadyExists`, `cancelRemote`, `endRemote`, and remote session end handling.

<Icon icon="file-lines" iconType="solid" /> Refer to [Read shared ambient notes](/headless-web-sdk/guides/read-shared-ambient-notes) for `useGetEncounterInfo`, Ambient note APIs, and patient context for Web SDK handoff.

<Icon icon="file-lines" iconType="solid" /> Refer to [Create an interoperable Headless session](/documentation/cookbooks/create-interoperable-headless-session) for a short create and conflict recipe.

<Icon icon="file-lines" iconType="solid" /> Refer to [Create ambient session](/headless-web-sdk/guides/hooks/ambient-hook) for `useAmbient`, create parameters, and create response fields.

<Icon icon="file-lines" iconType="solid" /> Refer to [Ambient interoperability](/documentation/concepts/ambient-clinical-notes/ambient-interoperability) for the platform overview across ambient products.
