The short answer
In a SMART on FHIR EHR launch, a user already working in the EHR opens the app, and the EHR passes it a launch id that carries context such as the current patient. In a standalone launch, the user opens the app from outside the EHR, and the app asks for the context it needs, such as launch/patient, during authorisation.1 Both use OAuth with PKCE (S256 only) and a state value, and access tokens should last no more than an hour.1 Neither keeps the app in sync if the user switches charts mid-session.1 For an AI assistant working beside a clinician, EHR launch is usually the right fit; for an agent with no user, use Backend Services instead.3
Deedglass
The server said “saved”. Deedglass looked.
Deedglass reads it back
The two flows side by side
| EHR launch | Standalone launch | |
|---|---|---|
| Where the user starts | Inside an EHR session | Outside the EHR, such as a phone app icon |
| How context arrives | EHR sends iss and a launch id; app echoes launch scope |
App requests launch/patient, launch/encounter; EHR acquires it |
| Typical apps | In-chart tools, user-level dashboards | Patient apps, clinician mobile apps |
| User picks the patient? | Already chosen in the EHR | Picked during authorisation if needed |
Source:1.
EHR launch, step by step
- The user is in an EHR session and launches the app.
- The EHR opens the app’s registered launch URL with
iss(the FHIR base URL) andlaunch(an opaque id), for examplehttps://app/launch?iss=https%3A%2F%2Fehr%2Ffhir&launch=xyz123.1 - The app fetches
.well-known/smart-configurationfrom the FHIR base to find the authorisation and token endpoints. - The app sends an authorisation request including the
launchscope andlaunch=xyz123, plus the scopes it needs.1 - After the user authorises (often silently, by policy), the app exchanges the code for a token, with the patient and other context in the token response.
The launch id ties the app’s authorisation to the user’s current EHR context, so the app opens on the patient the clinician was looking at.
The launch id is opaque; the app shouldn’t parse it or try to reuse it later. What the app should keep is the context it receives with the token, such as the patient id, and it should show that context to the user. For apps that act, that display is a safety feature: it’s how a clinician notices the app is bound to a different patient than the one on screen.
Standalone launch, step by step
- The user opens the app outside the EHR. There’s no launch request.1
- The app discovers the endpoints.
- The app requests scopes, including context requirements such as
launch/patient; the authorisation server acquires that context, for example by asking the user to pick a patient.1 - Code exchange and token, with the chosen context.
Scopes work the same way in both flows. SMART v2 scopes take the form context/ResourceType.letters (create, read, update, delete, search), and can be narrowed with query parameters.2 Our SMART v2 scopes post has examples.
Security rules that apply to both
| Rule | Requirement |
|---|---|
| PKCE | All apps SHALL support it; servers SHALL support S256 and SHALL NOT support plain1 |
state |
Apps SHALL use an unpredictable value per session and validate it1 |
| Access token lifetime | SHOULD be no more than one hour1 |
| Public vs confidential | Depends on whether the app can keep a secret; confidential clients may get longer-lived tokens1 |
| Permissions | SMART delegates a subset of the user’s existing permissions; it doesn’t define what those permissions are1 |
Two scope notes from the spec are easy to miss. First, mechanisms like session time-out, security auditing and accounting of disclosures are outside SMART’s scope; the EHR and the app still need them. Second, context sync isn’t covered: if the user changes the open chart, the app isn’t updated; the spec points to FHIRcast for that.1
Which flow for an AI assistant
| AI pattern | Flow | Why |
|---|---|---|
| Chart assistant in the EHR sidebar | EHR launch | Opens on the clinician’s current patient, acting as that user |
| Clinician’s mobile assistant | Standalone | Starts outside the EHR; user picks context |
| Patient-facing assistant | Standalone, patient scopes | The patient authorises access to their own data |
| Overnight agent with no user | Neither; Backend Services | No user to authorise at runtime3 |
The context-sync gap matters more for AI than for ordinary apps. A clinician who launches an assistant on one patient, then opens another chart, may keep talking to an assistant still bound to the first. If the assistant drafts a note or order, it drafts for the wrong patient context. Handle it in the app: show the bound patient prominently, re-check context before any write, and consider FHIRcast where the EHR supports it.1
Also remember that SMART delegates the user’s permissions.1 An assistant launched by a clinician can do what that clinician’s token allows within the requested scopes, so request narrow scopes per task, and put writes that need a second look behind an approval step outside the model.
Questions people ask
What’s the difference between SMART EHR launch and standalone launch?
EHR launch starts inside an EHR session and passes a launch id with context; standalone starts outside the EHR and requests context with scopes like launch/patient.1
Is PKCE required in SMART App Launch?
Yes. All apps SHALL support PKCE, and servers SHALL support S256 and not the plain method.1
Does SMART keep the app in sync with the open chart?
No. Context synchronisation isn’t addressed; the spec points to FHIRcast.1
For how agent writes made under a user’s token can be held and recorded, see our healthcare page and the provenance spec. To try approvals and read-backs on a real database in your browser, open the playground; to grade what an agent can reach on your own machine, run npx deedglass scan (the grade, explained).
Written with AI assistance and checked against our claims register.