This page is part of the Smart App Launch Implementation Guide (v2.2.0-ballot: STU 2.2 Ballot 1) based on FHIR (HL7® FHIR® Standard) R4. The current version which supersedes this version is 2.1.0. For a full list of available versions, see the Directory of published versions
The specification defines FHIR profiles for Endpoint, Organization, and Bundle resources that make it easier for patient-facing apps to connect to health data providers. It outlines the process for API providers to publish Brands associated with their FHIR Endpoints, and for apps to collect and present these Brands to users. Each Brand includes essential information such as the organization’s name, logo, and patient access details, which apps can display in their user interface.
EHR systems, healthcare providers, and app developers can ensure a consistent and recognizable user experience when connecting patients to their health records across various platforms and services by following this specification.
The Patient-Access Brand Examples illustrate how providers can represent diverse scenarios.
This specification supports a model UX where apps display a collection of cards or tiles, each representing a “Patient-access Brand” that patients can recognize and connect to. App developers are not expected to follow this model UX precisely; the model exists to keep the design grounded and establish a shared vocabulary.
In this model, a healthcare provider, payer, or other organization exposing a FHIR patient access API can decide which brands to publish in association with their FHIR endpoints. Each Brand includes data describing the organization (e.g., organization name and logo that a patient would recognize) together with details about their patient access portals (e.g., name, logo, and description in terms that patients would recognize) as well as the API endpoints associated with these portals.
In this model, an app can:
Each Brand includes the following information intended to support an app-based card or tile UX:
Field | Description | Cardinality |
---|---|---|
Name | Primary name for the organization to display on a card, e.g., “General Hospital” | 1..1 |
Consumer-facing website for this Brand | note this is distinct from a patient portal, described under “Patient Access Details” below | 1..1 |
Logo | to be displayed on a card, and link to logo use terms/agreements | 0..1 |
Aliases | e.g., former names like “General Health Associates” for filtering/search | 0..* |
Identifiers | supporting cross-publisher references or links to external data sets such as the NPI Registry. | 0..* |
Locations | zip codes and street addresses associated with the Brand | 0..* |
Categories | clinical, insurance, laboratory, imaging, pharmacy, network, aggregator — for filtering/search | 0..* |
Portal Details | describes a portal this Brand offers to patients See the table below. | 1..* |
The details of the Patient Access Brand communicated to the patient.
Field | Description | Cardinality |
---|---|---|
Portal name | e.g., “Patient Gateway” or “MyChildrens Portal” | 1..1 |
Portal logo | to be displayed on a card for Brands that have a portal logo in addition to their brand logo | 0..1 |
Portal URL | where patients can manage accounts with this provider. | 1..1 |
Patient-facing description | explaining the subset of patients eligible to connect, or the data available in a patient-friendly language | 0..1 |
API Endpoints | FHIR API Endpoints associated with the portal | 0..* |
Commonly, a single Brand is typically associated with a single patient Portal that offers a single FHIR Endpoint. But all of the following cases are supported by this conceptual model:
identifier
to facilitate matching, merging, and de-duplication. Apps can merge Brands into a single target Brand’s card by displaying the target Brand’s title and logo. Within the Brand’s card, the app displays a distinct “connect” button for each set of Patient Access Details.An app assembles its collection of Brands (typically as an offline, configuration-time process) by gathering FHIR PatientAccessEndpoint
(Endpoints) and PatientAccessBrand
(Organizations) resources from:
.well-known/smart-configuration
for known endpointsFor fine-grained organizational management, apps SHALL select the FHIR resources linked from .well-known/smart-configuration
if they differ from the resources in a vendor-consolidated Brand Bundle.
This annotated example illustrates how a Brand is represented as a FHIR Organization.
{
// A Brand is represented as a FHIR Organization
"resourceType" : "Organization",
"id" : "good-health",
// The primary name by which patients recognize this brand
"name" : "Good Health",
// Additional names or former names that patients may recognize
"alias" : ["Goodie Bag Health"],
// Any valid status is allowed, but publishers should consider filtering
// their published list to only include active brands.
"active" : true,
// This guide provides a vocabulary for loosely categorizing the type of
// data available at patient access API endpoints. Multiple categories
// can be included here.
"type" : [{
"coding" : [{
"system" : "http://hl7.org/fhir/smart-app-launch/CodeSystem/patient-access-category",
"code" : "clinical",
"display" : "Clinical"
}]
}],
"extension" : [{
// (0..1) `organization-brand` extension conveys branding details that
// are not part of FHIR's core data model
"url" : "http://hl7.org/fhir/StructureDefinition/organization-brand",
"extension" : {
// (0..*) Link to the logo (uses `https:` or `data:` schme for inline)
// * optimized for display as a 1 in / 2.54 cm square
// * formatted as SVG or 1024x1024 pixel PNG with transparent background
// * legible at small sizes
"url" : "brandLogo",
"valueUrl" : "https://goodhealth.example.org/images/logo.svg"
},{
// (0..*) Link to the license agreement for the logo, if applicable
"url" : "brandLogoLicense",
"valueUrl" : "https://goodhealth.example.org/license.html"
}, {
// (0..*) Link to a Brand Bundle where additional information about
// this Brand may be available.
"url" : "brandBundle",
"valueUrl" : "https://goodhealth.example.org/branding.json"
},
},
{
// (0..*) `organization-portal` extension conveys details about a
// portal associated with this brand. This extension repeats when
// more than one portal is associated with this brand.
"url" : "http://hl7.org/fhir/StructureDefinition/organization-portal",
"extension" : [{
// (0..1) Name of the portal as shown to patients
"url" : "portalName",
"valueString" : "GoodHealthCentral"
},
{
// (0..1) Describes the portal and its intended audience. May be used to help
// patients select the right portal if multiple options are available.
"url" : "portalDescription",
"valueMarkdown" : "GoodHealthCentral is available for our primary care patients."
},
{
// (0..1) Link to the portal website.
"url" : "portalUrl",
"valueUrl" : "https://goodhealthcentral.example.org"
},
{
// (0..1) Logo for the portal (see descriptions for brandLogo above)
"url" : "portalLogo",
"valueUrl" : "https://goodhealthcentral.example.org/logo.png"
},{
// (0..1) License for the portal logo (see description for brandLogoLicense above)
"url" : "portalLogoLicense",
"valueUrl" : "https://goodhealthcentral.example.org/logo-license.html"
},
{
// (0..*) Endpoint associated with this portal. This extension repeat
// when more than one endpoint is associated with this portal.
// (The `reference` is to an Endpoint that appears in the same
// Brand Bundle as this Organization)
"url" : "portalEndpoint",
"valueReference" : {
"reference" : "Endpoint/goodhealth-r4"
}
},{
"url" : "portalEndpoint",
"valueReference" : {
"reference" : "Endpoint/goodhealth-r2"
}
}]
}],
// Apps can use a Brand’s Organization.identifier to merge content published
// in multiple sources. To facilitate robust matching, EHRs SHALL support
// customer-supplied identifiers (system and value). It is RECOMMENDED that
// each Brand include an identifier where system is `urn:ietf:rfc: 3986`
// (meaning the identifier is a URL) and value is the HTTPS URL for the
// Brand’s primary web presence, omitting any “www.” prefix and any path.
// Of course, additional Identifiers may be included as well.
"identifier" : [{
"system" : "urn:ietf:rfc:3986",
"value" : "https://examplelabs.org"
}],
// telecom with value conveying the primary public website for the Brand.
// Note this is distinct from the patient access portal website.
"telecom" : [{
"system" : "url",
"value" : "https://brand.example.com"
}],
// Locations (e.g., zip codes and/or street addresses) associated with the Brand.
// The following combinations are allowed:
// * State
// * City, state
// * City, state, zip code
// * Street address, city, state, zip code
// * Zip code alone
"address" : [{
"city" : "Boston",
"state" : "MA",
"postalCode" : "02111"
}, {
"postalCode" : "02139"
}]
}
This annotated example illustrates how an Endpoint is represented.
{
"resourceType": "Endpoint",
"id": "goodhealth-r4",
// FHIR Base URL for the Patient Access Endpoint
"address": "https://fhir.goodhealth.example.org/r4",
// Any valid status is allowed, but publishers should consider filtering
// their published list to only include active endpoints.
"status": "active",
// Name for the Patient Access Endpoint. This value may contain
// technical details like FHIR API Version designations, so apps should prefer
// displaying the `Organization.name` from an associated PatientAccessBrand,
// rather than displaying this value to users.
"name": "FHIR R4 Endpoint for GoodHealth",
// Fixed value indicating FHIR API Endpoint
"connectionType": {
"code": "hl7-fhir-rest",
"system": "http://terminology.hl7.org/CodeSystem/endpoint-connection-type"
},
"extension": [
{
// (1..*) The Patient Access Endpoint's FHIR Version. This Extension
// is a denormalization to help clients focus on supported endpoints.
"url": "http://hl7.org/fhir/StructureDefinition/endpoint-fhir-version",
"valueCode": "4.0.1"
}
],
// Contact information for the endpoint. This will include at least one
// URL for a website where developers can configure access to this endpoint.
"contact": [
{
"system": "url",
"value": "https://dev-portal.goodhealth.example.org"
}
],
// Some `payloadType` is required by FHIR R4. It can be populated with a
// placeholder value like the one shown here.
"payloadType" : [
{
"coding" : [
{
"system" : "http://terminology.hl7.org/CodeSystem/endpoint-payload-type",
"code" : "none"
}
]
}
]
}
JSON FHIR Bundle (type: collection
) of Organizations and Endpoints that is hosted at a stable, publicly available, publicly disclosed location.
For background and context, see Patient Access Brands Overview.
Bundle Entries include:
Brand Bundles SHALL populate Bundle.timestamp
to advertise the timestamp of the last change to the contents. In addition, Brand Bundles SHOULD populate Bundle.entry.resource.meta.lastUpdated
with a more detailed timestamp if the system tracks updates per Resource.
{
"resourceType": "Bundle",
"id": "example",
// Brand Bundles are always published as "collection"
"type": "collection",
// Brand Bundles always include a timestamp that apps can use to recognize
// if contents have changed since the last time they fetched the bundle.
"timestamp": "2023-09-05T20:00:43.241070-07:00",
"entry": [ /* Organizations and Endpoints here */ ]
}
Brands and Endpoints are compiled together and published in a Brand Bundle.
The Patient-Access Brand Examples illustrate how providers can represent diverse scenarios including:
Apps can use a Brand’s Organization.identifier
element to merge content published in multiple sources. To facilitate robust matching, EHRs SHALL support customer-supplied identifiers (system
and value
). It is RECOMMENDED that each Brand include an identifier where system
is urn:ietf:rfc: 3986
(meaning the identifier is a URL) and value
is the HTTPS URL for the Brand’s primary web presence, omitting any “www.” prefix from the domain and omitting any path component. For example, since the main web presence of Boston Children’s Hospital is https://www.childrenshospital.org/, a recommended identifier would be
{"system": "urn:ietf:rfc:3986", "value": "https://childrenshospital.org"}
Publishers SHALL support Cross-Origin Resource Sharing (CORS) for all GET requests to the artifacts described in this guide.
Publishers SHOULD include a weak ETag
header in all HTTP responses. Clients SHOULD cache responses by ETag and SHOULD provide an If-None-Match
header in all requests to avoid re-fetching data that have not changed. See https://www.hl7.org/fhir/http.html#cread for background.
.well-known/smart-configuration
FHIR servers supporting this IG SHOULD include the following properties in the SMART configuration JSON response:
patientAccessBrandBundle
URL of a Brand Bundle. The Bundle entries include any Brand and “peer endpoints” associated with this FHIR endpoint.patientAccessBrandIdentifier
: FHIR Identifier for this server’s primary Brand within the Bundle. Publishers SHALL populate this property if the referenced Brand Bundle includes more than one Brand. When present, this identifier SHALL consist of a value
and SHOULD have a system
.The Brand Bundle SHALL include exactly one Brand with an Organization.identifier
that matches the primary Brand identifier from SMART configuration JSON.
The Brand Bundle SHOULD include only the Brands and Endpoints associated with the SMART on FHIR server that links to the Bundle. However, the Brand Bundle MAY have additional Brands or Endpoints (e.g., supporting a publication pattern where endpoints from a given vendor might point to a comprehensive, centralized vendor-managed list).
.well-known/smart-configuration
{
// details at http://hl7.org/fhir/smart-app-launch/conformance.html
"patientAccessBrandBundle": "https://example.org/brands.json",
"patientAccessBrandIdentifier": {
"system": "urn:ietf:rfc:3986",
"value": "https://example.org"
},
// ...
}
Dereferencing the patientAccessBrandBundle
URL above would return a Brand Bundle.
MS
) and Data Absent ReasonsFor this specification a profile element labeled as “must support” means publishers must provide a way for Brands to populate value. For example, marking a Brand’s “address” as 0..* MS
means that a publisher needs to give Brands a way to supply multiple addresses, even if some choose not to provide any.
An EHR that publishes a Brand Bundle may not have some required data elements (Brand Website, Portal Website, Portal Name). If the EHR has asked, but a Brand administrator has not supplied a value, the EHR MAY provide a Data Absent Reason of asked-declined
or asked-unknown
. The EHR SHALL NOT use other Data Absent Reasons.