SMART-FHIR Capability & .well-known statement (#4090)
[openemr.git] / API_README.md
blob4af96f656ecd0636e9e13d044d1fe39fe33d4d23
1 # OpenEMR REST API Documentation
3 ## Overview
5 Easy-to-use JSON-based REST API for OpenEMR. All code is done in classes and separate from the view to help with codebase modernization efforts. FHIR is also supported, see FHIR API documentation [here](FHIR_README.md)
7 ## Implementation
9 REST API endpoints are defined in the [primary routes file](_rest_routes.inc.php). The routes file maps an external, addressable
10 endpoint to the OpenEMR controller which handles the request, and also handles the JSON data conversions.
12 ```php
13 "POST /api/patient" => function () {
14     RestConfig::authorization_check("patients", "demo");
15     $data = (array)(json_decode(file_get_contents("php://input")));
16     return (new PatientRestController())->post($data);
18 ```
20 At a high level, the request processing flow consists of the following steps:
22 ```
23 JSON Request -> Controller Component -> Validation -> Service Component -> Database
24 ```
26 The logical response flow begins with the database result:
28 ```
29 Database Result -> Service Component -> Controller Component -> RequestControllerHelper -> JSON Response
30 ```
32 The [RequestControllerHelper class](./src/RestControllers/RestControllerHelper.php) evaluates the Service Component's
33 result and maps it to a http response code and response payload. Existing APIs should be updated to utilize the
34 `handleProcessingResult` method as it supports the [Validator](./src/Validators/BaseValidator.php) components.
36 The [PatientRestController](./src/RestControllers/PatientRestController.php) may be used as a reference to see how APIs are
37 integrated with `RequestControllerHelper::handleProcessingResult` and the `Validator` components.
39 Finally, APIs which are integrated with the new `handleProcessingResult` method utilize a common response format.
41 ```json
43     "validationErrors": [],
44     "internalErrors": [],
45     "data": < data payload >
47 ```
49 -   `validationErrors` contain "client based" data validation errors
50 -   `internalErrors` contain server related errors
51 -   `data` is the response payload, represented as an object/`{}` for single results or an array/`[]` for multiple results
53 ### Sections
55 -   [Authorization](API_README.md#authorization)
56 -   [Standard API Endpoints](API_README.md#api-endpoints)
57     -   [Facility API](API_README.md#post-apifacility)
58     -   [Practitioner API](API_README.md#get-apipractitioner)
59     -   [Patient API](API_README.md#post-apipatient)
60     -   [Immunization API](API_README.md#get-apiimmunization)
61     -   [Allergy API](API_README.md#get-apiallergy)
62     -   [Procedure API](API_README.md#get-apiprocedure)
63     -   [Drug API](API_README.md#get-apidrug)
64     -   [Prescription API](API_README.md#get-apiprescription)
65     -   [Insurance API](API_README.md#get-apipatientpidinsurance)
66     -   [Appointment API](API_README.md#get-apiappointment)
67     -   [Document API](API_README.md#get-apipatientpiddocument)
68     -   [Message API](API_README.md#post-apipatientpidmessage)
69 -   [Portal API Endpoints](API_README.md#portal-Endpoints)
70     -   [Patient API](API_README.md#get-portalpatient)
71 -   [FHIR API Endpoints](FHIR_README.md#fhir-endpoints)
72     -   [FHIR Capability Statement](FHIR_README.md#capability-statement)
73     -   [FHIR Patient](FHIR_README.md#patient-resource)
74     -   [FHIR Encounter](FHIR_README.md#encounter-resource)
75     -   [FHIR Practitioner](FHIR_README.md#practitioner-resource)
76     -   [FHIR PractitionerRole](FHIR_README.md#practitionerrole-resource)
77     -   [FHIR Immunization](FHIR_README.md#immunization-resource)
78     -   [FHIR AllergyIntolerance](FHIR_README.md#allergyintolerance-resource)
79     -   [FHIR Organization](FHIR_README.md#organization-resource)
80     -   [FHIR Observation](FHIR_README.md#observation-resource)
81     -   [FHIR QuestionnaireResponse](FHIR_README.md#questionnaireresponse-resource)
82     -   [FHIR Condition](FHIR_README.md#condition-resource)
83     -   [FHIR Procedure](FHIR_README.md#procedure-resource)
84     -   [FHIR MedicationRequest](FHIR_README.md#medicationrequest-resource)
85     -   [FHIR Medication](FHIR_README.md#medication-resource)
86     -   [FHIR Location](FHIR_README.md#location-resource)
87     -   [FHIR CareTeam](FHIR_README.md#careTeam-resource)
88     -   [FHIR Provenance](FHIR_README.md#Provenance-resources)
89 -   [Patient Portal FHIR API Endpoints](FHIR_README.md#patient-portal-fhir-endpoints)
90     -   [Patient Portal FHIR Patient](FHIR_README.md#patient-portal-patient-resource)
91 -   [Dev notes](API_README.md#dev-notes)
92 -   [Todos](API_README.md#project-management)
94 ### Prerequisite
96 Enable the Standard API service (/api/ endpoints) in OpenEMR menu: Administration->Globals->Connectors->"Enable OpenEMR Standard REST API"
98 Enable the Patient Portal API service (/portal/ endpoints) in OpenEMR menu: Administration->Globals->Connectors->"Enable OpenEMR Patient Portal REST API"
100 ### Using API Internally
102 There are several ways to make API calls from an authorized session and maintain security:
104 -   See the script at tests/api/InternalApiTest.php for examples of internal API use cases.
106 ### Multisite Support
108 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/api/patient`. If you are using multisite and using a site called `alternate`, then the path would look like `apis/alternate/api/patient`.
110 ### Authorization
112 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.
114 #### Registration
116 Here is an example for registering a client. A client needs to be registered before applying for grant to obtain access/refresh tokens. Note: "post_logout_redirect_uris" is optional and only used if client wants a redirect to its own confirmation workflow.
118 ```sh
119 curl -X POST -k -H 'Content-Type: application/json' -i https://localhost:9300/oauth2/default/registration --data '{
120    "application_type": "private",
121    "redirect_uris":
122      ["https://client.example.org/callback"],
123    "post_logout_redirect_uris":
124      ["https://client.example.org/logout/callback"],
125    "client_name": "A Private App",
126    "token_endpoint_auth_method": "client_secret_post",
127    "contacts": ["me@example.org", "them@example.org"]
128   }'
131 Response:
133 ```json
135     "client_id": "LnjqojEEjFYe5j2Jp9m9UnmuxOnMg4VodEJj3yE8_OA",
136     "client_secret": "j21ecvLmFi9HPc_Hv0t7Ptmf1pVcZQLtHjIdU7U9tkS9WAjFJwVMav0G8ogTJ62q4BATovC7BQ19Qagc4x9BBg",
137     "registration_access_token": "uiDSXx2GNSvYy5n8eW50aGrJz0HjaGpUdrGf07Agv_Q",
138     "registration_client_uri": "https:\/\/localhost:9300\/oauth2\/default\/client\/6eUVG0-qK2dYiwfYdECKIw",
139     "client_id_issued_at": 1604767861,
140     "client_secret_expires_at": 0,
141     "contacts": ["me@example.org", "them@example.org"],
142     "application_type": "private",
143     "client_name": "A Private App",
144     "redirect_uris": ["https:\/\/client.example.org\/callback"],
145     "token_endpoint_auth_method": "client_secret_post"
149 #### Authorization Code Grant
151 This is the recommended standard mechanism to obtain access/refresh tokens. This is done by using an OAuth2 client with provider url of `oauth2/<site>`; an example full path would be `https://localhost:9300/oauth2/default`.
153 #### Refresh Token Grant
155 Example:
157 ```sh
158 curl -X POST -k -H 'Content-Type: application/x-www-form-urlencoded'
159 -i 'https://localhost:9300/oauth2/default/token'
160 --data 'grant_type=refresh_token
161 &client_id=LnjqojEEjFYe5j2Jp9m9UnmuxOnMg4VodEJj3yE8_OA
162 &scope=openid
163 &refresh_token=def5020089a766d16...'
166 Response:
168 ```json
170   "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJrYn...",
171   "token_type": "Bearer",
172   "expires_in": 3599,
173   "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJrYnl1RkRp...",
174   "refresh_token": "def5020017b484b0add020bf3491a8a537fa04eda12..."
178 #### Password Grant
180 Recommend not using this mechanism unless you know what you are doing. It is considered far less secure than the standard authorization code method. Because of security implications, it is not turned on by default. It can be turned on at Administration->Globals->Connectors->'Enable OAuth2 Password Grant (Not considered secure)'.
182 Example for `users` role:
183 ```sh
184 curl -X POST -k -H 'Content-Type: application/x-www-form-urlencoded'
185 -i 'https://localhost:9300/oauth2/default/token'
186 --data 'grant_type=password
187 &client_id=LnjqojEEjFYe5j2Jp9m9UnmuxOnMg4VodEJj3yE8_OA
188 &scope=openid
189 &user_role=users
190 &username=admin
191 &password=pass'
194 Example for `patient` role:
195 ```sh
196 curl -X POST -k -H 'Content-Type: application/x-www-form-urlencoded'
197 -i 'https://localhost:9300/oauth2/default/token'
198 --data 'grant_type=password
199 &client_id=LnjqojEEjFYe5j2Jp9m9UnmuxOnMg4VodEJj3yE8_OA
200 &scope=openid
201 &user_role=patient
202 &username=Phil1
203 &password=phil
204 &email=heya@invalid.email.com'
207 Response:
209 ```json
211   "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJrYn...",
212   "token_type": "Bearer",
213   "expires_in": 3599,
214   "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJrYnl1RkRp...",
215   "refresh_token": "def5020017b484b0add020bf3491a8a537fa04eda12..."
219 #### Logout
221 A grant (both Authorization Code and Password grants) can be logged out (ie. removed) by url of `oauth2/<site>/logout?id_token_hint=<id_token>`; an example full path would be `https://localhost:9300/oauth2/default/logout?id_token_hint=<id_token>`. Optional: `post_logout_redirect_uri` and `state` parameters can also be sent; note that `post_logout_redirect_uris` also needs to be set during registration for it to work.
223 #### More Details
225 The forum thread that detailed development of Authorization and where questions and issues are addressed is here: https://community.open-emr.org/t/v6-authorization-and-api-changes-afoot/15450
227 More specific development api topics are discussed and described on the above forum thread (such as introspection).
229 ### /api/ Endpoints
231 OpenEMR standard endpoints Use `http://localhost:8300/apis/default/api as base URI.`
233 Note that the `default` component can be changed to the name of the site when using OpenEMR's multisite feature.
235 _Example:_ `http://localhost:8300/apis/default/api/patient` returns a resource of all Patients.
237 The Bearer token is required for each OpenEMR API request, and is conveyed using an Authorization header. Note that the Bearer token is the access_token that is obtained in the above [Authorization](API_README.md#authorization) section.
239 Request:
241 ```sh
242 curl -X GET 'http://localhost:8300/apis/default/api/patient/1/medical_problem' \
243   -H 'Authorization: Bearer eyJ0b2tlbiI6IjAwNmZ4TWpsNWhsZmNPelZicXBEdEZVUlNPQUY5KzdzR1Jjejc4WGZyeGFjUjY2QlhaaEs4eThkU3cxbTd5VXFBeTVyeEZpck9mVzBQNWc5dUlidERLZ0trUElCME5wRDVtTVk5bE9WaE5DTHF5RnRnT0Q0OHVuaHRvbXZ6OTEyNmZGUmVPUllSYVJORGoyZTkzTDA5OWZSb0ZRVGViTUtWUFd4ZW5cL1piSzhIWFpJZUxsV3VNcUdjQXR5dmlLQXRXNDAiLCJzaXRlX2lkIjoiZGVmYXVsdCIsImFwaSI6Im9lbXIifQ=='
246 #### POST /api/facility
248 Request:
250 ```sh
251 curl -X POST 'http://localhost:8300/apis/default/api/facility' -d \
253     "name": "Aquaria",
254     "phone": "808-606-3030",
255     "fax": "808-606-3031",
256     "street": "1337 Bit Shifter Ln",
257     "city": "San Lorenzo",
258     "state": "ZZ",
259     "postal_code": "54321",
260     "email": "foo@bar.com",
261     "service_location": "1",
262     "billing_location": "1",
263     "color": "#FF69B4"
267 #### PUT /api/facility/:fid
269 Request:
271 ```sh
272 curl -X PUT 'http://localhost:8300/apis/default/api/facility/1' -d \
274     "name": "Aquaria",
275     "phone": "808-606-3030",
276     "fax": "808-606-3031",
277     "street": "1337 Bit Shifter Ln",
278     "city": "San Lorenzo",
279     "state": "AZ",
280     "postal_code": "54321",
281     "email": "foo@bar.com",
282     "service_location": "1",
283     "billing_location": "1",
284     "color": "#FF69B4"
288 #### GET /api/facility
290 Request:
292 ```sh
293 curl -X GET 'http://localhost:8300/apis/default/api/facility'
296 #### GET /api/facility/:fid
298 Request:
300 ```sh
301 curl -X GET 'http://localhost:8300/apis/default/api/facility/1'
304 #### GET /api/practitioner
306 Request:
308 ```sh
309 curl -X GET 'http://localhost:8300/apis/default/api/practitioner'
312 #### GET /api/practitioner/:uuid
314 Request:
316 ```sh
317 curl -X GET 'http://localhost:8300/apis/default/api/practitioner/90cde167-7b9b-4ed1-bd55-533925cb2605'
320 #### POST /api/practitioner
322 Request:
324 ```sh
325 curl -X POST 'http://localhost:8300/apis/default/api/practitioner' -d \
327     "title": "Mrs.",
328     "fname": "Eduardo",
329     "mname": "Kathy",
330     "lname": "Perez",
331     "federaltaxid": "",
332     "federaldrugid": "",
333     "upin": "",
334     "facility_id": "3",
335     "facility": "Your Clinic Name Here",
336     "npi": "0123456789",
337     "email": "info@pennfirm.com",
338     "specialty": "",
339     "billname": null,
340     "url": null,
341     "assistant": null,
342     "organization": null,
343     "valedictory": null,
344     "street": "789 Third Avenue",
345     "streetb": "123 Cannaut Street",
346     "city": "San Diego",
347     "state": "CA",
348     "zip": "90210",
349     "phone": "(619) 555-9827",
350     "fax": null,
351     "phonew1": "(619) 555-7822",
352     "phonecell": "(619) 555-7821",
353     "notes": null,
354     "state_license_number": "123456"
358 Response:
360 ```json
362     "validationErrors": [],
363     "internalErrors": [],
364     "data": {
365         "id": 7,
366         "uuid": "90d453fb-0248-4c0d-9575-d99d02b169f5"
367     }
371 #### PUT /api/practitioner/:uuid
373 Request:
375 ```sh
376 curl -X PUT 'http://localhost:8300/apis/default/api/patient/90a8923c-0b1c-4d0a-9981-994b143381a7' -d \
378     "title": "Mr",
379     "fname": "Baz",
380     "mname": "",
381     "lname": "Bop",
382     "street": "456 Tree Lane",
383     "zip": "08642",
384     "city": "FooTown",
385     "state": "FL",
386     "phone": "123-456-7890"
390 Response:
392 ```json
394     "validationErrors": [],
395     "internalErrors": [],
396     "data": {
397         "id": "7",
398         "uuid": "90d453fb-0248-4c0d-9575-d99d02b169f5",
399         "title": "Mr",
400         "fname": "Baz",
401         "lname": "Bop",
402         "mname": "",
403         "federaltaxid": "",
404         "federaldrugid": "",
405         "upin": "",
406         "facility_id": "3",
407         "facility": "Your Clinic Name Here",
408         "npi": "0123456789",
409         "email": "info@pennfirm.com",
410         "active": "1",
411         "specialty": "",
412         "billname": "",
413         "url": "",
414         "assistant": "",
415         "organization": "",
416         "valedictory": "",
417         "street": "456 Tree Lane",
418         "streetb": "123 Cannaut Street",
419         "city": "FooTown",
420         "state": "FL",
421         "zip": "08642",
422         "phone": "123-456-7890",
423         "fax": "",
424         "phonew1": "(619) 555-7822",
425         "phonecell": "(619) 555-7821",
426         "notes": "",
427         "state_license_number": "123456",
428         "abook_title": null,
429         "physician_title": null,
430         "physician_code": null
431     }
435 #### POST /api/patient
437 Request:
439 ```sh
440 curl -X POST 'http://localhost:8300/apis/default/api/patient' -d \
442     "title": "Mr",
443     "fname": "Foo",
444     "mname": "",
445     "lname": "Bar",
446     "street": "456 Tree Lane",
447     "postal_code": "08642",
448     "city": "FooTown",
449     "state": "FL",
450     "country_code": "US",
451     "phone_contact": "123-456-7890",
452     "DOB": "1992-02-02",
453     "sex": "Male",
454     "race": "",
455     "ethnicity": ""
459 Response:
461 ```json
463     "validationErrors": [],
464     "internalErrors": [],
465     "data": {
466         "pid": 1
467     }
471 #### PUT /api/patient/:puuid
473 Request:
475 ```sh
476 curl -X PUT 'http://localhost:8300/apis/default/api/patient/90a8923c-0b1c-4d0a-9981-994b143381a7' -d \
478     "title": "Mr",
479     "fname": "Baz",
480     "mname": "",
481     "lname": "Bop",
482     "street": "456 Tree Lane",
483     "postal_code": "08642",
484     "city": "FooTown",
485     "state": "FL",
486     "country_code": "US",
487     "phone_contact": "123-456-7890",
488     "DOB": "1992-02-03",
489     "sex": "Male",
490     "race": "",
491     "ethnicity": ""
495 Response:
497 ```json
499     "validationErrors": [],
500     "internalErrors": [],
501     "data": {
502         "id": "193",
503         "pid": "1",
504         "pubpid": "",
505         "title": "Mr",
506         "fname": "Baz",
507         "mname": "",
508         "lname": "Bop",
509         "ss": "",
510         "street": "456 Tree Lane",
511         "postal_code": "08642",
512         "city": "FooTown",
513         "state": "FL",
514         "county": "",
515         "country_code": "US",
516         "drivers_license": "",
517         "contact_relationship": "",
518         "phone_contact": "123-456-7890",
519         "phone_home": "",
520         "phone_biz": "",
521         "phone_cell": "",
522         "email": "",
523         "DOB": "1992-02-03",
524         "sex": "Male",
525         "race": "",
526         "ethnicity": "",
527         "status": ""
528     }
532 #### GET /api/patient
534 Request:
536 ```sh
537 curl -X GET 'http://localhost:8300/apis/default/api/patient'
540 Response:
542 ```json
544     "validationErrors": [],
545     "internalErrors": [],
546     "data": [{ patientRecord }, { patientRecord }, etc]
550 Request:
552 ```sh
553 curl -X GET 'http://localhost:8300/apis/default/api/patient&fname=...&lname=...&dob=...'
556 Response:
558 ```json
560     "validationErrors": [],
561     "internalErrors": [],
562     "data": [{ patientRecord }, { patientRecord }, etc]
566 #### GET /api/patient/:puuid
568 Request:
570 ```sh
571 curl -X GET 'http://localhost:8300/apis/default/api/patient/90a8923c-0b1c-4d0a-9981-994b143381a7'
574 Response:
576 ```json
578     "validationErrors": [],
579     "internalErrors": [],
580     "data": {
581         "id": "193",
582         "pid": "1",
583         "pubpid": "",
584         "title": "Mr",
585         "fname": "Baz",
586         "mname": "",
587         "lname": "Bop",
588         "ss": "",
589         "street": "456 Tree Lane",
590         "postal_code": "08642",
591         "city": "FooTown",
592         "state": "FL",
593         "county": "",
594         "country_code": "US",
595         "drivers_license": "",
596         "contact_relationship": "",
597         "phone_contact": "123-456-7890",
598         "phone_home": "",
599         "phone_biz": "",
600         "phone_cell": "",
601         "email": "",
602         "DOB": "1992-02-03",
603         "sex": "Male",
604         "race": "",
605         "ethnicity": "",
606         "status": ""
607     }
611 #### GET /api/immunization
613 Request:
615 ```sh
616 curl -X GET 'http://localhost:8300/apis/default/api/immunization'
619 #### GET /api/immunization/:uuid
621 Request:
623 ```sh
624 curl -X GET 'http://localhost:8300/apis/default/api/immunization/90cde167-7b9b-4ed1-bd55-533925cb2605'
627 #### POST /api/patient/:pid/encounter
629 Request:
631 ```sh
632 curl -X POST 'http://localhost:8300/apis/default/api/patient/90a8923c-0b1c-4d0a-9981-994b143381a7/encounter' -d \
634     "date":"2020-11-10",
635     "onset_date": "",
636     "reason": "Pregnancy Test",
637     "facility": "Owerri General Hospital",
638     "pc_catid": "5",
639     "facility_id": "3",
640     "billing_facility": "3",
641     "sensitivity": "normal",
642     "referral_source": "",
643     "pos_code": "0",
644     "external_id": "",
645     "provider_id": "1",
646     "class_code" : "AMB"
650 Response:
652 ```json
654     "validationErrors": [],
655     "internalErrors": [],
656     "data": {
657         "encounter": 1,
658         "uuid": "90c196f2-51cc-4655-8858-3a80aebff3ef"
659     }
663 #### PUT /api/patient/:pid/encounter/:eid
665 Request:
667 ```sh
668 curl -X POST 'http://localhost:8300/apis/default/api/patient/90a8923c-0b1c-4d0a-9981-994b143381a7/encounter/90c196f2-51cc-4655-8858-3a80aebff3ef' -d \
670     "date":"2019-09-14",
671     "onset_date": "2019-04-20 00:00:00",
672     "reason": "Pregnancy Test",
673     "pc_catid": "5",
674     "facility_id": "3",
675     "billing_facility": "3",
676     "sensitivity": "normal",
677     "referral_source": "",
678     "pos_code": "0"
682 Response:
684 ```json
686     "validationErrors": [],
687     "internalErrors": [],
688     "data": {
689         "id": "1",
690         "uuid": "90c196f2-51cc-4655-8858-3a80aebff3ef",
691         "date": "2019-09-14 00:00:00",
692         "reason": "Pregnancy Test",
693         "facility": "Owerri General Hospital",
694         "facility_id": "3",
695         "pid": "1",
696         "onset_date": "2019-04-20 00:00:00",
697         "sensitivity": "normal",
698         "billing_note": null,
699         "pc_catid": "5",
700         "last_level_billed": "0",
701         "last_level_closed": "0",
702         "last_stmt_date": null,
703         "stmt_count": "0",
704         "provider_id": "1",
705         "supervisor_id": "0",
706         "invoice_refno": "",
707         "referral_source": "",
708         "billing_facility": "3",
709         "external_id": "",
710         "pos_code": "0",
711         "class_code": "AMB",
712         "class_title": "ambulatory",
713         "pc_catname": "Office Visit",
714         "billing_facility_name": "Owerri General Hospital"
715     }
719 #### GET /api/patient/:pid/encounter
721 Request:
723 ```sh
724 curl -X GET 'http://localhost:8300/apis/default/api/patient/90a8923c-0b1c-4d0a-9981-994b143381a7/encounter'
727 Response:
729 ```json
731     "validationErrors": [],
732     "internalErrors": [],
733     "data": [{ encounterRecord }, { encounterRecord }, etc]
737 #### GET /api/patient/:pid/encounter/:eid
739 Request:
741 ```sh
742 curl -X GET 'http://localhost:8300/apis/default/api/patient/90a8923c-0b1c-4d0a-9981-994b143381a7/encounter/90c196f2-51cc-4655-8858-3a80aebff3ef'
745 Response:
747 ```json
749     "validationErrors": [],
750     "internalErrors": [],
751     "data": {
752         "id": "1",
753         "uuid": "90c196f2-51cc-4655-8858-3a80aebff3ef",
754         "date": "2019-09-14 00:00:00",
755         "reason": "Pregnancy Test",
756         "facility": "Owerri General Hospital",
757         "facility_id": "3",
758         "pid": "1",
759         "onset_date": "2019-04-20 00:00:00",
760         "sensitivity": "normal",
761         "billing_note": null,
762         "pc_catid": "5",
763         "last_level_billed": "0",
764         "last_level_closed": "0",
765         "last_stmt_date": null,
766         "stmt_count": "0",
767         "provider_id": "1",
768         "supervisor_id": "0",
769         "invoice_refno": "",
770         "referral_source": "",
771         "billing_facility": "3",
772         "external_id": "",
773         "pos_code": "0",
774         "class_code": "AMB",
775         "class_title": "ambulatory",
776         "pc_catname": "Office Visit",
777         "billing_facility_name": "Owerri General Hospital"
778     }
782 #### POST /api/patient/:pid/encounter/:eid/vital
784 Request:
786 ```sh
787 curl -X POST 'http://localhost:8300/apis/default/api/patient/1/encounter/1/vital' -d \
789     "bps": "130",
790     "bpd": "80",
791     "weight": "220",
792     "height": "70",
793     "temperature": "98",
794     "temp_method": "Oral",
795     "pulse": "60",
796     "respiration": "20",
797     "note": "...",
798     "waist_circ": "37",
799     "head_circ": "22.2",
800     "oxygen_saturation": "80"
804 #### PUT /api/patient/:pid/encounter/:eid/vital/:vid
806 Request:
808 ```sh
809 curl -X PUT 'http://localhost:8300/apis/default/api/patient/1/encounter/1/vital/1' -d \
811     "bps": "140",
812     "bpd": "80",
813     "weight": "220",
814     "height": "70",
815     "temperature": "98",
816     "temp_method": "Oral",
817     "pulse": "60",
818     "respiration": "20",
819     "note": "...",
820     "waist_circ": "37",
821     "head_circ": "22.2",
822     "oxygen_saturation": "80"
826 #### GET /api/patient/:pid/encounter/:eid/vital
828 Request:
830 ```sh
831 curl -X GET 'http://localhost:8300/apis/default/api/patient/1/encounter/1/vital'
834 #### GET /api/patient/:pid/encounter/:eid/vital/:vid
836 Request:
838 ```sh
839 curl -X GET 'http://localhost:8300/apis/default/api/patient/1/encounter/1/vital/1'
842 #### POST /api/patient/:pid/encounter/:eid/soap_note
844 Request:
846 ```sh
847 curl -X POST 'http://localhost:8300/apis/default/api/patient/1/encounter/1/soap_note' -d \
849     "subjective": "...",
850     "objective": "...",
851     "assessment": "...",
852     "plan": "..."
856 #### PUT /api/patient/:pid/encounter/:eid/soap_note/:sid
858 Request:
860 ```sh
861 curl -X PUT 'http://localhost:8300/apis/default/api/patient/1/encounter/1/soap_note/1' -d \
863     "subjective": "...",
864     "objective": "...",
865     "assessment": "...",
866     "plan": "..."
870 #### GET /api/patient/:pid/encounter/:eid/soap_note
872 Request:
874 ```sh
875 curl -X GET 'http://localhost:8300/apis/default/api/patient/1/encounter/1/soap_note'
878 #### GET /api/patient/:pid/encounter/:eid/soap_note/:sid
880 Request:
882 ```sh
883 curl -X GET 'http://localhost:8300/apis/default/api/patient/1/encounter/1/soap_note/1'
886 #### GET /api/medical_problem
888 Request:
890 ```sh
891 curl -X GET 'http://localhost:8300/apis/default/api/medical_problem'
894 #### GET /api/medical_problem/:muuid
896 Request:
898 ```sh
899 curl -X GET 'http://localhost:8300/apis/default/api/medical_problem/9109890a-6756-44c1-a82d-bdfac91c7424'
902 #### GET /api/patient/:puuid/medical_problem
904 Request:
906 ```sh
907 curl -X GET 'http://localhost:8300/apis/default/api/patient/9101a093-da04-457f-a6a1-46ce93f0d629/medical_problem'
910 #### GET /api/patient/:puuid/medical_problem/:muuid
912 Request:
914 ```sh
915 curl -X GET 'http://localhost:8300/apis/default/api/patient/9101a093-da04-457f-a6a1-46ce93f0d629/medical_problem/91208832-47ab-4f65-ba44-08f57d4c028e'
918 #### POST /api/patient/:puuid/medical_problem
920 Request:
922 ```sh
923 curl -X POST 'http://localhost:8300/apis/default/api/patient/9101a093-da04-457f-a6a1-46ce93f0d629/medical_problem' -d \
925     "title": "Dermatochalasis",
926     "begdate": "2010-04-13",
927     "enddate": null,
928     "diagnosis": "ICD10:H02.839"
932 #### PUT /api/patient/:puuid/medical_problem/:muuid
934 Request:
936 ```sh
937 curl -X PUT 'http://localhost:8300/apis/default/api/patient/9101a093-da04-457f-a6a1-46ce93f0d629/medical_problem/91208832-47ab-4f65-ba44-08f57d4c028e' -d \
939     "title": "Dermatochalasis",
940     "begdate": "2010-04-13",
941     "enddate": "2018-03-12",
942     "diagnosis": "ICD10:H02.839"
946 #### DELETE /api/patient/:puuid/medical_problem/:muuid
948 Request:
950 ```sh
951 curl -X DELETE 'http://localhost:8300/apis/default/api/patient/9101a093-da04-457f-a6a1-46ce93f0d629/medical_problem/91208832-47ab-4f65-ba44-08f57d4c028e'
954 #### GET /api/allergy
956 Request:
958 ```sh
959 curl -X GET 'http://localhost:8300/apis/default/api/allergy'
962 #### GET /api/allergy/:auuid
964 Request:
966 ```sh
967 curl -X GET 'http://localhost:8300/apis/default/api/allergy/90c196f2-51cc-4655-8858-3a80aebff3ef'
970 #### GET /api/patient/:puuid/allergy
972 Request:
974 ```sh
975 curl -X GET 'http://localhost:8300/apis/default/api/patient/90c196f2-51cc-4655-8858-3a80aebff3ef/allergy'
978 #### GET /api/patient/:puuid/allergy/:auuid
980 Request:
982 ```sh
983 curl -X GET 'http://localhost:8300/apis/default/api/patient/90c196f2-51cc-4655-8858-3a80aebff3ef/allergy/90c196f2-51cc-4655-8858-3a80aebff3ef'
986 #### POST /api/patient/:puuid/allergy
988 Request:
990 ```sh
991 curl -X POST 'http://localhost:8300/apis/default/api/patient/90c196f2-51cc-4655-8858-3a80aebff3ef/allergy' -d \
993     "title": "Iodine",
994     "begdate": "2010-10-13",
995     "enddate": null
999 #### PUT /api/patient/:puuid/allergy/:auuid
1001 Request:
1003 ```sh
1004 curl -X PUT 'http://localhost:8300/apis/default/api/patient/90c196f2-51cc-4655-8858-3a80aebff3ef/allergy/90c196f2-51cc-4655-8858-3a80aebff3ef' -d \
1006     "title": "Iodine",
1007     "begdate": "2012-10-13",
1008     "enddate": null
1012 #### DELETE /api/patient/:puuid/allergy/:auuid
1014 Request:
1016 ```sh
1017 curl -X DELETE 'http://localhost:8300/apis/default/api/patient/90c196f2-51cc-4655-8858-3a80aebff3ef/allergy/90c196f2-51cc-4655-8858-3a80aebff3ef'
1020 #### GET /api/procedure
1022 Request:
1024 ```sh
1025 curl -X GET 'http://localhost:8300/apis/default/api/procedure'
1028 #### GET /api/procedure/:uuid
1030 Request:
1032 ```sh
1033 curl -X GET 'http://localhost:8300/apis/default/api/procedure/90c196f2-51cc-4655-8858-3a80aebff3ef'
1036 #### GET /api/drug
1038 Request:
1040 ```sh
1041 curl -X GET 'http://localhost:8300/apis/default/api/drug'
1044 #### GET /api/drug/:uuid
1046 Request:
1048 ```sh
1049 curl -X GET 'http://localhost:8300/apis/default/api/drug/90c196f2-51cc-4655-8858-3a80aebff3ef'
1052 #### GET /api/prescription
1054 Request:
1056 ```sh
1057 curl -X GET 'http://localhost:8300/apis/default/api/prescription'
1060 #### GET /api/prescription/:uuid
1062 Request:
1064 ```sh
1065 curl -X GET 'http://localhost:8300/apis/default/api/prescription/9128a1ec-95be-4649-8a66-d3686b7ab0ca'
1068 #### POST /api/patient/:pid/medication
1070 Request:
1072 ```sh
1073 curl -X POST 'http://localhost:8300/apis/default/api/patient/1/medication' -d \
1075     "title": "Norvasc",
1076     "begdate": "2013-10-13",
1077     "enddate": null
1081 #### PUT /api/patient/:pid/medication/:mid
1083 Request:
1085 ```sh
1086 curl -X PUT 'http://localhost:8300/apis/default/api/patient/1/medication/1' -d \
1088     "title": "Norvasc",
1089     "begdate": "2013-04-13",
1090     "enddate": null
1094 #### GET /api/patient/:pid/medication
1096 Request:
1098 ```sh
1099 curl -X GET 'http://localhost:8300/apis/default/api/patient/1/medication'
1102 #### GET /api/patient/:pid/medication/:mid
1104 Request:
1106 ```sh
1107 curl -X GET 'http://localhost:8300/apis/default/api/patient/1/medication/1'
1110 #### DELETE /api/patient/:pid/medication/:mid
1112 Request:
1114 ```sh
1115 curl -X DELETE 'http://localhost:8300/apis/default/api/patient/1/medication/1'
1118 #### POST /api/patient/:pid/surgery
1120 Request:
1122 ```sh
1123 curl -X POST 'http://localhost:8300/apis/default/api/patient/1/surgery' -d \
1125     "title": "Blepharoplasty",
1126     "begdate": "2013-10-13",
1127     "enddate": null,
1128     "diagnosis": "CPT4:15823-50"
1132 #### PUT /api/patient/:pid/surgery/:sid
1134 Request:
1136 ```sh
1137 curl -X PUT 'http://localhost:8300/apis/default/api/patient/1/surgery/1' -d \
1139     "title": "Blepharoplasty",
1140     "begdate": "2013-10-14",
1141     "enddate": null,
1142     "diagnosis": "CPT4:15823-50"
1146 #### GET /api/patient/:pid/surgery
1148 Request:
1150 ```sh
1151 curl -X GET 'http://localhost:8300/apis/default/api/patient/1/surgery'
1154 #### GET /api/patient/:pid/surgery/:sid
1156 Request:
1158 ```sh
1159 curl -X GET 'http://localhost:8300/apis/default/api/patient/1/surgery/1'
1162 #### DELETE /api/patient/:pid/surgery/:sid
1164 Request:
1166 ```sh
1167 curl -X DELETE 'http://localhost:8300/apis/default/api/patient/1/surgery/1'
1170 #### POST /api/patient/:pid/dental_issue
1172 Request:
1174 ```sh
1175 curl -X POST 'http://localhost:8300/apis/default/api/patient/1/dental_issue' -d \
1177     "title": "Halitosis",
1178     "begdate": "2015-03-17",
1179     "enddate": null
1183 #### PUT /api/patient/:pid/dental_issue/:did
1185 Request:
1187 ```sh
1188 curl -X PUT 'http://localhost:8300/apis/default/api/patient/1/dental_issue/1' -d \
1190     "title": "Halitosis",
1191     "begdate": "2015-03-17",
1192     "enddate": "2018-03-20"
1196 #### GET /api/patient/:pid/dental_issue
1198 Request:
1200 ```sh
1201 curl -X GET 'http://localhost:8300/apis/default/api/patient/1/dental_issue'
1204 #### GET /api/patient/:pid/dental_issue/:did
1206 Request:
1208 ```sh
1209 curl -X GET 'http://localhost:8300/apis/default/api/patient/1/dental_issue/1'
1212 #### DELETE /api/patient/:pid/dental_issue/:did
1214 Request:
1216 ```sh
1217 curl -X DELETE 'http://localhost:8300/apis/default/api/patient/1/dental_issue/1'
1220 #### GET /api/patient/:pid/insurance
1222 Request:
1224 ```sh
1225 curl -X GET 'http://localhost:8300/apis/default/api/patient/1/insurance'
1228 #### GET /api/patient/:pid/insurance/:type
1230 Request:
1232 ```sh
1233 curl -X GET 'http://localhost:8300/apis/default/api/patient/1/insurance/secondary'
1236 #### POST /api/patient/:pid/insurance/:type
1238 Request:
1240 ```sh
1241 curl -X POST 'http://localhost:8300/apis/default/api/patient/10/insurance/primary' -d \
1243     "type": "primary",
1244     "provider": "33",
1245     "plan_name": "Some Plan",
1246     "policy_number": "12345",
1247     "group_number": "252412",
1248     "subscriber_lname": "Tester",
1249     "subscriber_mname": "Xi",
1250     "subscriber_fname": "Foo",
1251     "subscriber_relationship": "other",
1252     "subscriber_ss": "234231234",
1253     "subscriber_DOB": "2018-10-03",
1254     "subscriber_street": "183 Cool St",
1255     "subscriber_postal_code": "23418",
1256     "subscriber_city": "Cooltown",
1257     "subscriber_state": "AZ",
1258     "subscriber_country": "USA",
1259     "subscriber_phone": "234-598-2123",
1260     "subscriber_employer": "Some Employer",
1261     "subscriber_employer_street": "123 Heather Lane",
1262     "subscriber_employer_postal_code": "23415",
1263     "subscriber_employer_state": "AZ",
1264     "subscriber_employer_country": "USA",
1265     "subscriber_employer_city": "Cooltown",
1266     "copay": "35",
1267     "date": "2018-10-15",
1268     "subscriber_sex": "Female",
1269     "accept_assignment": "TRUE",
1270     "policy_type": "a"
1274 Notes:
1276 -   `provider` is the insurance company id
1277 -   `state` can be found by querying `resource=/api/list/state`
1278 -   `country` can be found by querying `resource=/api/list/country`
1280 #### PUT /api/patient/:pid/insurance/:type
1282 Request:
1284 ```sh
1285 curl -X PUT 'http://localhost:8300/apis/default/api/patient/10/insurance/primary' -d \
1287     "type": "primary",
1288     "provider": "33",
1289     "plan_name": "Some Plan",
1290     "policy_number": "12345",
1291     "group_number": "252412",
1292     "subscriber_lname": "Tester",
1293     "subscriber_mname": "Xi",
1294     "subscriber_fname": "Foo",
1295     "subscriber_relationship": "other",
1296     "subscriber_ss": "234231234",
1297     "subscriber_DOB": "2018-10-03",
1298     "subscriber_street": "183 Cool St",
1299     "subscriber_postal_code": "23418",
1300     "subscriber_city": "Cooltown",
1301     "subscriber_state": "AZ",
1302     "subscriber_country": "USA",
1303     "subscriber_phone": "234-598-2123",
1304     "subscriber_employer": "Some Employer",
1305     "subscriber_employer_street": "123 Heather Lane",
1306     "subscriber_employer_postal_code": "23415",
1307     "subscriber_employer_state": "AZ",
1308     "subscriber_employer_country": "USA",
1309     "subscriber_employer_city": "Cooltown",
1310     "copay": "35",
1311     "date": "2018-10-15",
1312     "subscriber_sex": "Female",
1313     "accept_assignment": "TRUE",
1314     "policy_type": "a"
1318 Notes:
1320 -   `provider` is the insurance company id
1321 -   `state` can be found by querying `resource=/api/list/state`
1322 -   `country` can be found by querying `resource=/api/list/country`
1324 #### GET /api/list/:list_name
1326 Request:
1328 ```sh
1329 curl -X GET 'http://localhost:8300/apis/default/api/list/medical_problem_issue_list'
1332 #### GET /api/version
1334 Request:
1336 ```sh
1337 curl -X GET 'http://localhost:8300/apis/default/api/version'
1340 #### GET /api/product
1342 Request:
1344 ```sh
1345 curl -X GET 'http://localhost:8300/apis/default/api/product'
1348 #### GET /api/insurance_company
1350 Request:
1352 ```sh
1353 curl -X GET 'http://localhost:8300/apis/default/api/insurance_company'
1356 #### GET /api/insurance_type
1358 Request:
1360 ```sh
1361 curl -X GET 'http://localhost:8300/apis/default/api/insurance_type'
1364 #### POST /api/insurance_company
1366 Request:
1368 ```sh
1369 curl -X POST 'http://localhost:8300/apis/default/api/insurance_company' -d \
1371     "name": "Cool Insurance Company",
1372     "attn": null,
1373     "cms_id": null,
1374     "ins_type_code": "2",
1375     "x12_receiver_id": null,
1376     "x12_default_partner_id": null,
1377     "alt_cms_id": "",
1378     "line1": "123 Cool Lane",
1379     "line2": "Suite 123",
1380     "city": "Cooltown",
1381     "state": "CA",
1382     "zip": "12245",
1383     "country": "USA"
1387 Notes: `ins_type_code` can be found by inspecting the above route (/api/insurance_type).
1389 #### PUT /api/insurance_company/:iid
1391 Request:
1393 ```sh
1394 curl -X PUT 'http://localhost:8300/apis/default/api/insurance_company/1' -d \
1396     "name": "Super Insurance Company",
1397     "attn": null,
1398     "cms_id": null,
1399     "ins_type_code": "2",
1400     "x12_receiver_id": null,
1401     "x12_default_partner_id": null,
1402     "alt_cms_id": "",
1403     "line1": "123 Cool Lane",
1404     "line2": "Suite 123",
1405     "city": "Cooltown",
1406     "state": "CA",
1407     "zip": "12245",
1408     "country": "USA"
1412 Notes: `ins_type_code` can be found by inspecting the above route (/api/insurance_type).
1414 #### GET /api/appointment
1416 Request:
1418 ```sh
1419 curl -X GET 'http://localhost:8300/apis/default/api/appointment'
1422 #### GET /api/appointment/:eid
1424 Request:
1426 ```sh
1427 curl -X GET 'http://localhost:8300/apis/default/api/appointment/1'
1430 #### GET /api/patient/:pid/appointment
1432 Request:
1434 ```sh
1435 curl -X GET 'http://localhost:8300/apis/default/api/patient/1/appointment'
1438 #### GET /api/patient/:pid/appointment/:eid
1440 Request:
1442 ```sh
1443 curl -X GET 'http://localhost:8300/apis/default/api/patient/1/appointment/1'
1446 #### POST /api/patient/:pid/appointment
1448 Request:
1450 ```sh
1451 curl -X POST 'http://localhost:8300/apis/default/api/patient/1/appointment' -d \
1453     "pc_eid":"1",
1454     "pc_catid": "5",
1455     "pc_title": "Office Visit",
1456     "pc_duration": "900",
1457     "pc_hometext": "Test",
1458     "pc_apptstatus": "-",
1459     "pc_eventDate": "2018-10-19",
1460     "pc_startTime": "09:00",
1461     "pc_facility": "9",
1462     "pc_billing_location": "10"
1466 #### DELETE /api/patient/:pid/appointment/:eid
1468 Request:
1470 ```sh
1471 curl -X DELETE 'http://localhost:8300/apis/default/api/patient/1/appointment/1' -d \
1474 #### GET /api/patient/:pid/document
1476 Request:
1478 ```sh
1479 curl -X GET 'http://localhost:8300/apis/default/api/patient/1/document&path=/eye_module/imaging-eye/drawings-eye'
1482 Note: The `path` query string represents the OpenEMR documents paths with two exceptions:
1484 -   Spaces are represented with `_`
1485 -   All characters are lowercase
1487 #### POST /api/patient/:pid/document
1489 Request:
1491 ```sh
1492 curl -X POST 'http://localhost:8300/apis/default/api/patient/1/document&path=/eye_module/imaging-eye/drawings-eye' \
1493  -F document=@/home/someone/Desktop/drawing.jpg
1496 Note: The `path` query string represents the OpenEMR documents paths with two exceptions:
1498 -   Spaces are represented with `_`
1499 -   All characters are lowercase
1501 #### GET /api/patient/:pid/document/:did
1503 Request:
1505 ```sh
1506 curl -X GET 'http://localhost:8300/apis/default/api/patient/1/document/1'
1509 #### POST /api/patient/:pid/message
1511 Request:
1513 ```sh
1514 curl -X POST 'http://localhost:8300/apis/default/api/patient/1/message' -d \
1516     "body": "Test 123",
1517     "groupname": "Default",
1518     "from": "admin",
1519     "to": "Matthew",
1520     "title": "Other",
1521     "message_status": "New"
1525 Notes:
1527 -   For `title`, use `resource=/api/list/note_type`
1528 -   For `message_type`, use `resource=/api/list/message_status`
1530 #### PUT /api/patient/:pid/message/:mid
1532 Request:
1534 ```sh
1535 curl -X PUT 'http://localhost:8300/apis/default/api/patient/1/message/1' -d \
1537     "body": "Test 456",
1538     "groupname": "Default",
1539     "from": "Matthew",
1540     "to": "admin",
1541     "title": "Other",
1542     "message_status": "New"
1546 Notes:
1548 -   For `title`, use `resource=/api/list/note_type`
1549 -   For `message_type`, use `resource=/api/list/message_status`
1551 #### DELETE /api/patient/:pid/message/:mid
1553 Request:
1555 ```sh
1556 curl -X DELETE 'http://localhost:8300/apis/default/api/patient/1/message/1'
1559 ### /portal/ Endpoints
1561 OpenEMR patient portal endpoints Use `http://localhost:8300/apis/default/portal as base URI.`
1563 Note that the `default` component can be changed to the name of the site when using OpenEMR's multisite feature.
1565 _Example:_ `http://localhost:8300/apis/default/portal/patient` returns a resource of the patient.
1567 The Bearer token is required for each OpenEMR API request, and is conveyed using an Authorization header. Note that the Bearer token is the access_token that is obtained in the above [Authorization](API_README.md#authorization) section.
1569 Request:
1571 ```sh
1572 curl -X GET 'http://localhost:8300/apis/default/portal/patient' \
1573   -H 'Authorization: Bearer eyJ0b2tlbiI6IjAwNmZ4TWpsNWhsZmNPelZicXBEdEZVUlNPQUY5KzdzR1Jjejc4WGZyeGFjUjY2QlhaaEs4eThkU3cxbTd5VXFBeTVyeEZpck9mVzBQNWc5dUlidERLZ0trUElCME5wRDVtTVk5bE9WaE5DTHF5RnRnT0Q0OHVuaHRvbXZ6OTEyNmZGUmVPUllSYVJORGoyZTkzTDA5OWZSb0ZRVGViTUtWUFd4ZW5cL1piSzhIWFpJZUxsV3VNcUdjQXR5dmlLQXRXNDAiLCJzaXRlX2lkIjoiZGVmYXVsdCIsImFwaSI6Im9lbXIifQ=='
1576 #### GET /portal/patient
1578 Request:
1580 ```sh
1581 curl -X GET 'http://localhost:8300/apis/default/portal/patient'
1584 Response:
1586 ```json
1588     "validationErrors": [],
1589     "internalErrors": [],
1590     "data": {
1591         "id": "193",
1592         "pid": "1",
1593         "pubpid": "",
1594         "title": "Mr",
1595         "fname": "Baz",
1596         "mname": "",
1597         "lname": "Bop",
1598         "ss": "",
1599         "street": "456 Tree Lane",
1600         "postal_code": "08642",
1601         "city": "FooTown",
1602         "state": "FL",
1603         "county": "",
1604         "country_code": "US",
1605         "drivers_license": "",
1606         "contact_relationship": "",
1607         "phone_contact": "123-456-7890",
1608         "phone_home": "",
1609         "phone_biz": "",
1610         "phone_cell": "",
1611         "email": "",
1612         "DOB": "1992-02-03",
1613         "sex": "Male",
1614         "race": "",
1615         "ethnicity": "",
1616         "status": ""
1617     }
1621 ### Dev Notes
1623 -   For business logic, make or use the services [here](src/Services)
1624 -   For controller logic, make or use the classes [here](src/RestControllers)
1625 -   For routing declarations, use the class [here](_rest_routes.inc.php).
1627 ### Project Management
1629 #### General API
1631 -   TODO(?): Prevent `ListService` from using `enddate` of `0000-00-00` by default
1632 -   TODO(?): API for fee sheets
1633 -   TODO(?): API for pharmacies
1634 -   TODO(?): API for immunizations
1635 -   TODO(?): API for prescriptions
1636 -   TODO(?): Drug search API
1637 -   TODO(?): API for onotes