1 # OpenEMR FHIR API Documentation
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)
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.
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);
20 At a high level, the request processing flow consists of the following steps:
23 JSON Request -> FHIR Controller Component -> FHIR Validation -> Parsing FHIR Resource -> Standard Service Component -> Validation -> Database
26 The logical response flow begins with the database result:
29 Database Result -> Service Component -> FHIR Service Component -> Parse OpenEMR Record -> FHIR Controller Component -> RequestControllerHelper -> JSON Response
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)
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.
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
76 ### Capability Statement
78 #### GET fhir/metadata
80 This will return the Capability Statement.
83 curl -X GET 'http://localhost:8300/apis/fhir/metadata'
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'.
97 curl -X POST -H 'Content-Type: application/json' 'http://localhost:8300/apis/fhir/auth' \
99 "grant_type":"password",
100 "username": "ServiceUser",
101 "password": "password",
110 "token_type": "Bearer",
111 "access_token": "eyJ0b2tlbiI6IjAwNmZ4TWpsNWhsZmNPelZicXBEdEZVUlNPQUY5KzdzR1Jjejc4WGZyeGFjUjY2QlhaaEs4eThkU3cxbTd5VXFBeTVyeEZpck9mVzBQNWc5dUlidERLZ0trUElCME5wRDVtTVk5bE9WaE5DTHF5RnRnT0Q0OHVuaHRvbXZ6OTEyNmZGUmVPUllSYVJORGoyZTkzTDA5OWZSb0ZRVGViTUtWUFd4ZW5cL1piSzhIWFpJZUxsV3VNcUdjQXR5dmlLQXRXNDAiLCJzaXRlX2lkIjoiZGVmYXVsdCIsImFwaSI6Im9lbXIifQ==",
112 "expires_in": "3600",
119 The Bearer token is required for each OpenEMR API request, and is conveyed using an Authorization header.
124 curl -X GET 'http://localhost:8300/apis/fhir/Patient' \
125 -H 'Authorization: Bearer eyJ0b2tlbiI6IjAwNnZ3eGJZYmFrOXlxUjF4U290Y1g4QVVDd3JOcG5yYXZEaFlqaHFjWXJXRGNDQUtFZmJONkh2cElTVkJiaWFobHBqOTBYZmlNRXpiY2FtU01pSHk1UzFlMmgxNmVqZEhcL1ZENlNtaVpTRFRLMmtsWDIyOFRKZzNhQmxMdUloZmNJM3FpMGFKZ003OXdtOGhYT3dpVkx5b3BFRXQ1TlNYNTE3UW5TZ0dsUVdQbG56WjVxOVYwc21tdDlSQ3RvcDV3TEkiLCJzaXRlX2lkIjoiZGVmYXVsdCIsImFwaSI6ImZoaXIifQ=='
132 #### GET fhir/Patient
137 curl -X GET 'http://localhost:8300/apis/fhir/Patient'
140 #### GET fhir/Patient[id]
145 curl -X GET 'http://localhost:8300/apis/fhir/Patient/90a8923c-0b1c-4d0a-9981-994b143381a7'
148 - Supported Search Parameters
162 #### POST fhir/Patient
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" } ],
172 "family": "Chalmers",
173 "given": [ "Peter", "James" ]
176 "birthDate": "1974-12-25"
180 #### PUT fhir/Patient/[id]
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",
189 "identifier": [ { "system": "urn:oid:1.2.36.146.595.217.0.1", "value": "12345" } ],
191 "family": "Chalmers",
192 "given": [ "Peter", "James" ]
195 "birthDate": "1974-01-13",
197 "line": [ "534 Erewhon St" ],
198 "city": "PleasantVille",
205 #### PATCH fhir/Patient/[id]
210 curl -X PATCH -H 'Content-Type: application/fhir+json' 'http://localhost:8300/apis/fhir/Patient/90a8923c-0b1c-4d0a-9981-994b143381a7' -d \
214 "path": "/address/0/postalCode",
219 "path": "/birthDate",
220 "value": "1974-02-13"
227 ### Encounter Resource
229 #### GET fhir/Encounter
234 curl -X GET 'http://localhost:8300/apis/fhir/Encounter'
237 #### GET fhir/Encounter[id]
242 curl -X GET 'http://localhost:8300/apis/fhir/Encounter/90c196f2-51cc-4655-8858-3a80aebff3ef'
245 - Supported Search Parameters
252 ### Practitioner Resource
254 #### GET fhir/Practitioner
259 curl -X GET 'http://localhost:8300/apis/fhir/Practitioner'
262 #### GET fhir/Practitioner[id]
267 curl -X GET 'http://localhost:8300/apis/fhir/Practitioner/90a8923c-0b1c-4d0a-9981-994b143381a7'
270 - Supported Search Parameters
283 #### POST fhir/Practitioner
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" } ],
294 "family": "Chalmers",
295 "given": [ "Peter", "James" ]
300 #### PATCH fhir/Practitioner/[id]
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" } ],
312 "given": [ "Katy", "Wilson" ]
315 "line": [ "534 Erewhon St" ],
316 "city": "PleasantVille",
325 ### PractitionerRole Resource
327 #### GET fhir/PractitionerRole
332 curl -X GET 'http://localhost:8300/apis/fhir/PractitionerRole'
335 #### GET fhir/PractitionerRole/[id]
340 curl -X GET 'http://localhost:8300/apis/fhir/PractitionerRole/90de091a-91e9-4bbe-9a81-75ed623f65bf'
343 - Supported Search Parameters
349 ### Immunization Resource
351 #### GET fhir/Immunization
356 curl -X GET 'http://localhost:8300/apis/fhir/Immunization'
359 #### GET fhir/Immunization/[id]
364 curl -X GET 'http://localhost:8300/apis/fhir/Immunization/90feaaa2-4097-4437-966e-c425d1958dd6'
367 - Supported Search Parameters
372 ### AllergyIntolerance Resource
374 #### GET fhir/AllergyIntolerance
379 curl -X GET 'http://localhost:8300/apis/fhir/AllergyIntolerance'
382 #### GET fhir/AllergyIntolerance/[id]
387 curl -X GET 'http://localhost:8300/apis/fhir/AllergyIntolerance/90feaaa2-4097-4437-966e-c425d1958dd6'
392 ### Organization Resource
394 #### GET /fhir/Organization
399 curl -X GET 'http://localhost:8300/apis/fhir/Organization'
402 #### GET /fhir/Organization/:id
407 curl -X GET 'http://localhost:8300/apis/fhir/Organization/1'
412 ### Observation Resource
414 #### GET /fhir/Observation
419 curl -X GET 'http://localhost:8300/apis/fhir/Observation'
422 #### GET /fhir/Observation/:uuid
427 curl -X GET 'http://localhost:8300/apis/fhir/Observation/9150635b-0705-4a27-8820-df8b56cf07eb'
432 ### QuestionnaireResponse Resource
434 #### POST /fhir/QuestionnaireResponse
439 curl -X POST -H 'Content-Type: application/fhir+json' 'http://localhost:8300/apis/fhir/QuestionnaireResponse' -d \
441 "resourceType": "QuestionnaireResponse",
445 "lastUpdated": "2020-03-22T09:11:45.181+00:00",
446 "source": "#L0otRLyoImuOVD2S"
448 "status": "completed",
451 "text": "Do you have allergies?"
454 "text": "General questions",
457 "text": "What is your gender?"
460 "text": "What is your date of birth?"
469 ### Condition Resource
471 #### GET fhir/Condition
476 curl -X GET 'http://localhost:8300/apis/fhir/Condition'
479 #### GET fhir/Condition/[id]
484 curl -X GET 'http://localhost:8300/apis/fhir/Condition/9109890a-6756-44c1-a82d-bdfac91c7424'
489 ### Procedure Resource
491 #### GET /fhir/Procedure
496 curl -X GET 'http://localhost:8300/apis/fhir/Procedure'
499 #### GET /fhir/Procedure/:uuid
504 curl -X GET 'http://localhost:8300/apis/fhir/Procedure/9109890a-6756-44c1-a82d-bdfac91c7424'
509 ### MedicationRequest Resource
511 #### GET /fhir/MedicationRequest
516 curl -X GET 'http://localhost:8300/apis/fhir/MedicationRequest'
519 #### GET /fhir/MedicationRequest/:uuid
524 curl -X GET 'http://localhost:8300/apis/fhir/MedicationRequest/9128a1ec-95be-4649-8a66-d3686b7ab0ca'
529 ### Medication Resource
531 #### GET /fhir/Medication
536 curl -X GET 'http://localhost:8300/apis/fhir/Medication'
539 #### GET /fhir/Medication/:uuid
544 curl -X GET 'http://localhost:8300/apis/fhir/Medication/9109890a-6756-44c1-a82d-bdfac91c7424'
549 ### Location Resource
551 #### GET /fhir/Location
556 curl -X GET 'http://localhost:8300/apis/fhir/Location'
559 #### GET /fhir/Location/:uuid
564 curl -X GET 'http://localhost:8300/apis/fhir/Location/90f3d0e9-2a19-453b-84bd-1fa2b533f96c'
569 ### CareTeam Resource
571 #### GET /fhir/CareTeam
576 curl -X GET 'http://localhost:8300/apis/fhir/CareTeam'
579 #### GET /fhir/CareTeam/:uuid
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:
594 curl -X GET 'http://localhost:8300/apis/fhir/AllergyIntolerance?_revinclude=Provenance:target'
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.
615 curl -X POST -H 'Content-Type: application/json' 'http://localhost:8300/apis/portalfhir/auth' \
617 "grant_type":"password",
618 "username": "ServiceUser",
619 "password": "password",
628 "token_type": "Bearer",
629 "access_token": "eyJ0b2tlbiI6IjAwNmZ4TWpsNWhsZmNPelZicXBEdEZVUlNPQUY5KzdzR1Jjejc4WGZyeGFjUjY2QlhaaEs4eThkU3cxbTd5VXFBeTVyeEZpck9mVzBQNWc5dUlidERLZ0trUElCME5wRDVtTVk5bE9WaE5DTHF5RnRnT0Q0OHVuaHRvbXZ6OTEyNmZGUmVPUllSYVJORGoyZTkzTDA5OWZSb0ZRVGViTUtWUFd4ZW5cL1piSzhIWFpJZUxsV3VNcUdjQXR5dmlLQXRXNDAiLCJzaXRlX2lkIjoiZGVmYXVsdCIsImFwaSI6Im9lbXIifQ==",
630 "expires_in": "3600",
637 The Bearer token is required for each OpenEMR Patient Portal FHIR service request, and is conveyed using an Authorization header.
642 curl -X GET 'http://localhost:8300/apis/portalfhir/Patient' \
643 -H 'Authorization: Bearer eyJ0b2tlbiI6IjAwNmZ4TWpsNWhsZmNPelZicXBEdEZVUlNPQUY5KzdzR1Jjejc4WGZyeGFjUjY2QlhaaEs4eThkU3cxbTd5VXFBeTVyeEZpck9mVzBQNWc5dUlidERLZ0trUElCME5wRDVtTVk5bE9WaE5DTHF5RnRnT0Q0OHVuaHRvbXZ6OTEyNmZGUmVPUllSYVJORGoyZTkzTDA5OWZSb0ZRVGViTUtWUFd4ZW5cL1piSzhIWFpJZUxsV3VNcUdjQXR5dmlLQXRXNDAiLCJzaXRlX2lkIjoiZGVmYXVsdCIsImFwaSI6Im9lbXIifQ=='
648 ### Patient Portal Patient Resource
650 #### GET /portalfhir/Patient
655 curl -X GET 'http://localhost:8300/apis/portalfhir/Patient'