1 # OpenEMR FHIR API Documentation
3 ## FHIR API Table of Contents
4 - [Overview](FHIR_README.md#overview)
5 - [Prerequisite](FHIR_README.md#prerequisite)
6 - [Using FHIR API Internally](FHIR_README.md#using-fhir-api-internally)
7 - [Multisite Support](FHIR_README.md#multisite-support)
8 - [Authorization (in API_README.md)](API_README.md#authorization)
9 - [Scopes (in API_README.md)](API_README.md#scopes)
10 - [Registration (in API_README.md)](API_README.md#registration)
11 - [SMART on FHIR Registration (in API_README.md)](API_README.md#smart-on-fhir-registration)
12 - [Authorization Code Grant (in API_README.md)](API_README.md#authorization-code-grant)
13 - [Refresh Token Grant (in API_README.md)](API_README.md#refresh-token-grant)
14 - [Password Grant (in API_README.md)](API_README.md#password-grant)
15 - [Client Credentials Grant (in API_README.md)](API_README.md#client-credentials-grant)
16 - [Logout (in API_README.md)](API_README.md#logout)
17 - [More Details (in API_README.md)](API_README.md#more-details)
18 - [FHIR API Documentation](FHIR_README.md#fhir-api-documentation)
19 - [Capability Statement](FHIR_README.md#capability-statement)
20 - [Provenance](FHIR_README.md#Provenance-resources)
21 - [BULK FHIR Exports](FHIR_README.md#bulk-fhir-exports)
22 - [System Export](FHIR_README.md#bulk-fhir-exports)
23 - [Patient Export](FHIR_README.md#bulk-fhir-exports)
24 - [Group Export](FHIR_README.md#bulk-fhir-exports)
25 - [3rd Party SMART Apps](FHIR_README.md#3rd-party-smart-apps)
26 - [For Developers](FHIR_README.md#for-developers)
30 Easy-to-use JSON-based REST API for OpenEMR FHIR. See standard OpenEMR API docs [here](API_README.md). The OpenEMR FHIR API conforms to the R4 specification and the US Core 3.1 Implementation Guide (IG).
34 Enable the Standard FHIR service (/fhir/ endpoints) in OpenEMR menu: Administration->Globals->Connectors->"Enable OpenEMR Standard FHIR REST API"
36 ## Using FHIR API Internally
38 There are several ways to make API calls from an authorized session and maintain security:
40 - See the script at tests/api/InternalApiTest.php for examples of internal API use cases.
44 Multisite is supported by including the site in the endpoint. When not using multisite or using the `default` multisite site, then a typical path would look like `apis/default/fhir/patient`. If you were using multisite and using a site called `alternate`, then the path would look like `apis/alternate/fhir/patient`.
48 OpenEMR uses OIDC compliant authorization for API. SSL is required and setting baseurl at Administration->Globals->Connectors->'Site Address (required for OAuth2 and FHIR)' is required.
50 See [Authorization](API_README.md#authorization) for more details.
52 ## FHIR API Documentation
54 The FHIR API is documented via Swagger. Can see this documentation (and can test it) by going to the `swagger` directory in your OpenEMR installation. The FHIR API is documented there in the `fhir` section. Can also see (and test) this in the online demos at https://www.open-emr.org/wiki/index.php/Development_Demo#Daily_Build_Development_Demos (clicking on the `API (Swagger) User Interface` link for the demo will take you there).
56 Standard FHIR endpoints Use `https://localhost:9300/apis/default/fhir as base URI.`
58 Note that the `default` component can be changed to the name of the site when using OpenEMR's multisite feature.
60 _Example:_ `https://localhost:9300/apis/default/fhir/Patient` returns a Patient's bundle resource, etc
62 The Bearer token is required for each OpenEMR FHIR request (except for the Capability Statement), and is conveyed using an Authorization header. Note that the Bearer token is the access_token that is obtained in the [Authorization](API_README.md#authorization) section.
64 When registering an API client to use with Swagger the following for the redirect url and launch url for the client.
65 - Redirect URL -> <base_site_address>/swagger/oauth2-redirect.html
66 - Launch URL -> <base_site_address>/swagger/index.html
71 curl -X GET 'https://localhost:9300/apis/fhir/Patient' \
72 -H 'Authorization: Bearer eyJ0b2tlbiI6IjAwNnZ3eGJZYmFrOXlxUjF4U290Y1g4QVVDd3JOcG5yYXZEaFlqaHFjWXJXRGNDQUtFZmJONkh2cElTVkJiaWFobHBqOTBYZmlNRXpiY2FtU01pSHk1UzFlMmgxNmVqZEhcL1ZENlNtaVpTRFRLMmtsWDIyOFRKZzNhQmxMdUloZmNJM3FpMGFKZ003OXdtOGhYT3dpVkx5b3BFRXQ1TlNYNTE3UW5TZ0dsUVdQbG56WjVxOVYwc21tdDlSQ3RvcDV3TEkiLCJzaXRlX2lkIjoiZGVmYXVsdCIsImFwaSI6ImZoaXIifQ=='
77 ### Capability Statement
79 #### GET fhir/metadata
81 This will return the Capability Statement. Note this can be tested in the Swagger documentation linked to in the above `FHIR API Documentation`.
83 curl -X GET 'https://localhost:9300/apis/default/fhir/metadata'
86 ### Provenance Resources
88 Provenance resources are requested by including `_revinclude=Provenance:target` in the search of a resource. Is currently supported for the following resources:
91 curl -X GET 'https://localhost:9300/apis/default/fhir/AllergyIntolerance?_revinclude=Provenance:target'
95 An export operation that implements the [BULK FHIR Export ONC requirements](https://hl7.org/fhir/uv/bulkdata/export/index.html) can be requested by issuing a GET request to the following endpoints:
96 - System Export, requires the **system/\*.$export** scope. Exports All supported FHIR resources
98 curl -X GET 'https://localhost:9300/apis/default/fhir/$export'
100 - Group Export, requires the **system/Group.$export** scope. Exports all data in the [Patient Compartment](https://www.hl7.org/fhir/compartmentdefinition-patient.html) for the group.
101 There is only one group defined in the system currently. If OpenEMR defines additional patient population groups you would change the Group ID in the API call.
103 curl -X GET 'https://localhost:9300/apis/default/fhir/Group/1/$export'
105 - Patient Export, requires the **system/Group.$export** scope. Exports all data for all patients in the [Patient Compartment](https://www.hl7.org/fhir/compartmentdefinition-patient.html).
107 curl -X GET 'https://localhost:9300/apis/default/fhir/Patient/$export'
109 You will get an empty body response with a **Content-Location** header with the URL you can query for status updates on the export.
111 To query the status update operation you need the **system/\*.$bulkdata-status** scope. An example query:
114 curl -X GET 'https://localhost:9300/apis/default/fhir/$bulkdata-status?job=92a94c00-77d6-4dfc-ae3b-73550742536d'
117 A status Query will return a result like the following:
121 "date": "2021-02-05 20:48:38.000000",
125 "request": "\/apis\/default\/fhir\/Group\/1\/%24export",
126 "requiresAccessToken": true,
129 "url": "https:\/\/localhost:9300\/apis\/default\/fhir\/Document\/97552\/Binary",
133 "url": "https:\/\/localhost:9300\/apis\/default\/fhir\/Document\/105232\/Binary",
141 You can download the exported documents which are formatted in Newline Delimited JSON (NDJSON) by making a call to:
143 curl -X GET 'https://localhost:9300/apis/default/fhir/Document/105232/Binary'
146 ## 3rd Party SMART Apps
147 OpenEMR supports the ability for 3rd party apps who implement the [SMART on FHIR App Launch Implementation Guide 1.1.0](http://hl7.org/fhir/smart-app-launch/2021May/) context.
149 3rd party Apps using the confidential app profile must be authorized by the OpenEMR Server Installation Administrator. Access Tokens issued to 3rd party apps are only valid for one hour and must be renewed with a refresh token which is valid for up to three months. Refresh tokens are only issued if the offline_access scope is authorized by the OpenEMR user authenticating with OpenEMR through their 3rd party app.
151 For a patient to have access to their patient data via a 3rd party app they must have api credentials generated by their clinician from the patient demographics page. A patient must not have opted out of 3rd party API access.
153 OpenEMR does NOT support wildcard scopes (patient/*.* or patient/*.read). Scopes must be requested explicitly by an app at the time of registration. OpenEMR does not support adding scopes from the initial registration.
157 FHIR endpoints are defined in the [primary routes file](_rest_routes.inc.php). The routes file maps an external, addressable
158 endpoint to the OpenEMR FHIR controller which handles the request, and also handles the JSON data conversions.
161 "GET /fhir/Patient" => function () {
162 RestConfig::authorization_check("patients", "demo");
163 $return = (new FhirPatientRestController())->getAll($_GET);
164 RestConfig::apiLog($return);
169 At a high level, the request processing flow consists of the following steps:
172 JSON Request -> FHIR Controller Component -> FHIR Validation -> Parsing FHIR Resource -> Standard Service Component -> Validation -> Database
175 The logical response flow begins with the database result:
178 Database Result -> Service Component -> FHIR Service Component -> Parse OpenEMR Record -> FHIR Controller Component -> RequestControllerHelper -> JSON Response