php82 ci docker update (#6003)
[openemr.git] / FHIR_README.md
bloba2ccc2e82f633d55899ee20403a727175f1a01e4
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 - [Native Applications](FHIR_README.md#native-applications)
27 - [Carecoordination Summary Of Care (CCD) Generation](FHIR_README.md#carecoordination-summary-of-care-docref-operation)
28     - [Overview Docref](FHIR_README.md#overview-docref)
29     - [Generate CCDA](FHIR_README.md#generate-ccda)
30     - [Details Docref](FHIR_README.md#details-docref)
31 - [For Developers](FHIR_README.md#for-developers)
33 ## Overview
35 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).
37 ## Prerequisite
39 Enable the Standard FHIR service (/fhir/ endpoints) in OpenEMR menu: Administration->Globals->Connectors->"Enable OpenEMR Standard FHIR REST API"
41 ## Using FHIR API Internally
43 There are several ways to make API calls from an authorized session and maintain security:
45 -   See the script at tests/api/InternalApiTest.php for examples of internal API use cases.
47 ## Multisite Support
49 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`.
51 ## Authorization
53 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.
55 See [Authorization](API_README.md#authorization) for more details.
57 ## FHIR API Documentation
59 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).
61 Standard FHIR endpoints Use `https://localhost:9300/apis/default/fhir as base URI.`
63 Note that the `default` component can be changed to the name of the site when using OpenEMR's multisite feature.
65 _Example:_ `https://localhost:9300/apis/default/fhir/Patient` returns a Patient's bundle resource, etc
67 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.
69 When registering an API client to use with Swagger the following for the redirect url and launch url for the client.
70 - Redirect URL -> <base_site_address>/swagger/oauth2-redirect.html
71 - Launch URL -> <base_site_address>/swagger/index.html
73 Request:
75 ```sh
76 curl -X GET 'https://localhost:9300/apis/fhir/Patient' \
77   -H 'Authorization: Bearer eyJ0b2tlbiI6IjAwNnZ3eGJZYmFrOXlxUjF4U290Y1g4QVVDd3JOcG5yYXZEaFlqaHFjWXJXRGNDQUtFZmJONkh2cElTVkJiaWFobHBqOTBYZmlNRXpiY2FtU01pSHk1UzFlMmgxNmVqZEhcL1ZENlNtaVpTRFRLMmtsWDIyOFRKZzNhQmxMdUloZmNJM3FpMGFKZ003OXdtOGhYT3dpVkx5b3BFRXQ1TlNYNTE3UW5TZ0dsUVdQbG56WjVxOVYwc21tdDlSQ3RvcDV3TEkiLCJzaXRlX2lkIjoiZGVmYXVsdCIsImFwaSI6ImZoaXIifQ=='
78 ```
80 ---
82 ### Capability Statement
84 #### GET fhir/metadata
86 This will return the Capability Statement. Note this can be tested in the Swagger documentation linked to in the above `FHIR API Documentation`.
87     ```sh
88     curl -X GET 'https://localhost:9300/apis/default/fhir/metadata'
89     ```
91 ### Provenance Resources
93 Provenance resources are requested by including `_revinclude=Provenance:target` in the search of a resource. Is currently supported for the following resources:
94   - AllergyIntolerance
95       ```sh
96       curl -X GET 'https://localhost:9300/apis/default/fhir/AllergyIntolerance?_revinclude=Provenance:target'
97       ```
99 ### BULK FHIR Exports
100 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:
101  - System Export, requires the **system/\*.$export** scope.  Exports All supported FHIR resources
102     ```sh
103           curl -X GET 'https://localhost:9300/apis/default/fhir/$export'
104     ```
105  - 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.
106    The system automatically creates a group for every Practitioner resource in the system where the patients in the group are the individuals who have the Practitioner as their primary care provider.
107     ```sh
108           curl -X GET 'https://localhost:9300/apis/default/fhir/Group/1/$export'
109     ```
110  - Patient Export, requires the **system/Patient.$export** scope.  Exports all data for all patients in the [Patient Compartment](https://www.hl7.org/fhir/compartmentdefinition-patient.html).
111     ```sh
112           curl -X GET 'https://localhost:9300/apis/default/fhir/Patient/$export'
113     ```
114 You will get an empty body response with a **Content-Location** header with the URL you can query for status updates on the export.
116 To query the status update operation you need the **system/\*.$bulkdata-status** scope.  An example query:
117  - Status Query
118     ```sh
119           curl -X GET 'https://localhost:9300/apis/default/fhir/$bulkdata-status?job=92a94c00-77d6-4dfc-ae3b-73550742536d'
120     ```
122 A status Query will return a result like the following:
125   "transactionTime": {
126     "date": "2021-02-05 20:48:38.000000",
127     "timezone_type": 3,
128     "timezone": "UTC"
129   },
130   "request": "\/apis\/default\/fhir\/Group\/1\/%24export",
131   "requiresAccessToken": true,
132   "output": [
133     {
134       "url": "https:\/\/localhost:9300\/apis\/default\/fhir\/Binary\/97552",
135       "type": "Patient"
136     },
137     {
138       "url": "https:\/\/localhost:9300\/apis\/default\/fhir\/Binary\/105232",
139       "type": "Encounter"
140     }
141   ],
142   "error": []
146 You can download the exported documents which are formatted in Newline Delimited JSON (NDJSON) by making a call to:
147     ```sh
148           curl -X GET 'https://localhost:9300/apis/default/fhir/Binary/105232'
149     ```
151 In order to download the documents you will need the **system/Binary.read** scope.
153 #### Bulk FHIR Scope Reference
154 - All System export - **system/\*.$export system\*.$bulkdata-status system/Binary.read**
155 - Group System export - **system/Group.$export system\*.$bulkdata-status system/Binary.read**
156 - Patient System export - **system/Patient.$export system\*.$bulkdata-status system/Binary.read**
158 ####
159 ## 3rd Party SMART Apps
160 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.
162 3rd party Apps using the confidential app profile are auto enabled if they are strictly a patient standalone app.  A patient standalone app is one that only requests patient only scopes such as patient/\*. A provider or system app (requesting permissions such as launch, user/\*, system/\*, etc) 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.
164 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.
166 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.
169 ## Revoking Clients, Users, Access Tokens, Refresh Tokens
171 ## Revoking Clients
172 You can disable a client completely which prevents their access tokens from being used in the system from the Admin -> System -> API Clients interface.  Edit the client registered in your system you wish to disable and hit the Disable button.
174 ## Revoking Users
175 If you wish to revoke a user's authorization for a particular client you will need to open up the API client from the Admin -> System -> API Clients interface.  Once you are editing the client you will need to go to the Authenticated API Users section.
177 From there you can find the user that is listed and hit the Revoke User button (Note this can be a lengthy list so use your browser's search text functionality to find the user).
179 ## Revoking Access Tokens
180 You can revoke an access token two ways.  One from the API Client edit screen, finding the client and then the access token's identifier you wish to revoke.
182 The second way is if you have the fully encoded access token using the API Client Tools screen.  Go to Admin->System->API Clients and then click on the Token Tools button.  Paste in the entire encoded token and then select Parse Token.  Information about the token will be displayed including the authenticated user that authorized the token.  Now select the Revoke Token button to revoke the token.  A success message will be displayed when the revocation completes.  You can parse the token again to see that the token has been revoked.
184 ## Native Applications
185 Interoperability requirements with OpenEMR for Native Applications
187 - Native applications wishing to use the OpenEMR FHIR API with refresh tokens MUST be capable of storing the refresh token in a secure manner similar to the requirements of storing a secret for confidential apps.
188 - Native applications must support either PKCE with a public app or use a confidential app.  PKCE is still recommended to be used with confidential apps to prevent MITM attacks.
189 - Native applications must request the offline_scope in their initial API request in order to receive a refresh token
190 - Native application refresh tokens are valid for 3 months before they must be renewed.
191 - Native applications will receive a new refresh token every time they are renewed.
192 - Native applications can only communicate with OpenEMR over a TLS secured channel in order to ensure the safe transmission of the refresh token.
193 - Native applications should use certificate pinning to mitigate any SSL MITM attack.
194 - Native applications must use the Authorization Code grant flow in order to receive a refresh token.
196 It is recommended that native applications follow best practices for native client applications as outlined in RFC 8252 OAuth 2.0 for Native Apps.
198 ## Carecoordination Summary of Care Docref Operation
199 ### Overview Docref
200 - The $docref operation is used to request the server to generate a document based on the specified
201   parameters. If no additional parameters are specified then a DocumentReference to the patient's most current Clinical
202   Summary of Care Document (CCD) is returned. The document itself is retrieved using the DocumentReference.content.attachment.url
203   element.  See <a href='http://hl7.org/fhir/us/core/OperationDefinition-docref.html' target='_blank'
204   rel='noopener'>http://hl7.org/fhir/us/core/OperationDefinition-docref.html</a> for more details.
205 ### Generate CCDA
206 - [Tutorial to Generate CCDA (with Screenshots)](https://github.com/openemr/openemr/issues/5284#issuecomment-1155678620)
207 ### Details Docref
208 - Requires <context>/DocumentReference.$docref, <context>/DocumentReference.read, and <context>/Binary.read scopes
209 - Start and end date filter encounter related events for the following sections:
210     - History of Procedures
211     - Relevant DX Tests / LAB Data
212     - Functional Status
213     - Progress Notes
214     - Procedure Notes
215     - Laboratory Report Narrative
216     - Encounters
217     - Assessments
218     - Treatment Plan
219     - Goals
220     - Health Concerns Document
221     - Reason for Referral
222     - Mental Status
223 - The following sections have the entire medical record sent to ensure that medical professionals have medically necessary information to provide treatment of care:
224     - Demographics
225     - Allergies, Adverse Reactions, Alerts
226     - History of Medication Use
227     - Problem List
228     - Immunizations
229     - Social History
230     - Medical Equipment
231     - Vital Signs (shows the latest vitals recorded for the patient)
232 - CCD is generated on demand, saved off in patient's documents record under the CCDA category.
233 - Returns a DocumentReference search bundle per the IG spec.
234 - XSL to view the document can be download at /<site>/interface/modules/zend_modules/public/xsl/cda.xsl
235     - Or xml file can be uploaded as a document into OpenEMR to view in a human readable format
236     - Due to browser security restrictions XSL file must be in same directory as ccd document to view.
237 - If no start date is provided it will retrieve all records in the patient history up to the end date
238 - If no end date is provided it will retrieve all records connected to encounters starting from the start date
239 - If a records for a specific service date are desired, make the start date and end date the same day in YYYY-MM-DD format.
240 - Dates must be specified in least specifity to most specifity for wildcard like operations IE YYYY for the beginning of the year for start date or ending of the year for end date, YYYY-MM for the beginning of the month for start date and end of the month for end date, etc.
242 ## For Developers
244 FHIR endpoints are defined in the [primary routes file](_rest_routes.inc.php). The routes file maps an external, addressable
245 endpoint to the OpenEMR FHIR controller which handles the request, and also handles the JSON data conversions.
247 ```php
248 "GET /fhir/Patient" => function () {
249     RestConfig::authorization_check("patients", "demo");
250     $return = (new FhirPatientRestController())->getAll($_GET);
251     RestConfig::apiLog($return);
252     return $return;
256 At a high level, the request processing flow consists of the following steps:
259 JSON Request -> FHIR Controller Component -> FHIR Validation -> Parsing FHIR Resource -> Standard Service Component -> Validation -> Database
262 The logical response flow begins with the database result:
265 Database Result -> Service Component -> FHIR Service Component -> Parse OpenEMR Record -> FHIR Controller Component -> RequestControllerHelper -> JSON Response