ScribeberryScribeberry Docs

Widget API Reference

Complete schemas, field types, and validation rules for the Partner Widget postMessage API.

This page documents every field Scribeberry accepts and emits for the Partner Widget. For setup and a working example, see Partner Widget.

All postMessage payloads are JSON objects with a required type string. Always verify event.origin === 'https://app.scribeberry.com' (or your configured Scribeberry host) before handling messages.

HTTP: Token endpoint

Mint session tokens server-side only. Never expose your partner key to the browser.

POST https://app.scribeberry.com/api/widget/token
X-Partner-Key: your-partner-id.your-secret
Content-Type: application/json

Request body

FieldRequiredTypeDescription
userEmailYesstringValid email address. Used to create or link the clinician's Scribeberry account.
emrUserIdYesstringYour stable identifier for this clinician (min length 1).
emrSessionIdNostringYour session or encounter identifier. When provided, Scribeberry reopens the same scribe on relaunch. Omit only if clinicians should pick scribes manually.

Success response

{
  "success": true,
  "data": {
    "token": "eyJ...",
    "expiresAt": "2026-08-12T12:00:00.000Z"
  }
}
FieldTypeDescription
tokenstringJWT for the iframe ?token= query parameter. Default expiry is 24 hours.
expiresAtstringISO 8601 expiry timestamp.

Common HTTP errors

StatusMeaning
401Missing or invalid X-Partner-Key header
400Invalid request body (e.g. malformed userEmail)
429Rate limited (20 requests/minute per IP)

EMR → Scribeberry messages

PATIENT_CONTEXT

Send when the chart opens or when the active patient, encounter, or clinical context changes.

{
  type: 'PATIENT_CONTEXT',
  patient: WidgetPatient,           // required
  context?: WidgetMedicalContext,   // optional
  appointment?: WidgetAppointment,    // optional
  noteConfig?: WidgetNoteConfig,      // optional
}

patient (WidgetPatient)

FieldRequiredTypeDescription
idYesstringYour stable patient identifier (non-empty after trimming). Returned on PUSH_NOTE.patientId and PUSH_DOCUMENT.patientId. Use the same id your EMR uses to route notes back to the chart.
nameYesstringPatient full name (non-empty after trimming).
firstNameNostringFirst name. If omitted, parsed from name.
lastNameNostringLast name. If omitted, parsed from name.
dobNostringDate of birth. Recommended format: YYYY-MM-DD.
genderNoenumOne of male, female, other, unknown. Case-insensitive"Male" is accepted and normalized to "male".
healthCardNumberNostringProvincial health number / PHN.
emailNostringValid email address, or empty string "".
phoneNostringContact phone number.

Example — minimum valid patient:

{
  "id": "patient-123",
  "name": "James Wilson"
}

Example — full demographics:

{
  "id": "patient-123",
  "name": "James Wilson",
  "firstName": "James",
  "lastName": "Wilson",
  "dob": "1985-03-15",
  "gender": "male",
  "healthCardNumber": "1234567890",
  "email": "james@example.com",
  "phone": "+1-555-0100"
}

context (WidgetMedicalContext)

All fields are optional. Omit the entire context object if you have no clinical data to send.

FieldTypeDescription
allergiesWidgetAllergy[]Known allergies
medicationsWidgetMedication[]Current medications
diagnosesWidgetDiagnosis[]Active or historical diagnoses
labResultsWidgetLabResult[]Recent lab values
chiefComplaintstringReason for visit
medicalHistorystringFree-text past medical history
customDataobjectArbitrary key/value data for your integration

allergies[]

FieldRequiredTypeDescription
nameYesstringAllergen name
severityNoenummild, moderate, or severe (case-insensitive)
reactionNostringReaction description

medications[]

FieldRequiredTypeDescription
nameYesstringMedication name
dosageNostringDose (e.g. "500mg BID")
frequencyNostringFrequency
startDateNostringStart date
statusNoenumactive or discontinued (case-insensitive)

diagnoses[]

FieldRequiredTypeDescription
nameYesstringDiagnosis description
codeNostringCode value (e.g. ICD-10)
codeSystemNostringCode system (e.g. "ICD-10")
dateNostringDiagnosis date
statusNoenumactive or resolved (case-insensitive)

labResults[]

FieldRequiredTypeDescription
nameYesstringTest name
valueNostringResult value
unitNostringUnit of measure
dateNostringCollection or result date
normalRangeNostringReference range

appointment (WidgetAppointment)

FieldRequiredTypeDescription
idNostringYour appointment identifier
dateTimeNostringISO 8601 datetime
typeNostringVisit type (e.g. "Follow-up")
durationNonumberDuration in minutes
reasonNostringAppointment reason

