Skip to content

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.

const sectionText = (s) => (s.editedBody?.length ? s.editedBody : s.body).join("\n");

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

{ "type": "sahl: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

{ "type": "AUTH_ERROR", "error": "Unable to authenticate. Please try again." }

Sent by the Secure JWT handshake when the assertion is rejected or the handshake payload is malformed.