Skip to main content

Set up the SDK

Follow these steps once per environment. Each step says who does it.

Enable the SDK​

Nabla

Contact connect@nabla.com to enable the Nabla Connect SDK for your organization.

Allowlist your origins​

Nabla Admin

Nabla only exchanges messages with pages whose origin you have allowlisted.

  1. Open Nabla Connect Admin.
  2. Under Target origin allowlist (front integration), click Add target origin.
  3. Enter one or more origins, comma-separated, for example https://ehr.example.com,https://staging.ehr.example.com.
  4. Save.

An origin is scheme://host:port, with no path and no trailing slash. It must match the page that embeds the iframe exactly, including scheme, hostname, and port. Use HTTPS origins.

danger

Removing an origin breaks live launches. POST /encounters rejects the removed origin immediately, so an integration that still uses it stops creating encounters. Encounters already launched keep the origin they were launched with.

Pass target_origin​

Backend

When your backend calls POST /encounters, set target_origin to the origin of the page that will embed the iframe. It must be in the allowlist, and a well-formed origin. Otherwise the call returns 400 with target_origin <origin> is not in the allowlist or target_origin must be a well-formed URL origin.

{
"external_encounter_id": "enc-42",
"external_provider_id": "prov-7",
"provider_email": "dr.smith@example.com",
"target_origin": "https://ehr.example.com"
}

Without target_origin, the iframe loads normally but sends nothing to the parent page, and ready rejects with TIMEOUT.

Embed the iframe​

Browser

Same requirements as any Connect embed, with one difference: render the iframe without a src. The SDK loads the encounter URL for you. See Launch encounters for the allow list.

<iframe id="nabla" allow="microphone; clipboard-write"></iframe>

A client is bound to its iframe. If another client is created on the same iframe, or another document or origin loads in it, the client emits CONTEXT_CHANGED. Call destroy() before removing or replacing the iframe. If the iframe reloads, the client reconnects on its own.

Install​

Browser
npm install @nabla/connect-sdk

Create the client​

Browser

Pass the iframe and the encounter URL from your backend to NablaConnect.create. The SDK takes the Connect origin from the URL. It must be HTTPS, except on localhost, 127.0.0.1 and [::1].

Encounter URLs only, from POST /encounters or POST /encounters/url. A settings URL (POST /settings/url) is not an encounter: load it in a plain iframe without the SDK. A client created on it never gets a first state.

import { NablaConnect } from "@nabla/connect-sdk";

const iframe = document.getElementById("nabla") as HTMLIFrameElement;
const client = NablaConnect.create({ iframe, url: encounterUrl }); // encounterUrl comes from your backend

client.addEventListener("stateChanged", ({ detail: state }) => {
recordButton.disabled = !state.availableActions.includes("START_RECORDING");
closeButton.disabled = !state.canBeClosed;
});

client.addEventListener("noteExported", ({ detail }) => {
saveToChart(detail.note, detail.transcript);
});

client.addEventListener("error", ({ detail: error }) => {
console.warn("Nabla Connect", error.code, error.reason);
});

try {
const state = await client.ready; // the stateChanged listener above has already received the first state
if (state.availableActions.includes("START_RECORDING")) {
await client.startRecording();
}
} catch (error) {
// A NablaConnectError. TIMEOUT keeps the client listening: the first state still arrives on stateChanged.
// Any other code ends the client: create a new one to retry.
}

create is synchronous. ready resolves with the first state once the iframe has loaded and is connected, or rejects 30 seconds after create.

create throws a TypeError when the iframe does not belong to a window. Nothing else throws: every failure is a NablaConnectError. ready rejects with UNSUPPORTED_VERSION, INVALID_ORIGIN, TIMEOUT, CONTEXT_CHANGED, UNKNOWN, or DESTROYED. A rejected ready ends the client, so create another one to retry. TIMEOUT is the exception: the iframe may still be waiting on the provider (sign-in, onboarding), so the client keeps listening and stateChanged delivers the first state when it comes. Commands called before that state reject with TIMEOUT. A failure before ready rejects ready only: it does not reach the error event, except a failure that ends the client after a TIMEOUT, which is reported on error since ready already settled.

If ready rejects with TIMEOUT, see Troubleshooting.