Write-back messages¶
The panel talks to your page with window.postMessage. Every message arrives at the listener you registered. Always check event.origin before reading event.data.
| Message | Identified by | When |
|---|---|---|
| Clinical note | No type; has a summary array |
Clinician presses Send to EHR |
| Codification | type: "icd-automation" |
Clinician sends from Codify and Automate (accounts with codification) |
| Close | type: "sahl:close" |
Clinician finishes and the panel can be closed |
| Authentication error | type: "AUTH_ERROR" |
Secure JWT handshake failed |
| Handshake ready | type: "SAHL_IFRAME_READY" |
Panel loaded (secure modes) |
When codification is enabled, one send produces two messages: first the clinical note, then the codification envelope. Branch on data.type:
function handleSahlData(data) {
switch (data?.type) {
case "icd-automation":
return applyCodification(data.data);
case "sahl:close":
return closeSahlPanel();
case "AUTH_ERROR":
return reportSahlError(data.error);
case "SAHL_IFRAME_READY":
return; // handled by the handshake code
default:
if (Array.isArray(data?.summary)) return applyClinicalNote(data);
}
}
Be tolerant of new fields
We add fields to these payloads over time. Ignore any field you do not recognise, and do not fail validation because one is present.
Clinical note¶
{
"promptId": "2a2a3817-41db-447f-81bd-38b7066e3a02",
"summary": [
{
"title": "Chief Complaint",
"body": ["- Headache for three days."],
"editedBody": null,
"show": true
},
{
"title": "History of Present Illness",
"body": ["- Throbbing frontal headache, worse in the morning.", "- No visual disturbance."],
"editedBody": ["- Throbbing frontal headache, worse in the morning, for three days.", "- No visual disturbance or vomiting."],
"show": true
},
{
"title": "Assessment and Plan",
"body": ["- Tension-type headache.", "- Paracetamol 1 g as needed; review in one week."],
"editedBody": null,
"show": true
}
]
}
| Field | Type | Description |
|---|---|---|
promptId |
string | The note template used. |
summary |
array | Ordered note sections. Sections with no documented content are left out. |
summary[].title |
string | Section heading. The template defines titles and order. |
summary[].body |
string[] | Generated content, one entry per line. |
summary[].editedBody |
string[] | null | The clinician's edited version, if they changed the section. |
summary[].show |
boolean | Whether the section is shown by default. |
Use the clinician's edits
When editedBody is a non-empty array, it is the reviewed text. File it instead of body.
Codification¶
The standard payload is shown below. If Sahl AI has built a response mapping for your organization, field names and code sets follow your specification instead.
{
"type": "icd-automation",
"data": {
"chiefComplaints": [
{ "complaint": "Headache", "description": "Headache", "code": "R51" }
],
"diagnoses": {
"principal": { "description": "Migraine, unspecified", "code": "G43.9" },
"additionalDiagnosis": [
{ "description": "Type 2 diabetes mellitus without complications", "code": "E11.9", "condition": "Better" }
]
},
"medications": [
{
"name": "Nexium 20 mg Tablet",
"code": "PGIT0244",
"method": "Oral",
"quantity": "",
"dosage": "20 MG",
"frequency": "Once Daily",
"duration": "For 5 Days",
"prescriptionInstructions": ""
}
],
"orders": [
{ "code": "L230", "name": "VITAMIN B 12 (VIT B12)" }
],
"physicalExaminations": [
{
"code": "29",
"name": "Chest and Heart",
"bodyPart": "Chest",
"mentionedLinkedExaminations": "Normal heart sounds, no murmurs",
"type": "Normal"
}
],
"allergies": [
{
"allergen": "Almond",
"code": 256350002,
"name": "Almond",
"description": "",
"type": "Food",
"severity": "Moderate",
"reactions": ["Urticaria"]
}
],
"summary": [ { "title": "Chief Complaint", "body": ["- Headache for three days."], "editedBody": null, "show": true } ]
}
}
| Field | Description |
|---|---|
chiefComplaints[] |
Accepted chief complaints with codes. |
diagnoses.principal |
Principal diagnosis: description and ICD-10 code. |
diagnoses.additionalDiagnosis[] |
Secondary diagnoses. condition is the clinician's status (for example Better, Same, Worse). |
medications[] |
Accepted medications. code comes from your drug master list once it is loaded. |
orders[] |
Accepted lab, radiology and procedure orders. code comes from your order catalogue. |
physicalExaminations[] |
Examination findings by body system. type is Normal or Abnormal. |
allergies[] |
Allergies. code is SNOMED CT where available. |
summary |
The clinical note sections, the same shape as the clinical note. |
Only items the clinician accepted in the panel are sent. Items they rejected or left unreviewed are not included.
Codes match your masters
Medication and order codes are matched against the master lists loaded for your organization. Until your masters are loaded, staging returns codes from Sahl AI's default catalogue, which will not match your EHR. When nothing can be matched with confidence, the field is sent empty rather than guessed.
Close¶
Sent when the clinician finishes in the panel. Close or collapse your container. The iframe does not need to be destroyed; reset its src for the next encounter.
Authentication error¶
Sent by the Secure JWT handshake when the assertion is rejected or the handshake payload is malformed.