OpenEMR Appointment API both Standard API and FHIR not Working

Hello @adunsulag ,

I am trying to retrieve appointment information from my OpenEMR installation using the Standard API on Postman. Anytime i hit the endpoint, i get unauthorized 401 on the endpoint example.org/apis/default/api/appointment.

I tried the FHIR API as well and i had an internal server error.

Please see the error in my logs below

[19-Aug-2023 15:00:22 UTC] PHP Fatal error:  Uncaught Exception: DateTime::__construct(): Failed to parse time string (2022-08-30 32:00:00) at position 11 (3): Unexpected character in /home/root3375/public_html/example.org/src/Services/FHIR/UtilsService.php:307
Stack trace:
#0 /home/root3375/public_html/example.org/src/Services/FHIR/UtilsService.php(307): DateTime->__construct('2022-08-30 32:0...', Object(DateTimeZone))
#1 /home/root3375/public_html/example.org/src/Services/FHIR/FhirAppointmentService.php(196): OpenEMR\Services\FHIR\UtilsService::getLocalDateAsUTC('2022-08-30 32:0...')
#2 /home/root3375/public_html/example.org/src/Services/FHIR/FhirServiceBase.php(219): OpenEMR\Services\FHIR\FhirAppointmentService->parseOpenEMRRecord(Array)
#3 /home/root3375/public_html/example.org/src/RestControllers/FHIR/FhirAppointmentRestController.php(49): OpenEMR\Services\FHIR\FhirServiceBase->getAll(Array, NULL)
#4 /home/root3375/public_html/example.org/_rest_routes.inc.php(7638): OpenEMR\RestControllers\FHIR\FhirAppointmentRestController->getAll(Arra in /home/root3375/public_html/example.org/src/Services/FHIR/UtilsService.php on line 307

and these are my scopes

  • openid
  • fhirUser
  • online_access
  • offline_access
  • launch
  • launch/patient
  • api:oemr
  • api:fhir
  • api:port
  • profile
  • name
  • address
  • given_name
  • family_name
  • nickname
  • phone
  • phone_verified
  • email
  • email_verified
  • site:default
  • patient/Appointment.read
  • user/Appointment.read

I am running OpenEMR V7.0.0(2)

What is the localization setting for your date time settings? Are you able to reproduce this against the demos?

@adunsulag ,

i just checked my localization settings and it was set to “Unassigned”.

Can that be a factor?

I havent tested with the demos yet.

i will set the timezone setting and test with the demos.

Will keep you updated

I changed my locale timezone to America/New York and the same error persists (Internal Server Error)

On the OpenEMR demos, i get the error “The requested URL was not found on this server” using Postman when trying to get an access token

So a couple of things looking more closely at this. If you are using the standard api you’ll need to use the user/appointment.read scope (note the lowercase, uppercase is for the FHIR endpoint).

Second, its really hard to see what is going on with your posts to the demo servers or your own local server without any kind of sample request of what you are posting to see if there is something going on with the specific data you are using. If you can put up the full HTTP request you are sending that would be helpful. You can remove sensitive data such as client secrets or mask any urls you need to.

On the OpenEMR demo,

the FHIR API works.

The Standard API still shows invalid. I also used lowercase for the standard API.

This is the get request for a new token

GET https://example.org/oauth2/default/authorize?response_type=code&state=eCjLAjsjeT&client_id=oq2RiHr_L3BQipwKH6jVDs9o5aJnjUJA2F1TITvr3mw&scope=openid%20site%3Adefault%20fhirUser%20online_access%20offline_access%20launch%20launch%2Fpatient%20api%3Aoemr%20api%3Aoemr%20api%3Afhir%20api%3Aport%20profile%20name%20address%20given_name%20family_name%20nickname%20phone%20phone_verified%20email%20email_verified%20user%2Fappointment.read%20patient%2Fappointment.read&redirect_uri=https%3A%2F%2Fv7.medsov.com%2Fswagger%2Foauth2-redirect.html

This is the rest of the requests in succession.

So I would check what are the scopes being returned back to you in your token request and make sure you have the user/appointment.read scope being returned.

I’d also check to make sure you are logging in with a user that has the OpenEMR ACL for patients/appt.

Finally, I’d turn on the system logger debug logs (Config → Logging → System Error Logging Options) and see what happens when you hit the appointments endpoint. It should tell you why you are getting the 401 for the api if the system logger debug is turned on.

Seems the scope is not being saved. This was the error i found in my logs

OpenEMR.DEBUG: RestConfig::scope_check scope not in access token {“scope”:“user/appointment.read”,“scopes_granted”:[“openid”,“fhirUser”,“online_access”,“offline_access”,“launch”,“launch/patient”,“api:oemr”,“api:fhir”,“api:port”,“site:default”]} []

Please how do i get around this?

Go look at your Admin → System → API Clients screen and find your registered API client. Look at what scopes your client has registered. If the scopes you are requesting don’t appear in that list you need to review how you are registering your api client.

On the API clients page, the scope is included in the list. I have both user/Appointment and patient/Appointment.

This problem also exists on the demo instance of OpenEMR.

You need the lowercase scope: user/appointment.read If that is not there, it is why your request is failing.

Right,

But there’s no user/appointment.read when registering the client as part of the scopes.

The only option available is user/Appointment.read

Are you doing your registration via the GUI or via Postman? You can send a registration request as a POST api that includs the user/appointment.read scope.

Look at the following post request (copied from Insomnia) as an example:

> POST /oauth2/default/registration HTTP/1.1
> Host: localhost:9300
> User-Agent: insomnia/2021.2.2
> Cookie: XDEBUG_SESSION=1
> Content-Type: application/json
> Accept: */*
> Content-Length: 1287

| {
| 	"application_type": "private",
|    "redirect_uris":
|      ["http://localhost:4567/inferno/oauth2/static/redirect"],
|    "post_logout_redirect_uris":
|      ["http://localhost:4567/inferno/oauth2/static/logout"],
|    "client_name": "My new test client blah blah",
| 	"initiate_login_uri": "http://localhost:4567/inferno/oauth2/static/launch",
|    "token_endpoint_auth_method": "client_secret_post",
|    "contacts": ["me@example.org", "them@example.org"],
| 	 "scope": "openid offline_access api:oemr api:fhir api:port user/allergy.read user/allergy.write user/appointment.read user/appointment.write user/dental_issue.read user/dental_issue.write user/document.read user/document.write user/drug.read user/encounter.read user/encounter.write user/facility.read user/facility.write user/immunization.read user/insurance.read user/insurance.write user/insurance_company.read user/insurance_company.write user/insurance_type.read user/list.read user/medical_problem.read user/medical_problem.write user/medication.read user/medication.write user/message.write user/patient.read user/patient.write user/practitioner.read user/practitioner.write user/prescription.read user/procedure.read user/soap_note.read user/soap_note.write user/surgery.read user/surgery.write user/vital.read user/vital.write"
| }

That is correct.

I am doing the registration through the GUI.

I’ll try doing the registration using Postman

@adunsulag,

It’s working now. Turns out it was only the FHIR API user/Appointment that was registering in the database. Once i registered the client using user/appointment, i am able to retrieve the appointments API without any problem.

Thanks a million.

2 Likes