button name change (#3991)
[openemr.git] / FHIR_README.md
blob5a3155bdffcd35b319623da28f2755c8affb87db
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 "POST /fhir/Patient" => function () {
14     RestConfig::authorization_check("patients", "demo");
15     $data = (array)(json_decode(file_get_contents("php://input"), true));
16     return (new FhirPatientRestController())->post($data);
18 ```
20 At a high level, the request processing flow consists of the following steps:
22 ```
23 JSON Request -> FHIR Controller Component -> FHIR Validation -> Parsing FHIR Resource -> Standard Service Component -> Validation -> Database
24 ```
26 The logical response flow begins with the database result:
28 ```
29 Database Result -> Service Component -> FHIR Service Component -> Parse OpenEMR Record -> FHIR Controller Component -> RequestControllerHelper -> JSON Response
30 ```
32 ### Sections
34 -   [FHIR API Endpoints](FHIR_README.md#fhir-endpoints)
35     -   [Capability Statement](FHIR_README.md#capability-statement)
36     -   [Authorization](FHIR_README.md#authorization)
37     -   [Patient](FHIR_README.md#patient-resource)
38     -   [Encounter](FHIR_README.md#encounter-resource)
39     -   [Practitioner](FHIR_README.md#practitioner-resource)
40     -   [PractitionerRole](FHIR_README.md#practitionerrole-resource)
41     -   [Immunization](FHIR_README.md#immunization-resource)
42     -   [AllergyIntolerance](FHIR_README.md#allergyintolerance-resource)
43     -   [Organization](FHIR_README.md#organization-resource)
44     -   [Observation](FHIR_README.md#observation-resource)
45     -   [QuestionnaireResponse](FHIR_README.md#questionnaireresponse-resource)
46     -   [Condition](FHIR_README.md#condition-resource)
47     -   [Procedure](FHIR_README.md#procedure-resource)
48     -   [MedicationRequest](FHIR_README.md#medicationrequest-resource)
49     -   [Medication](FHIR_README.md#medication-resource)
50     -   [Location](FHIR_README.md#location-resource)
51     -   [CareTeam](FHIR_README.md#careTeam-resource)
52     -   [Provenance](FHIR_README.md#Provenance-resources)
53 -   [Patient Portal FHIR API Endpoints](FHIR_README.md#patient-portal-fhir-endpoints)
54     -   [Authorization](FHIR_README.md#patient-portal-authorization)
55     -   [Patient](FHIR_README.md#patient-portal-patient-resource)
57 ### Prerequisite
59 Enable the Standard FHIR service (/fhir/ endpoints) in OpenEMR menu: Administration->Globals->Connectors->"Enable OpenEMR Standard FHIR REST API"
60 Enable the Patient Portal FHIR service (/portalfhir/ endpoints) in OpenEMR menu: Administration->Globals->Connectors->"Enable OpenEMR Patient Portal FHIR REST API"
62 ### Using FHIR API Internally
64 There are several ways to make API calls from an authorized session and maintain security:
66 -   See the script at tests/api/InternalApiTest.php for examples of internal API use cases.
68 ## FHIR Endpoints
70 Standard FHIR endpoints Use `http://localhost:8300/apis/fhir as base URI.`
72 _Example:_ `http://localhost:8300/apis/fhir/Patient` returns a Patient's bundle resource, etc
74 ---
76 ### Capability Statement
78 #### GET fhir/metadata
80 This will return the Capability Statement.
82 ```sh
83 curl -X GET 'http://localhost:8300/apis/fhir/metadata'
84 ```
86 ---
88 ### Authorization
90 #### POST fhir/auth
92 The OpenEMR FHIR API utilizes the OAuth2 password credential flow for authentication. To obtain an API token, submit your login credentials and requested scope. The scope must match a site that has been setup in OpenEMR, in the /sites/ directory. If additional sites have not been created, set the scope to 'default'.
94 Request:
96 ```sh
97 curl -X POST -H 'Content-Type: application/json' 'http://localhost:8300/apis/fhir/auth' \
98 -d '{
99     "grant_type":"password",
100     "username": "ServiceUser",
101     "password": "password",
102     "scope":"site id"
106 Response:
108 ```json
110     "token_type": "Bearer",
111     "access_token": "eyJ0b2tlbiI6IjAwNmZ4TWpsNWhsZmNPelZicXBEdEZVUlNPQUY5KzdzR1Jjejc4WGZyeGFjUjY2QlhaaEs4eThkU3cxbTd5VXFBeTVyeEZpck9mVzBQNWc5dUlidERLZ0trUElCME5wRDVtTVk5bE9WaE5DTHF5RnRnT0Q0OHVuaHRvbXZ6OTEyNmZGUmVPUllSYVJORGoyZTkzTDA5OWZSb0ZRVGViTUtWUFd4ZW5cL1piSzhIWFpJZUxsV3VNcUdjQXR5dmlLQXRXNDAiLCJzaXRlX2lkIjoiZGVmYXVsdCIsImFwaSI6Im9lbXIifQ==",
112     "expires_in": "3600",
113     "user_data": {
114         "user_id": "1"
115     }
119 The Bearer token is required for each OpenEMR API request, and is conveyed using an Authorization header.
121 Request:
123 ```sh
124 curl -X GET 'http://localhost:8300/apis/fhir/Patient' \
125   -H 'Authorization: Bearer eyJ0b2tlbiI6IjAwNnZ3eGJZYmFrOXlxUjF4U290Y1g4QVVDd3JOcG5yYXZEaFlqaHFjWXJXRGNDQUtFZmJONkh2cElTVkJiaWFobHBqOTBYZmlNRXpiY2FtU01pSHk1UzFlMmgxNmVqZEhcL1ZENlNtaVpTRFRLMmtsWDIyOFRKZzNhQmxMdUloZmNJM3FpMGFKZ003OXdtOGhYT3dpVkx5b3BFRXQ1TlNYNTE3UW5TZ0dsUVdQbG56WjVxOVYwc21tdDlSQ3RvcDV3TEkiLCJzaXRlX2lkIjoiZGVmYXVsdCIsImFwaSI6ImZoaXIifQ=='
130 ### Patient Resource
132 #### GET fhir/Patient
134 Request:
136 ```sh
137 curl -X GET 'http://localhost:8300/apis/fhir/Patient'
140 #### GET fhir/Patient[id]
142 Request:
144 ```sh
145 curl -X GET 'http://localhost:8300/apis/fhir/Patient/90a8923c-0b1c-4d0a-9981-994b143381a7'
148 -   Supported Search Parameters
149     -   address
150     -   address-city
151     -   address-postalcode
152     -   address-state
153     -   birthdate
154     -   email
155     -   family
156     -   gender
157     -   given
158     -   name
159     -   phone
160     -   telecom
162 #### POST fhir/Patient
164 Request:
166 ```sh
167 curl -X POST -H 'Content-Type: application/fhir+json' 'http://localhost:8300/apis/fhir/Patient' -d \
169   "resourceType": "Patient",
170   "identifier": [ { "system": "urn:oid:1.2.36.146.595.217.0.1", "value": "12345" } ],
171   "name": [ {
172       "family": "Chalmers",
173       "given": [ "Peter", "James" ]
174   } ],
175   "gender": "male",
176   "birthDate": "1974-12-25"
180 #### PUT fhir/Patient/[id]
182 Request:
184 ```sh
185 curl -X PUT -H 'Content-Type: application/fhir+json' 'http://localhost:8300/apis/fhir/Patient/90a8923c-0b1c-4d0a-9981-994b143381a7' -d \
187   "resourceType": "Patient",
188   "id": "1",
189   "identifier": [ { "system": "urn:oid:1.2.36.146.595.217.0.1", "value": "12345" } ],
190   "name": [ {
191       "family": "Chalmers",
192       "given": [ "Peter", "James" ]
193   } ],
194   "gender": "male",
195   "birthDate": "1974-01-13",
196   "address": [ {
197       "line": [ "534 Erewhon St" ],
198       "city": "PleasantVille",
199       "state": "Vic",
200       "postalCode": "3999"
201   } ]
205 #### PATCH fhir/Patient/[id]
207 Request:
209 ```sh
210 curl -X PATCH -H 'Content-Type: application/fhir+json' 'http://localhost:8300/apis/fhir/Patient/90a8923c-0b1c-4d0a-9981-994b143381a7' -d \
213    "op": "replace",
214    "path": "/address/0/postalCode",
215    "value": "M5C 2X8"
216  },
218    "op": "replace",
219    "path": "/birthDate",
220    "value": "1974-02-13"
227 ### Encounter Resource
229 #### GET fhir/Encounter
231 Request:
233 ```sh
234 curl -X GET 'http://localhost:8300/apis/fhir/Encounter'
237 #### GET fhir/Encounter[id]
239 Request:
241 ```sh
242 curl -X GET 'http://localhost:8300/apis/fhir/Encounter/90c196f2-51cc-4655-8858-3a80aebff3ef'
245 -   Supported Search Parameters
246     -   \_id
247     -   patient
248     -   date {gt|lt|ge|le}
252 ### Practitioner Resource
254 #### GET fhir/Practitioner
256 Request:
258 ```sh
259 curl -X GET 'http://localhost:8300/apis/fhir/Practitioner'
262 #### GET fhir/Practitioner[id]
264 Request:
266 ```sh
267 curl -X GET 'http://localhost:8300/apis/fhir/Practitioner/90a8923c-0b1c-4d0a-9981-994b143381a7'
270 -   Supported Search Parameters
271     -   address
272     -   address-city
273     -   address-postalcode
274     -   address-state
275     -   email
276     -   active
277     -   family
278     -   given
279     -   name
280     -   phone
281     -   telecom
283 #### POST fhir/Practitioner
285 Request:
287 ```sh
288 curl -X POST -H 'Content-Type: application/fhir+json' 'http://localhost:8300/apis/fhir/Practitioner' -d \
290   "resourceType": "Practitioner",
291   "identifier": [ { "system": "http://hl7.org/fhir/sid/us-npi", "value": "1122334499" } ],
292   "name": [ {
293       "use": "official",
294       "family": "Chalmers",
295       "given": [ "Peter", "James" ]
296   } ]
300 #### PATCH fhir/Practitioner/[id]
302 Request:
304 ```sh
305 curl -X PATCH -H 'Content-Type: application/fhir+json' 'http://localhost:8300/apis/fhir/Practitioner/90a8923c-0b1c-4d0a-9981-994b143381a7' -d \
307   "resourceType": "Practitioner",
308   "identifier": [ { "system": "http://hl7.org/fhir/sid/us-npi", "value": "1155667799" } ],
309   "name": [ {
310       "use": "official",
311       "family": "Theil",
312       "given": [ "Katy", "Wilson" ]
313   } ],
314   "address": [ {
315       "line": [ "534 Erewhon St" ],
316       "city": "PleasantVille",
317       "state": "Vic",
318       "postalCode": "3999"
319   } ]
325 ### PractitionerRole Resource
327 #### GET fhir/PractitionerRole
329 Request:
331 ```sh
332 curl -X GET 'http://localhost:8300/apis/fhir/PractitionerRole'
335 #### GET fhir/PractitionerRole/[id]
337 Request:
339 ```sh
340 curl -X GET 'http://localhost:8300/apis/fhir/PractitionerRole/90de091a-91e9-4bbe-9a81-75ed623f65bf'
343 -   Supported Search Parameters
344     -   speciality
345     -   practitioner
349 ### Immunization Resource
351 #### GET fhir/Immunization
353 Request:
355 ```sh
356 curl -X GET 'http://localhost:8300/apis/fhir/Immunization'
359 #### GET fhir/Immunization/[id]
361 Request:
363 ```sh
364 curl -X GET 'http://localhost:8300/apis/fhir/Immunization/90feaaa2-4097-4437-966e-c425d1958dd6'
367 -   Supported Search Parameters
368     -   patient
372 ### AllergyIntolerance Resource
374 #### GET fhir/AllergyIntolerance
376 Request:
378 ```sh
379 curl -X GET 'http://localhost:8300/apis/fhir/AllergyIntolerance'
382 #### GET fhir/AllergyIntolerance/[id]
384 Request:
386 ```sh
387 curl -X GET 'http://localhost:8300/apis/fhir/AllergyIntolerance/90feaaa2-4097-4437-966e-c425d1958dd6'
392 ### Organization Resource
394 #### GET /fhir/Organization
396 Request:
398 ```sh
399 curl -X GET 'http://localhost:8300/apis/fhir/Organization'
402 #### GET /fhir/Organization/:id
404 Request:
406 ```sh
407 curl -X GET 'http://localhost:8300/apis/fhir/Organization/1'
412 ### Observation Resource
414 #### GET /fhir/Observation
416 Request:
418 ```sh
419 curl -X GET 'http://localhost:8300/apis/fhir/Observation'
422 #### GET /fhir/Observation/:uuid
424 Request:
426 ```sh
427 curl -X GET 'http://localhost:8300/apis/fhir/Observation/9150635b-0705-4a27-8820-df8b56cf07eb'
432 ### QuestionnaireResponse Resource
434 #### POST /fhir/QuestionnaireResponse
436 Request:
438 ```sh
439 curl -X POST -H 'Content-Type: application/fhir+json' 'http://localhost:8300/apis/fhir/QuestionnaireResponse' -d \
441   "resourceType": "QuestionnaireResponse",
442   "id": "697485",
443   "meta": {
444     "versionId": "1",
445     "lastUpdated": "2020-03-22T09:11:45.181+00:00",
446     "source": "#L0otRLyoImuOVD2S"
447   },
448   "status": "completed",
449   "item": [ {
450     "linkId": "1",
451     "text": "Do you have allergies?"
452   }, {
453     "linkId": "2",
454     "text": "General questions",
455     "item": [ {
456       "linkId": "2.1",
457       "text": "What is your gender?"
458     }, {
459       "linkId": "2.2",
460       "text": "What is your date of birth?"
461     }]
462   }]
463   } ]
469 ### Condition Resource
471 #### GET fhir/Condition
473 Request:
475 ```sh
476 curl -X GET 'http://localhost:8300/apis/fhir/Condition'
479 #### GET fhir/Condition/[id]
481 Request:
483 ```sh
484 curl -X GET 'http://localhost:8300/apis/fhir/Condition/9109890a-6756-44c1-a82d-bdfac91c7424'
489 ### Procedure Resource
491 #### GET /fhir/Procedure
493 Request:
495 ```sh
496 curl -X GET 'http://localhost:8300/apis/fhir/Procedure'
499 #### GET /fhir/Procedure/:uuid
501 Request:
503 ```sh
504 curl -X GET 'http://localhost:8300/apis/fhir/Procedure/9109890a-6756-44c1-a82d-bdfac91c7424'
509 ### MedicationRequest Resource
511 #### GET /fhir/MedicationRequest
513 Request:
515 ```sh
516 curl -X GET 'http://localhost:8300/apis/fhir/MedicationRequest'
519 #### GET /fhir/MedicationRequest/:uuid
521 Request:
523 ```sh
524 curl -X GET 'http://localhost:8300/apis/fhir/MedicationRequest/9128a1ec-95be-4649-8a66-d3686b7ab0ca'
529 ### Medication Resource
531 #### GET /fhir/Medication
533 Request:
535 ```sh
536 curl -X GET 'http://localhost:8300/apis/fhir/Medication'
539 #### GET /fhir/Medication/:uuid
541 Request:
543 ```sh
544 curl -X GET 'http://localhost:8300/apis/fhir/Medication/9109890a-6756-44c1-a82d-bdfac91c7424'
549 ### Location Resource
551 #### GET /fhir/Location
553 Request:
555 ```sh
556 curl -X GET 'http://localhost:8300/apis/fhir/Location'
559 #### GET /fhir/Location/:uuid
561 Request:
563 ```sh
564 curl -X GET 'http://localhost:8300/apis/fhir/Location/90f3d0e9-2a19-453b-84bd-1fa2b533f96c'
569 ### CareTeam Resource
571 #### GET /fhir/CareTeam
573 Request:
575 ```sh
576 curl -X GET 'http://localhost:8300/apis/fhir/CareTeam'
579 #### GET /fhir/CareTeam/:uuid
581 Request:
583 ```sh
584 curl -X GET 'http://localhost:8300/apis/fhir/CareTeam/915e8fb4-86b2-4365-a420-d46fc07d5aed'
589 ### Provenance Resources
591 Provenance resources are requested by including `_revinclude=Provenance:target` in the search of a resource. Is currently supported for the following resources:
592   - AllergyIntolerance
593       ```sh
594       curl -X GET 'http://localhost:8300/apis/fhir/AllergyIntolerance?_revinclude=Provenance:target'
595       ```
597 ## Patient Portal FHIR Endpoints
599 OpenEMR patient portal fhir endpoints Use `http://localhost:8300/apis/portalfhir as base URI.`
601 _Example:_ `http://localhost:8300/apis/portalfhir/Patient` returns a resource of the patient.
605 ### Patient Portal Authorization
607 #### POST /portalfhir/auth
609 The OpenEMR Patient Portal FHIR service utilizes the OAuth2 password credential flow for authentication. To obtain an API token, submit your login credentials and requested scope. The scope must match a site that has been setup in OpenEMR, in the /sites/ directory. If additional sites have not been created, set the scope
610 to 'default'. If the patient portal is set to require email address on authenticate, then need to also include an `email` field in the request.
612 Request:
614 ```sh
615 curl -X POST -H 'Content-Type: application/json' 'http://localhost:8300/apis/portalfhir/auth' \
616 -d '{
617     "grant_type":"password",
618     "username": "ServiceUser",
619     "password": "password",
620     "scope":"site id"
624 Response:
626 ```json
628     "token_type": "Bearer",
629     "access_token": "eyJ0b2tlbiI6IjAwNmZ4TWpsNWhsZmNPelZicXBEdEZVUlNPQUY5KzdzR1Jjejc4WGZyeGFjUjY2QlhaaEs4eThkU3cxbTd5VXFBeTVyeEZpck9mVzBQNWc5dUlidERLZ0trUElCME5wRDVtTVk5bE9WaE5DTHF5RnRnT0Q0OHVuaHRvbXZ6OTEyNmZGUmVPUllSYVJORGoyZTkzTDA5OWZSb0ZRVGViTUtWUFd4ZW5cL1piSzhIWFpJZUxsV3VNcUdjQXR5dmlLQXRXNDAiLCJzaXRlX2lkIjoiZGVmYXVsdCIsImFwaSI6Im9lbXIifQ==",
630     "expires_in": "3600",
631     "user_data": {
632         "user_id": "1"
633     }
637 The Bearer token is required for each OpenEMR Patient Portal FHIR service request, and is conveyed using an Authorization header.
639 Request:
641 ```sh
642 curl -X GET 'http://localhost:8300/apis/portalfhir/Patient' \
643   -H 'Authorization: Bearer eyJ0b2tlbiI6IjAwNmZ4TWpsNWhsZmNPelZicXBEdEZVUlNPQUY5KzdzR1Jjejc4WGZyeGFjUjY2QlhaaEs4eThkU3cxbTd5VXFBeTVyeEZpck9mVzBQNWc5dUlidERLZ0trUElCME5wRDVtTVk5bE9WaE5DTHF5RnRnT0Q0OHVuaHRvbXZ6OTEyNmZGUmVPUllSYVJORGoyZTkzTDA5OWZSb0ZRVGViTUtWUFd4ZW5cL1piSzhIWFpJZUxsV3VNcUdjQXR5dmlLQXRXNDAiLCJzaXRlX2lkIjoiZGVmYXVsdCIsImFwaSI6Im9lbXIifQ=='
648 ### Patient Portal Patient Resource
650 #### GET /portalfhir/Patient
652 Request:
654 ```sh
655 curl -X GET 'http://localhost:8300/apis/portalfhir/Patient'