09.03.2026

Today’s release includes the following updates:

ui

  • Prescribers can now review and sign a prescription without an SPI (Surescripts Prescriber Identifier) number on file.
    • SPI is only needed to transmit a prescription electronically through Surescripts, so it no longer blocks review and sign for prescribers who don’t transmit that way, such as direct-integration or compounding workflows.
    • A prescription whose prescriber has no SPI still offers no send action. The same applies to Refill and Adjust Prescription.
    • An NPI number is still required to sign, and controlled-substance prescribing is still gated by EPCS enrollment.

bugfix

  • Fixed an issue in the appointment scheduling modal where free-text fields would grey out and lose the cursor mid-word while a scheduling plugin was installed, sometimes discarding characters. Reason for Visit, Comments, Event Title, and any text field a plugin adds now stay editable while the form refreshes.

sdk

  • Plugins can now dock an application in a persistent pane on an edge of the screen: left, right, top, or bottom.
    • The pane stays mounted as staff move around Canvas, so it keeps its state instead of being rebuilt on every page. on_context_change() hands it each new page’s context, and the pane reloads only if the plugin asks it to.
    • A plugin decides who gets a pane. visible() is asked per staff member, so a dock can be scoped to a team or a role rather than appearing for everyone once the plugin is installed.
    • Staff resize a pane by dragging its divider or with the arrow keys, and Canvas remembers the size each pane was left at. A plugin can resize its own pane too, collapse it to a thin rail, or remove it.
    • Up to two panes can share an edge. Left and right panes together take at most half the window’s width, and top and bottom panes at most half its height.
  • Plugins can now drive their own automations in a note, rather than clinicians having only the ones built into Canvas. A plugin adds an action button in the new NOTE_BODY_AUTOMATION location, and it appears in the note body’s / menu alongside the native commands, marked with a plug icon.
    • It is an ordinary action button, so handle() can return any effects. What the location is meant for is a BatchOriginateCommandEffect with replace_line=True, which originates a set of commands onto the line the clinician typed the trigger on.
    • visible() decides who sees an entry and where. Its context carries the signed-in staff member alongside the note and the patient, so an entry can be limited to particular staff as well as to particular notes or patients. PRIORITY orders it within the menu.
  • Four more records are now readable through the SDK data module, covering the Surescripts change and cancel workflows:
    • PrescriptionChangeResponse: the approve or deny recorded against a change request, with the response type, the status, and the response detail fields.
    • PrescriptionChangeRequest: the pharmacy’s incoming change request, with its medication codings and the prescription it relates to.
    • CancelPrescription: a request to cancel a patient’s prescription, with the prescription, the patient, the note, the message, and the status.
    • CancelPrescriptionResponse: the response to a cancel request, linked one to one to the request that produced it.
  • Fixed an issue where a self-pay coverage reported a stale Failed eligibility status to plugins. A self-pay coverage now reports NOT_APPLICABLE, and the stale response behind it is never surfaced.
  • Fixed an issue where a field a plugin adds to the appointment scheduling modal with editable=False was still editable. The flag had never taken effect; it now makes the field read-only.