Merge pull request #4297 from sunsetsystems/whrwork3
[openemr.git] / FHIR_README.md
blob08fd19d0ccd481cde58c405cd6541c70703d9892
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       "family": "Chalmers",
160       "given": [ "Peter", "James" ]
161   } ],
162   "gender": "male",
163   "birthDate": "1974-12-25"
167 #### PUT fhir/Patient/[id]
169 Request:
171 ```sh
172 curl -X PUT -H 'Content-Type: application/fhir+json' 'http://localhost:8300/apis/default/fhir/Patient/90a8923c-0b1c-4d0a-9981-994b143381a7' -d \
174   "resourceType": "Patient",
175   "id": "1",
176   "identifier": [ { "system": "urn:oid:1.2.36.146.595.217.0.1", "value": "12345" } ],
177   "name": [ {
178       "family": "Chalmers",
179       "given": [ "Peter", "James" ]
180   } ],
181   "gender": "male",
182   "birthDate": "1974-01-13",
183   "address": [ {
184       "line": [ "534 Erewhon St" ],
185       "city": "PleasantVille",
186       "state": "Vic",
187       "postalCode": "3999"
188   } ]
192 #### PUT fhir/Patient/[id]
194 Request:
196 ```sh
197 curl -X PUT -H 'Content-Type: application/fhir+json' 'http://localhost:8300/apis/default/fhir/Patient/90a8923c-0b1c-4d0a-9981-994b143381a7' -d \
200    "op": "replace",
201    "path": "/address/0/postalCode",
202    "value": "M5C 2X8"
203  },
205    "op": "replace",
206    "path": "/birthDate",
207    "value": "1974-02-13"
214 ### Coverage Resource
216 #### GET fhir/Coverage
218 Request:
220 ```sh
221 curl -X GET 'http://localhost:8300/apis/default/fhir/Coverage'
224 #### GET fhir/Coverage[id]
226 Request:
228 ```sh
229 curl -X GET 'http://localhost:8300/apis/default/fhir/Coverage/926c051b-9eaf-4753-b5d3-65c3f329e656'
232 -   Supported Search Parameters
233     -   \_id
234     -   patient
235     -   payor
240 ### Encounter Resource
242 #### GET fhir/Encounter
244 Request:
246 ```sh
247 curl -X GET 'http://localhost:8300/apis/default/fhir/Encounter'
250 #### GET fhir/Encounter[id]
252 Request:
254 ```sh
255 curl -X GET 'http://localhost:8300/apis/default/fhir/Encounter/90c196f2-51cc-4655-8858-3a80aebff3ef'
258 -   Supported Search Parameters
259     -   \_id
260     -   patient
261     -   date {gt|lt|ge|le}
265 ### Practitioner Resource
267 #### GET fhir/Practitioner
269 Request:
271 ```sh
272 curl -X GET 'http://localhost:8300/apis/default/fhir/Practitioner'
275 #### GET fhir/Practitioner[id]
277 Request:
279 ```sh
280 curl -X GET 'http://localhost:8300/apis/default/fhir/Practitioner/90a8923c-0b1c-4d0a-9981-994b143381a7'
283 -   Supported Search Parameters
284     -   address
285     -   address-city
286     -   address-postalcode
287     -   address-state
288     -   email
289     -   active
290     -   family
291     -   given
292     -   name
293     -   phone
294     -   telecom
296 #### POST fhir/Practitioner
298 Request:
300 ```sh
301 curl -X POST -H 'Content-Type: application/fhir+json' 'http://localhost:8300/apis/default/fhir/Practitioner' -d \
303   "resourceType": "Practitioner",
304   "identifier": [ { "system": "http://hl7.org/fhir/sid/us-npi", "value": "1122334499" } ],
305   "name": [ {
306       "use": "official",
307       "family": "Chalmers",
308       "given": [ "Peter", "James" ]
309   } ]
313 #### PUT fhir/Practitioner/[id]
315 Request:
317 ```sh
318 curl -X PUT -H 'Content-Type: application/fhir+json' 'http://localhost:8300/apis/default/fhir/Practitioner/90a8923c-0b1c-4d0a-9981-994b143381a7' -d \
320   "resourceType": "Practitioner",
321   "identifier": [ { "system": "http://hl7.org/fhir/sid/us-npi", "value": "1155667799" } ],
322   "name": [ {
323       "use": "official",
324       "family": "Theil",
325       "given": [ "Katy", "Wilson" ]
326   } ],
327   "address": [ {
328       "line": [ "534 Erewhon St" ],
329       "city": "PleasantVille",
330       "state": "Vic",
331       "postalCode": "3999"
332   } ]
338 ### PractitionerRole Resource
340 #### GET fhir/PractitionerRole
342 Request:
344 ```sh
345 curl -X GET 'http://localhost:8300/apis/default/fhir/PractitionerRole'
348 #### GET fhir/PractitionerRole/[id]
350 Request:
352 ```sh
353 curl -X GET 'http://localhost:8300/apis/default/fhir/PractitionerRole/90de091a-91e9-4bbe-9a81-75ed623f65bf'
356 -   Supported Search Parameters
357     -   speciality
358     -   practitioner
362 ### Immunization Resource
364 #### GET fhir/Immunization
366 Request:
368 ```sh
369 curl -X GET 'http://localhost:8300/apis/default/fhir/Immunization'
372 #### GET fhir/Immunization/[id]
374 Request:
376 ```sh
377 curl -X GET 'http://localhost:8300/apis/default/fhir/Immunization/90feaaa2-4097-4437-966e-c425d1958dd6'
380 -   Supported Search Parameters
381     -   patient
385 ### AllergyIntolerance Resource
387 #### GET fhir/AllergyIntolerance
389 Request:
391 ```sh
392 curl -X GET 'http://localhost:8300/apis/default/fhir/AllergyIntolerance'
395 #### GET fhir/AllergyIntolerance/[id]
397 Request:
399 ```sh
400 curl -X GET 'http://localhost:8300/apis/default/fhir/AllergyIntolerance/90feaaa2-4097-4437-966e-c425d1958dd6'
405 ### Organization Resource
407 #### GET /fhir/Organization
409 Request:
411 ```sh
412 curl -X GET 'http://localhost:8300/apis/default/fhir/Organization'
415 #### GET /fhir/Organization/:id
417 Request:
419 ```sh
420 curl -X GET 'http://localhost:8300/apis/default/fhir/Organization/1'
425 ### Observation Resource
427 #### GET /fhir/Observation
429 Request:
431 ```sh
432 curl -X GET 'http://localhost:8300/apis/default/fhir/Observation'
435 #### GET /fhir/Observation/:uuid
437 Request:
439 ```sh
440 curl -X GET 'http://localhost:8300/apis/default/fhir/Observation/9150635b-0705-4a27-8820-df8b56cf07eb'
445 ### QuestionnaireResponse Resource
447 #### POST /fhir/QuestionnaireResponse
449 Request:
451 ```sh
452 curl -X POST -H 'Content-Type: application/fhir+json' 'http://localhost:8300/apis/default/fhir/QuestionnaireResponse' -d \
454   "resourceType": "QuestionnaireResponse",
455   "id": "697485",
456   "meta": {
457     "versionId": "1",
458     "lastUpdated": "2020-03-22T09:11:45.181+00:00",
459     "source": "#L0otRLyoImuOVD2S"
460   },
461   "status": "completed",
462   "item": [ {
463     "linkId": "1",
464     "text": "Do you have allergies?"
465   }, {
466     "linkId": "2",
467     "text": "General questions",
468     "item": [ {
469       "linkId": "2.1",
470       "text": "What is your gender?"
471     }, {
472       "linkId": "2.2",
473       "text": "What is your date of birth?"
474     }]
475   }]
476   } ]
482 ### Condition Resource
484 #### GET fhir/Condition
486 Request:
488 ```sh
489 curl -X GET 'http://localhost:8300/apis/default/fhir/Condition'
492 #### GET fhir/Condition/[id]
494 Request:
496 ```sh
497 curl -X GET 'http://localhost:8300/apis/default/fhir/Condition/9109890a-6756-44c1-a82d-bdfac91c7424'
502 ### Procedure Resource
504 #### GET /fhir/Procedure
506 Request:
508 ```sh
509 curl -X GET 'http://localhost:8300/apis/default/fhir/Procedure'
512 #### GET /fhir/Procedure/:uuid
514 Request:
516 ```sh
517 curl -X GET 'http://localhost:8300/apis/default/fhir/Procedure/9109890a-6756-44c1-a82d-bdfac91c7424'
522 ### MedicationRequest Resource
524 #### GET /fhir/MedicationRequest
526 Request:
528 ```sh
529 curl -X GET 'http://localhost:8300/apis/default/fhir/MedicationRequest'
532 #### GET /fhir/MedicationRequest/:uuid
534 Request:
536 ```sh
537 curl -X GET 'http://localhost:8300/apis/default/fhir/MedicationRequest/9128a1ec-95be-4649-8a66-d3686b7ab0ca'
542 ### Medication Resource
544 #### GET /fhir/Medication
546 Request:
548 ```sh
549 curl -X GET 'http://localhost:8300/apis/default/fhir/Medication'
552 #### GET /fhir/Medication/:uuid
554 Request:
556 ```sh
557 curl -X GET 'http://localhost:8300/apis/default/fhir/Medication/9109890a-6756-44c1-a82d-bdfac91c7424'
562 ### Location Resource
564 #### GET /fhir/Location
566 Request:
568 ```sh
569 curl -X GET 'http://localhost:8300/apis/default/fhir/Location'
572 #### GET /fhir/Location/:uuid
574 Request:
576 ```sh
577 curl -X GET 'http://localhost:8300/apis/default/fhir/Location/90f3d0e9-2a19-453b-84bd-1fa2b533f96c'
582 ### CareTeam Resource
584 #### GET /fhir/CareTeam
586 Request:
588 ```sh
589 curl -X GET 'http://localhost:8300/apis/default/fhir/CareTeam'
592 #### GET /fhir/CareTeam/:uuid
594 Request:
596 ```sh
597 curl -X GET 'http://localhost:8300/apis/default/fhir/CareTeam/915e8fb4-86b2-4365-a420-d46fc07d5aed'
602 ### Provenance Resources
604 Provenance resources are requested by including `_revinclude=Provenance:target` in the search of a resource. Is currently supported for the following resources:
605   - AllergyIntolerance
606       ```sh
607       curl -X GET 'http://localhost:8300/apis/default/fhir/AllergyIntolerance?_revinclude=Provenance:target'
608       ```
609 ### BULK FHIR Exports
610 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:
611  - System Export, requires the **system/\*.$export** scope.  Exports All supported FHIR resources
612     ```sh
613           curl -X GET 'https://localhost:9300/apis/default/fhir/$export'
614     ```
615  - 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.
616    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.
617     ```sh
618           curl -X GET 'https://localhost:9300/apis/default/fhir/Group/1/$export'
619     ```
620  - 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).
621     ```sh
622           curl -X GET 'https://localhost:9300/apis/default/fhir/Patient/$export'
623     ``` 
624 You will get an empty body response with a **Content-Location** header with the URL you can query for status updates on the export. 
626 To query the status update operation you need the **system/\*.$bulkdata-status** scope.  An example query:
627  - Status Query
628     ```sh
629           curl -X GET 'https://localhost:9300/apis/default/fhir/$bulkdata-status?job=92a94c00-77d6-4dfc-ae3b-73550742536d'
630     ``` 
632 A status Query will return a result like the following:
635   "transactionTime": {
636     "date": "2021-02-05 20:48:38.000000",
637     "timezone_type": 3,
638     "timezone": "UTC"
639   },
640   "request": "\/apis\/default\/fhir\/Group\/1\/%24export",
641   "requiresAccessToken": true,
642   "output": [
643     {
644       "url": "https:\/\/localhost:9300\/apis\/default\/fhir\/Document\/97552\/Binary",
645       "type": "Patient"
646     },
647     {
648       "url": "https:\/\/localhost:9300\/apis\/default\/fhir\/Document\/105232\/Binary",
649       "type": "Encounter"
650     }
651   ],
652   "error": []
656 You can download the exported documents which are formatted in Newline Delimited JSON (NDJSON) by making a call to:
657     ```sh
658           curl -X GET 'https://10.0.0.9:9300/apis/default/fhir/Document/105232/Binary'
659     ```