minor updates to UuidRegistry class (#4485)
[openemr.git] / FHIR_README.md
blobc8fa8ec2a428386df56ba684096e64d3745e97bd
1 # OpenEMR FHIR API Documentation
3 ## Overview
5 Easy-to-use JSON-based REST API for OpenEMR FHIR. All code is done in classes and separate from the view to help with codebase modernization efforts. See standard OpenEMR API docs [here](API_README.md)
7 ## Implementation
9 FHIR endpoints are defined in the [primary routes file](_rest_routes.inc.php). The routes file maps an external, addressable
10 endpoint to the OpenEMR FHIR controller which handles the request, and also handles the JSON data conversions.
12 ```php
13 "GET /fhir/Patient" => function () {
14     RestConfig::authorization_check("patients", "demo");
15     $return = (new FhirPatientRestController())->getAll($_GET);
16     RestConfig::apiLog($return);
17     return $return;
19 ```
21 At a high level, the request processing flow consists of the following steps:
23 ```
24 JSON Request -> FHIR Controller Component -> FHIR Validation -> Parsing FHIR Resource -> Standard Service Component -> Validation -> Database
25 ```
27 The logical response flow begins with the database result:
29 ```
30 Database Result -> Service Component -> FHIR Service Component -> Parse OpenEMR Record -> FHIR Controller Component -> RequestControllerHelper -> JSON Response
31 ```
33 ### Sections
34 -   [Authorization](API_README.md#authorization)
35     -   [Scopes](API_README.md#scopes)
36     -   [Registration](API_README.md#registration)
37         -   [SMART on FHIR Registration](API_README.md#smart-on-fhir-registration)
38     -   [Authorization Code Grant](API_README.md#authorization-code-grant)
39     -   [Refresh Token Grant](API_README.md#refresh-token-grant)
40     -   [Password Grant](API_README.md#password-grant)
41     -   [Client Credentials Grant](API_README.md#client-credentials-grant)
42     -   [Logout](API_README.md#logout)
43     -   [More Details](API_README.md#more-details)
44 -   [FHIR API Endpoints](FHIR_README.md#fhir-endpoints)
45     -   [Capability Statement](FHIR_README.md#capability-statement)
46     -   [Patient](FHIR_README.md#patient-resource)
47     -   [Coverage](FHIR_README.md#coverage-resource)
48     -   [Encounter](FHIR_README.md#encounter-resource)
49     -   [Practitioner](FHIR_README.md#practitioner-resource)
50     -   [PractitionerRole](FHIR_README.md#practitionerrole-resource)
51     -   [Immunization](FHIR_README.md#immunization-resource)
52     -   [AllergyIntolerance](FHIR_README.md#allergyintolerance-resource)
53     -   [Organization](FHIR_README.md#organization-resource)
54     -   [Observation](FHIR_README.md#observation-resource)
55     -   [Condition](FHIR_README.md#condition-resource)
56     -   [Procedure](FHIR_README.md#procedure-resource)
57     -   [MedicationRequest](FHIR_README.md#medicationrequest-resource)
58     -   [Medication](FHIR_README.md#medication-resource)
59     -   [Location](FHIR_README.md#location-resource)
60     -   [CareTeam](FHIR_README.md#careTeam-resource)
61     -   [Provenance](FHIR_README.md#Provenance-resources)
62     -   [System Export](FHIR_README.md#SystemExport-resource)
63     -   [Patient Export](FHIR_README.md#PatientExport-resource)
64     -   [Group Export](FHIR_README.md#GroupExport-resource)
66 ### Prerequisite
68 Enable the Standard FHIR service (/fhir/ endpoints) in OpenEMR menu: Administration->Globals->Connectors->"Enable OpenEMR Standard FHIR REST API"
70 ### Using FHIR API Internally
72 There are several ways to make API calls from an authorized session and maintain security:
74 -   See the script at tests/api/InternalApiTest.php for examples of internal API use cases.
76 ### Multisite Support
78 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`.
80 ### Authorization
82 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.
84 See [Authorization](API_README.md#authorization) for more details.
86 ### FHIR Endpoints
88 Standard FHIR endpoints Use `http://localhost:8300/apis/default/fhir as base URI.`
90 Note that the `default` component can be changed to the name of the site when using OpenEMR's multisite feature.
92 _Example:_ `http://localhost:8300/apis/default/fhir/Patient` returns a Patient's bundle resource, etc
94 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.
96 Request:
98 ```sh
99 curl -X GET 'http://localhost:8300/apis/fhir/Patient' \
100   -H 'Authorization: Bearer eyJ0b2tlbiI6IjAwNnZ3eGJZYmFrOXlxUjF4U290Y1g4QVVDd3JOcG5yYXZEaFlqaHFjWXJXRGNDQUtFZmJONkh2cElTVkJiaWFobHBqOTBYZmlNRXpiY2FtU01pSHk1UzFlMmgxNmVqZEhcL1ZENlNtaVpTRFRLMmtsWDIyOFRKZzNhQmxMdUloZmNJM3FpMGFKZ003OXdtOGhYT3dpVkx5b3BFRXQ1TlNYNTE3UW5TZ0dsUVdQbG56WjVxOVYwc21tdDlSQ3RvcDV3TEkiLCJzaXRlX2lkIjoiZGVmYXVsdCIsImFwaSI6ImZoaXIifQ=='
105 ### Capability Statement
107 #### GET fhir/metadata
109 This will return the Capability Statement.
111 ```sh
112 curl -X GET 'http://localhost:8300/apis/default/fhir/metadata'
117 ### Patient Resource
119 #### GET fhir/Patient
121 Request:
123 ```sh
124 curl -X GET 'http://localhost:8300/apis/default/fhir/Patient'
127 #### GET fhir/Patient[id]
129 Request:
131 ```sh
132 curl -X GET 'http://localhost:8300/apis/default/fhir/Patient/90a8923c-0b1c-4d0a-9981-994b143381a7'
135 -   Supported Search Parameters
136     -   address
137     -   address-city
138     -   address-postalcode
139     -   address-state
140     -   birthdate
141     -   email
142     -   family
143     -   gender
144     -   given
145     -   name
146     -   phone
147     -   telecom
149 #### POST fhir/Patient
151 Request:
153 ```sh
154 curl -X POST -H 'Content-Type: application/fhir+json' 'http://localhost:8300/apis/default/fhir/Patient' -d \
156   "resourceType": "Patient",
157   "identifier": [ { "system": "urn:oid:1.2.36.146.595.217.0.1", "value": "12345" } ],
158   "name": [ {
159       "use": "official",
160       "family": "Chalmers",
161       "given": [ "Peter", "James" ]
162   } ],
163   "gender": "male",
164   "birthDate": "1974-12-25"
168 #### PUT fhir/Patient/[id]
170 Request:
172 ```sh
173 curl -X PUT -H 'Content-Type: application/fhir+json' 'http://localhost:8300/apis/default/fhir/Patient/90a8923c-0b1c-4d0a-9981-994b143381a7' -d \
175   "resourceType": "Patient",
176   "id": "1",
177   "identifier": [ { "system": "urn:oid:1.2.36.146.595.217.0.1", "value": "12345" } ],
178   "name": [ {
179       "family": "Chalmers",
180       "given": [ "Peter", "James" ]
181   } ],
182   "gender": "male",
183   "birthDate": "1974-01-13",
184   "address": [ {
185       "line": [ "534 Erewhon St" ],
186       "city": "PleasantVille",
187       "state": "Vic",
188       "postalCode": "3999"
189   } ]
193 #### PUT fhir/Patient/[id]
195 Request:
197 ```sh
198 curl -X PUT -H 'Content-Type: application/fhir+json' 'http://localhost:8300/apis/default/fhir/Patient/90a8923c-0b1c-4d0a-9981-994b143381a7' -d \
201    "op": "replace",
202    "path": "/address/0/postalCode",
203    "value": "M5C 2X8"
204  },
206    "op": "replace",
207    "path": "/birthDate",
208    "value": "1974-02-13"
215 ### Coverage Resource
217 #### GET fhir/Coverage
219 Request:
221 ```sh
222 curl -X GET 'http://localhost:8300/apis/default/fhir/Coverage'
225 #### GET fhir/Coverage[id]
227 Request:
229 ```sh
230 curl -X GET 'http://localhost:8300/apis/default/fhir/Coverage/926c051b-9eaf-4753-b5d3-65c3f329e656'
233 -   Supported Search Parameters
234     -   \_id
235     -   patient
236     -   payor
241 ### Encounter Resource
243 #### GET fhir/Encounter
245 Request:
247 ```sh
248 curl -X GET 'http://localhost:8300/apis/default/fhir/Encounter'
251 #### GET fhir/Encounter[id]
253 Request:
255 ```sh
256 curl -X GET 'http://localhost:8300/apis/default/fhir/Encounter/90c196f2-51cc-4655-8858-3a80aebff3ef'
259 -   Supported Search Parameters
260     -   \_id
261     -   patient
262     -   date {gt|lt|ge|le}
266 ### Practitioner Resource
268 #### GET fhir/Practitioner
270 Request:
272 ```sh
273 curl -X GET 'http://localhost:8300/apis/default/fhir/Practitioner'
276 #### GET fhir/Practitioner[id]
278 Request:
280 ```sh
281 curl -X GET 'http://localhost:8300/apis/default/fhir/Practitioner/90a8923c-0b1c-4d0a-9981-994b143381a7'
284 -   Supported Search Parameters
285     -   address
286     -   address-city
287     -   address-postalcode
288     -   address-state
289     -   email
290     -   active
291     -   family
292     -   given
293     -   name
294     -   phone
295     -   telecom
297 #### POST fhir/Practitioner
299 Request:
301 ```sh
302 curl -X POST -H 'Content-Type: application/fhir+json' 'http://localhost:8300/apis/default/fhir/Practitioner' -d \
304   "resourceType": "Practitioner",
305   "identifier": [ { "system": "http://hl7.org/fhir/sid/us-npi", "value": "1122334499" } ],
306   "name": [ {
307       "use": "official",
308       "family": "Chalmers",
309       "given": [ "Peter", "James" ]
310   } ]
314 #### PUT fhir/Practitioner/[id]
316 Request:
318 ```sh
319 curl -X PUT -H 'Content-Type: application/fhir+json' 'http://localhost:8300/apis/default/fhir/Practitioner/90a8923c-0b1c-4d0a-9981-994b143381a7' -d \
321   "resourceType": "Practitioner",
322   "identifier": [ { "system": "http://hl7.org/fhir/sid/us-npi", "value": "1155667799" } ],
323   "name": [ {
324       "use": "official",
325       "family": "Theil",
326       "given": [ "Katy", "Wilson" ]
327   } ],
328   "address": [ {
329       "line": [ "534 Erewhon St" ],
330       "city": "PleasantVille",
331       "state": "Vic",
332       "postalCode": "3999"
333   } ]
339 ### PractitionerRole Resource
341 #### GET fhir/PractitionerRole
343 Request:
345 ```sh
346 curl -X GET 'http://localhost:8300/apis/default/fhir/PractitionerRole'
349 #### GET fhir/PractitionerRole/[id]
351 Request:
353 ```sh
354 curl -X GET 'http://localhost:8300/apis/default/fhir/PractitionerRole/90de091a-91e9-4bbe-9a81-75ed623f65bf'
357 -   Supported Search Parameters
358     -   speciality
359     -   practitioner
363 ### Immunization Resource
365 #### GET fhir/Immunization
367 Request:
369 ```sh
370 curl -X GET 'http://localhost:8300/apis/default/fhir/Immunization'
373 #### GET fhir/Immunization/[id]
375 Request:
377 ```sh
378 curl -X GET 'http://localhost:8300/apis/default/fhir/Immunization/90feaaa2-4097-4437-966e-c425d1958dd6'
381 -   Supported Search Parameters
382     -   patient
386 ### AllergyIntolerance Resource
388 #### GET fhir/AllergyIntolerance
390 Request:
392 ```sh
393 curl -X GET 'http://localhost:8300/apis/default/fhir/AllergyIntolerance'
396 #### GET fhir/AllergyIntolerance/[id]
398 Request:
400 ```sh
401 curl -X GET 'http://localhost:8300/apis/default/fhir/AllergyIntolerance/90feaaa2-4097-4437-966e-c425d1958dd6'
406 ### Organization Resource
408 #### GET /fhir/Organization
410 Request:
412 ```sh
413 curl -X GET 'http://localhost:8300/apis/default/fhir/Organization'
416 #### GET /fhir/Organization/:id
418 Request:
420 ```sh
421 curl -X GET 'http://localhost:8300/apis/default/fhir/Organization/1'
426 ### Observation Resource
428 #### GET /fhir/Observation
430 Request:
432 ```sh
433 curl -X GET 'http://localhost:8300/apis/default/fhir/Observation'
436 #### GET /fhir/Observation/:uuid
438 Request:
440 ```sh
441 curl -X GET 'http://localhost:8300/apis/default/fhir/Observation/9150635b-0705-4a27-8820-df8b56cf07eb'
446 ### QuestionnaireResponse Resource
448 #### POST /fhir/QuestionnaireResponse
450 Request:
452 ```sh
453 curl -X POST -H 'Content-Type: application/fhir+json' 'http://localhost:8300/apis/default/fhir/QuestionnaireResponse' -d \
455   "resourceType": "QuestionnaireResponse",
456   "id": "697485",
457   "meta": {
458     "versionId": "1",
459     "lastUpdated": "2020-03-22T09:11:45.181+00:00",
460     "source": "#L0otRLyoImuOVD2S"
461   },
462   "status": "completed",
463   "item": [ {
464     "linkId": "1",
465     "text": "Do you have allergies?"
466   }, {
467     "linkId": "2",
468     "text": "General questions",
469     "item": [ {
470       "linkId": "2.1",
471       "text": "What is your gender?"
472     }, {
473       "linkId": "2.2",
474       "text": "What is your date of birth?"
475     }]
476   }]
477   } ]
483 ### Condition Resource
485 #### GET fhir/Condition
487 Request:
489 ```sh
490 curl -X GET 'http://localhost:8300/apis/default/fhir/Condition'
493 #### GET fhir/Condition/[id]
495 Request:
497 ```sh
498 curl -X GET 'http://localhost:8300/apis/default/fhir/Condition/9109890a-6756-44c1-a82d-bdfac91c7424'
503 ### Procedure Resource
505 #### GET /fhir/Procedure
507 Request:
509 ```sh
510 curl -X GET 'http://localhost:8300/apis/default/fhir/Procedure'
513 #### GET /fhir/Procedure/:uuid
515 Request:
517 ```sh
518 curl -X GET 'http://localhost:8300/apis/default/fhir/Procedure/9109890a-6756-44c1-a82d-bdfac91c7424'
523 ### MedicationRequest Resource
525 #### GET /fhir/MedicationRequest
527 Request:
529 ```sh
530 curl -X GET 'http://localhost:8300/apis/default/fhir/MedicationRequest'
533 #### GET /fhir/MedicationRequest/:uuid
535 Request:
537 ```sh
538 curl -X GET 'http://localhost:8300/apis/default/fhir/MedicationRequest/9128a1ec-95be-4649-8a66-d3686b7ab0ca'
543 ### Medication Resource
545 #### GET /fhir/Medication
547 Request:
549 ```sh
550 curl -X GET 'http://localhost:8300/apis/default/fhir/Medication'
553 #### GET /fhir/Medication/:uuid
555 Request:
557 ```sh
558 curl -X GET 'http://localhost:8300/apis/default/fhir/Medication/9109890a-6756-44c1-a82d-bdfac91c7424'
563 ### Location Resource
565 #### GET /fhir/Location
567 Request:
569 ```sh
570 curl -X GET 'http://localhost:8300/apis/default/fhir/Location'
573 #### GET /fhir/Location/:uuid
575 Request:
577 ```sh
578 curl -X GET 'http://localhost:8300/apis/default/fhir/Location/90f3d0e9-2a19-453b-84bd-1fa2b533f96c'
583 ### CareTeam Resource
585 #### GET /fhir/CareTeam
587 Request:
589 ```sh
590 curl -X GET 'http://localhost:8300/apis/default/fhir/CareTeam'
593 #### GET /fhir/CareTeam/:uuid
595 Request:
597 ```sh
598 curl -X GET 'http://localhost:8300/apis/default/fhir/CareTeam/915e8fb4-86b2-4365-a420-d46fc07d5aed'
603 ### Provenance Resources
605 Provenance resources are requested by including `_revinclude=Provenance:target` in the search of a resource. Is currently supported for the following resources:
606   - AllergyIntolerance
607       ```sh
608       curl -X GET 'http://localhost:8300/apis/default/fhir/AllergyIntolerance?_revinclude=Provenance:target'
609       ```
610 ### BULK FHIR Exports
611 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:
612  - System Export, requires the **system/\*.$export** scope.  Exports All supported FHIR resources
613     ```sh
614           curl -X GET 'https://localhost:9300/apis/default/fhir/$export'
615     ```
616  - 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.
617    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.
618     ```sh
619           curl -X GET 'https://localhost:9300/apis/default/fhir/Group/1/$export'
620     ```
621  - 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).
622     ```sh
623           curl -X GET 'https://localhost:9300/apis/default/fhir/Patient/$export'
624     ``` 
625 You will get an empty body response with a **Content-Location** header with the URL you can query for status updates on the export. 
627 To query the status update operation you need the **system/\*.$bulkdata-status** scope.  An example query:
628  - Status Query
629     ```sh
630           curl -X GET 'https://localhost:9300/apis/default/fhir/$bulkdata-status?job=92a94c00-77d6-4dfc-ae3b-73550742536d'
631     ``` 
633 A status Query will return a result like the following:
636   "transactionTime": {
637     "date": "2021-02-05 20:48:38.000000",
638     "timezone_type": 3,
639     "timezone": "UTC"
640   },
641   "request": "\/apis\/default\/fhir\/Group\/1\/%24export",
642   "requiresAccessToken": true,
643   "output": [
644     {
645       "url": "https:\/\/localhost:9300\/apis\/default\/fhir\/Document\/97552\/Binary",
646       "type": "Patient"
647     },
648     {
649       "url": "https:\/\/localhost:9300\/apis\/default\/fhir\/Document\/105232\/Binary",
650       "type": "Encounter"
651     }
652   ],
653   "error": []
657 You can download the exported documents which are formatted in Newline Delimited JSON (NDJSON) by making a call to:
658     ```sh
659           curl -X GET 'https://10.0.0.9:9300/apis/default/fhir/Document/105232/Binary'
660     ```