Scribe Embedding
Overview
Section titled “Overview”HAMI Scribe listens to the clinician–patient consultation and drafts the clinical documentation: SOAP note, ICD/CPT codes, and after-visit summary. With Scribe embedding, the clinician opens Scribe inside your EHR for the appointment you have just sent to HAMI, instead of switching to a separate app.
The launch link comes back as scribeLaunchUrl in the response of the Universal Ingestion API. When the clinician finishes, HAMI pushes the completed note to your Scribe Webhook.
Prerequisites
Section titled “Prerequisites”Before go-live, the HAMI team configures the following for your group:
| Item | Details |
|---|---|
| Scribe embedding enabled | Switches on scribeLaunchUrl in ingestion responses. |
| Allowed origin | The origin of the EHR page that hosts the Scribe iframe (e.g. https://ehr.yourclinic.com). HAMI sends postMessage events containing encounter or patient identifiers only to this origin. |
| Clinician accounts | Every clinician who will use Scribe needs a HAMI account that is a member of your group. Otherwise they see an error screen at sign-in (see Error codes). |
| Launch link lifetime (optional) | Defaults to 120 minutes and can be adjusted per group. |
| Scribe webhook (optional) | Your HTTPS endpoint and API key, if you want the finished note pushed back. See Scribe Webhook. |
Launch Flow
Section titled “Launch Flow”- Ingest. Your system POSTs the FHIR bundle to the Universal Ingestion API. The response includes
scribeLaunchUrl(https://hamiapp.bostonhealth.ai/scribe/launch?launch_code=...; the host is the HAMI app for your environment). - Open. When the clinician opens the appointment in your EHR, load
scribeLaunchUrlin an iframe (or a new window). - Validate. HAMI checks the launch code without using it up and shows your group’s branding.
- Sign in. The clinician enters their phone number, then a one-time code or their password. A clinician who signed in to an embedded Scribe session recently in the same browser may be recognised automatically. HAMI checks that they belong to your group before using up the launch code, so a clinician who isn’t authorised yet can be added to the group and retry with the same link.
- Start the session. HAMI uses up the single-use launch code, links the session to the appointment’s encounter, and opens the consultation. Your page receives
HAMI_CONSULTATION_LAUNCHED. - Document. The clinician starts Scribe. Once the recording connection is up, your page receives
HAMI_SCRIBE_READY. When the clinician chooses Save & Complete, Scribe saves the transcript and draft note and your page receivesHAMI_SCRIBE_COMPLETE. - Sign off. The clinician signs off the SOAP note and HAMI generates the after-visit summary. Your page receives
HAMI_SOAP_LOCKED. - Deliver. If the Scribe webhook is configured, HAMI POSTs the full clinical note to your endpoint. This happens once per encounter, on the first sign-off.
Iframe Configuration
Section titled “Iframe Configuration”<iframe src="{scribeLaunchUrl}" title="HAMI Scribe" width="100%" height="800" style="border:0; display:block;" referrerpolicy="strict-origin-when-cross-origin" allow="microphone; autoplay; clipboard-write"></iframe>| Permission | Required | Description |
|---|---|---|
microphone | Yes | Scribe captures the consultation audio |
autoplay | Yes | Audio feedback and playback |
clipboard-write | Recommended | Lets the clinician copy note sections into your EHR |
The network requirements are the same as for intake. See Iframe Embedding → Network Connectivity.
Iframe Events (postMessage)
Section titled “Iframe Events (postMessage)”The Scribe iframe tells the host page about progress through window.parent.postMessage. Every message has a type. All messages except the session-timeout form of HAMI_SCRIBE_EXPIRED (see below) also carry source: "hami-scribe".
type | When it is sent | Payload fields |
|---|---|---|
HAMI_CONSULTATION_LAUNCHED | The consultation screen has loaded for this appointment | encounterId, patientId, groupSlug |
HAMI_SCRIBE_READY | The clinician started Scribe and the recording connection is up | encounterId, patientId, groupSlug |
HAMI_SCRIBE_COMPLETE | The clinician chose Save & Complete on the Scribe recording | encounterId, patientId |
HAMI_SOAP_LOCKED | The clinician signed off the SOAP note | encounterId, patientId |
HAMI_SCRIBE_EXPIRED | The launch link has expired or was already used (on the launch screen), or the active session ended because of inactivity or an expired sign-in | On the launch screen: source, code, message. On session timeout: no other fields (just { "type": "HAMI_SCRIBE_EXPIRED" }) |
HAMI_SCRIBE_ERROR | The launch failed for another reason | code, message |
Events that carry encounterId or patientId are sent only to your registered origin. If HAMI does not yet know your origin (for example, the launch code itself was invalid), error and expiry events may be sent without an origin restriction. They never contain patient data.
Error codes
Section titled “Error codes”code | Meaning | Suggested action |
|---|---|---|
TOKEN_EXPIRED | The launch link has expired or was already used | Request a new scribeLaunchUrl by ingesting the appointment again |
SESSION_EXPIRED | The clinician’s embedded session has expired | Open Scribe again with a fresh scribeLaunchUrl |
NOT_REGISTERED | No HAMI account exists for the phone number entered | Ask the HAMI team to create the clinician’s account |
WRONG_PASSWORD | The password was incorrect | The clinician retries |
NOT_AUTHORIZED | The clinician’s account is not a member of your group | Add the clinician to the group, then reload with the same link |
GENERIC | Unexpected error | Reload and try again. Contact support if it persists |
Listening for events
Section titled “Listening for events”// The HAMI app origin for your environment (the host of scribeLaunchUrl)const HAMI_ORIGIN = 'https://hamiapp.bostonhealth.ai';
window.addEventListener('message', (event) => { // Only trust messages from the HAMI iframe. Filter on origin and type, not on `source`, // because the session-timeout HAMI_SCRIBE_EXPIRED message has no `source` field. if (event.origin !== HAMI_ORIGIN || typeof event.data?.type !== 'string') return;
switch (event.data.type) { case 'HAMI_SCRIBE_READY': showRecordingIndicator(event.data.encounterId); break; case 'HAMI_SOAP_LOCKED': // The note is final: expect the Scribe webhook shortly markNotePending(event.data.encounterId); break; case 'HAMI_SCRIBE_EXPIRED': // Session over: ingest again (or reuse a still-unused link) to get a fresh scribeLaunchUrl showScribeExpired(event.data.code ?? 'SESSION_EXPIRED'); break; case 'HAMI_SCRIBE_ERROR': showScribeError(event.data.code, event.data.message); break; }});Security Notes
Section titled “Security Notes”scribeLaunchUrlis a bearer link for one appointment. Render it only for authorised clinicians, and never log it or put it in analytics.- Always check
event.originbefore acting on apostMessageevent. - The clinician always has to sign in with their own HAMI account. The launch link on its own doesn’t give access to patient data.
Support
Section titled “Support”- Email: support@bostonhealth.ai
- Website: bostonhealth.ai