noteConfig (WidgetNoteConfig)

Define the shape of structured note output. When provided, template selection is locked to the resolved template for these section labels.

FieldRequiredTypeDescription
sectionsYesarray1–20 ordered sections

Each section:

FieldRequiredTypeDescription
keyYesstring1–64 chars. Must match /^[a-zA-Z][a-zA-Z0-9_]*$/. Returned as the key in PUSH_NOTE.sections.
labelYesstring1–128 chars. Heading label used for note generation and template resolution.

Classic SOAP labels (Subjective, Objective, Assessment, Plan) resolve to Scribeberry's curated SOAP template. Other label sets get a synthetic heading-based template. If noteConfig is omitted, SOAP is used.


SET_CONTEXT

Append or replace free-text context outside the structured context object.

{
  type: 'SET_CONTEXT',
  context: string,                    // required
  mode?: 'append' | 'overwrite',     // default: 'append'
}

TOKEN_REFRESH

Extend the session without reloading the iframe.

{
  type: 'TOKEN_REFRESH',
  token: string,   // new JWT from POST /api/widget/token
}

CLOSE_WIDGET

Signal that the user left the chart. Scribeberry may tear down active state.

{
  type: 'CLOSE_WIDGET',
}

Scribeberry → EMR messages

WIDGET_READY

Widget loaded and ready to receive PATIENT_CONTEXT.

{
  type: 'WIDGET_READY',
  version: string,
}

SESSION_STARTED

Sent when an encounter-scoped scribe opens or resumes (emrSessionId was included in the token).

{
  type: 'SESSION_STARTED',
  sessionId: string,   // Scribeberry conversation id — store against your emrSessionId
}

PUSH_NOTE

Clinician sent a generated note to your EMR.

{
  type: 'PUSH_NOTE',
  note: string,                        // full note text — always present
  sections?: Record<string, string>,   // keyed by noteConfig section keys; "" if section not found
  transcript?: string,                 // visit transcript when available
  sessionId: string,                   // Scribeberry conversation id
  patientId: string,                   // your patient.id from PATIENT_CONTEXT
}

Notes can be sent multiple times per session (e.g. after edits).

PUSH_DOCUMENT

Clinician sent a document (letter, referral, form, or PDF).

{
  type: 'PUSH_DOCUMENT',
  title: string,
  content: string,
  documentType: 'letter' | 'referral' | 'form' | 'pdf',
  pdfUrl?: string,
  sessionId: string,
  patientId: string,
}

REQUEST_PATIENT_CONTEXT

Widget needs current patient data. Respond with PATIENT_CONTEXT.

{
  type: 'REQUEST_PATIENT_CONTEXT',
}

TOKEN_EXPIRING

Token will expire soon. Mint a new token and send TOKEN_REFRESH.

{
  type: 'TOKEN_EXPIRING',
  expiresInMs: number,
}

REQUEST_TOKEN_REFRESH

Widget is actively requesting a new token. Respond with TOKEN_REFRESH.

{
  type: 'REQUEST_TOKEN_REFRESH',
}

TOKEN_EXPIRED

Token has expired. Reload the iframe with a new token.

{
  type: 'TOKEN_EXPIRED',
}

WIDGET_ERROR

Validation or processing error. Handle this in your postMessage listener.

{
  type: 'WIDGET_ERROR',
  code: string,
  message: string,
}
CodeWhen
INVALID_PATIENT_DATAPATIENT_CONTEXT.patient failed validation

The message field contains field-level details, for example:

id: Patient ID is required; gender: Invalid enum value...

Common validation failures:

IssueFix
Missing patient.idInclude your EMR's stable patient identifier
Missing patient.nameInclude the patient's full name
Invalid genderUse male, female, other, or unknown (any casing)
Invalid emailProvide a valid email or omit the field
Invalid noteConfig.sections[].keyKeys must start with a letter and contain only letters, digits, and underscores

Patient ID semantics

  • patient.id is your EMR identifier. Scribeberry echoes it on PUSH_NOTE.patientId so you can file notes back to the correct chart row.
  • Internally, Scribeberry namespaces widget patients as widget_{partnerId}_{patientId} for conversation grouping. Your raw id is never used as a Scribeberry account patient UUID.
  • Use stable ids — auto-increment integers are fine as long as they are unique within your EMR and consistent across sessions for the same person.

Enum normalization

These string enums are case-insensitive. Values are trimmed and lowercased before validation:

FieldAccepted values
patient.gendermale, female, other, unknown
context.allergies[].severitymild, moderate, severe
context.medications[].statusactive, discontinued
context.diagnoses[].statusactive, resolved

Unrecognized enum values fail validation with a field-level error in WIDGET_ERROR.message.