SMART on FHIR
The interface VoiceboxMD builds to, published so you can evaluate it without a call. Standalone launch, one write scope, and a DocumentReference mapped field by field. You host the endpoints; we are the client.
How the Connection Is Made
Nothing here is bespoke to a vendor. Discovery makes a new EHR a configuration entry rather than a code change, which is the only way an integration programme stays viable past the first few partners.
1. Discovery
We read {fhir-base}/.well-known/smart-configuration to find your authorization and token endpoints, supported scopes and PKCE methods. Nothing is hard-coded per vendor, which is what lets a new EHR be configuration rather than a code change.
2. Standalone launch
The clinician connects from inside VoiceboxMD, so this is a standalone launch rather than an EHR launch. They authenticate against your authorization server with their own credentials and consent to the scopes below. We never see their password.
3. Authorization code with PKCE
Authorization code flow with PKCE using S256. We request offline_access so the token can be refreshed, and handle rotating refresh tokens where your server issues them.
4. Write, as the clinician
The note is written with the clinician’s own delegated token, so your audit log attributes it to them and not to a VoiceboxMD service account. That attribution is the reason to prefer this over a backend-services integration.
Exactly Which Scopes, and Why
Published in full rather than summarised, because a scope list is the first thing a security review asks for and the last thing most integration pages provide. Both SMART v1 and v2 spellings are shown; we request the granular form where your discovery document advertises it.
| SMART v1 | SMART v2 | Why we ask for it |
|---|---|---|
user/DocumentReference.write | user/DocumentReference.c | Create the note. The only write we request. |
user/Patient.read | user/Patient.rs | Resolve and confirm the right patient before writing. Read and search. |
launch/patient | launch/patient | Patient context where your server supports a picker. |
openid fhirUser | openid fhirUser | Identify the signed-in clinician, for the author field. |
offline_access | offline_access | Refresh token. Ambient notes finish after the session. |
The only write requested is DocumentReference create. Patient read is required to resolve the right patient before writing, so the integration is write-only in intent rather than literally.
The DocumentReference We Write
Field by field, so there is nothing to discover during implementation. Note state maps onto docStatus rather than being flattened, because writing an unreviewed draft into a chart as though it were signed is a compliance problem rather than a convenience.
| Field | Value |
|---|---|
resourceType | DocumentReference |
status | current |
docStatus | preliminary for a draft note, final once the clinician finalizes it |
type | LOINC. 11506-3 progress note, 34117-2 history and physical, 11488-4 consult note |
subject | Reference(Patient), resolved and confirmed before the write |
author | Reference(Practitioner), the clinician identified by fhirUser |
authenticator | Reference(Practitioner), populated only on a finalized note |
date | Instant the note was finalized |
context.encounter | Reference(Encounter) where an encounter is in context |
content.attachment.contentType | text/plain or text/html, agreed per integration |
content.attachment.data | The note, base64 encoded |
content.attachment.title | Template name, for example SOAP or Follow-up |
What goes inside the attachment, including the section model and the extracted codes, is on the note format page.
What We Need From Your Side
A FHIR base URL and SMART discovery
R4, with a reachable .well-known/smart-configuration. If discovery is not published we can be configured explicitly, but discovery is what keeps you out of our release cycle.
A registered client
You issue us a client id, and a secret if your server expects a confidential client, along with an approved redirect URI. This is the one step that has to happen on your side, because the credential is yours to grant.
DocumentReference create, and Patient read
Write is genuinely limited to DocumentReference. The Patient read is not optional though: without a way to resolve the right patient there is nothing safe to attach the note to.
A sandbox, if you have one
Synthetic patients are enough. No production PHI is needed to prove the integration works, and we would rather not be given any.
No FHIR server? The signed webhook is one endpoint and about a day of work, and nothing about it prevents moving to FHIR later.
See the webhook pathSMART on FHIR, Frequently Asked Questions
Is this a live API we can call today?
No, and the distinction is worth being precise about. This page describes the interface VoiceboxMD builds to, published so you can evaluate it before committing engineering time. Direct chart write is delivered with integration partners rather than as a self-serve public API. In SMART standalone launch we are the client, so the endpoints involved are yours; there is no VoiceboxMD endpoint to call here.
You say write only, but you request a read scope. Which is it?
The only write requested is DocumentReference create. We also request Patient read and search, because a note has to be attached to the right patient and there is no safe way to resolve that without reading. Describing the integration as write-only is accurate about intent and inaccurate about the scope list, so the scope list is published above rather than summarised.
Why does the write happen as the clinician rather than as your system?
Because your audit log should be true. A note written by a shared service account tells whoever reviews the chart later that software wrote it, with no way to establish who was responsible. Using the clinician’s own delegated authorization means the record reflects the person who dictated and reviewed the note, which is a medico-legal position rather than an engineering preference.
Why do you need offline_access?
Ambient notes are drafted after the encounter finishes, and the clinician reviews and finalizes them later, sometimes hours later. Without a refresh token the access token has expired by the time there is anything to write, and the clinician would have to re-authenticate for every note. It is the difference between an integration that works and one that is technically correct and unusable.
Do you support SMART v1 or v2 scopes?
Both. Vendors are mid-migration, so we request the granular v2 form where your discovery document advertises support for it and fall back to the v1 form otherwise. The table above lists both spellings of each scope for that reason.
What if we are not on FHIR at all?
Then this is the wrong page and the signed webhook is the right one. You expose a single endpoint, we POST the finished note as JSON, and there is no OAuth server, FHIR server or marketplace review involved. Most small and mid-size platforms integrate that way, and nothing about it prevents moving to FHIR later.
Is the mapping stable?
It is versioned. What is published here is v1, and it freezes once the first partner ships against it. Additive changes, meaning new optional fields, can appear within v1; anything that would break an existing integration means a v2 published alongside v1 rather than instead of it.
One write scope. Attributed to the clinician.
Published so you can size the work before you talk to us.
Talk to us about integrating