Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents

Software Release Version

DrCloudEHR

...

2025

API Description

Easy-to-use JSON-based REST API for DrCloudEHR FHIR. See standard DrCloudEHR API docs here. The DrCloudEHR FHIR API conforms to the R4 specification and the US Core 3.1 Implementation Guide (IG).

API Documentation using Swagger

For API Syntax, function names, required/optional parameters see swagger based documentation at https://cures-api-docs.drcloudemr.com

Prerequisites

Interoperability requirements with DrCloudEHR for Native Applications

    • Native applications wishing to use the DrCloudEHR FHIR API with refresh tokens MUST be capable of storing the refresh token in a secure manner similar to the requirements of storing a secret for confidential apps.
    • Native applications must support either PKCE with a public app or use a confidential app. PKCE is still recommended to be used with confidential apps to prevent MITM attacks.
    • Native applications must request the offline_scope in their initial API request in order to receive a refresh token
    • Native application refresh tokens are valid for 3 months before they must be renewed.
    • Native applications will receive a new refresh token every time they are renewed.
    • Native applications can only communicate with DrCloudEHR over a TLS secured channel in order to ensure the safe transmission of the refresh token.
    • Native applications should use certificate pinning to mitigate any SSL MITM attack.
    • Native applications must use the Authorization Code grant flow in order to receive a refresh token.
    • It is recommended that native applications follow best practices for native client applications as outlined in RFC 8252 OAuth 2.0 for Native Apps.

Technical details

    • The DrCloudEHR server uses HTTPS to ensure a secure data connection.
    • Parameters are passed to the API scripts using POST variables.
      • Most of the API calls return their result as an XML file.
      • The script that handles MU3 data request returns a JSON file.

Authorization

DrCloudEHR uses OIDC compliant authorization for API. SSL is required.

Scopes

This is a listing of scopes:

    • openid (Generic mandatory scope)
    • fhirUser
    • online_access
    • offline_access (Will signal server to provide a refresh token)
    • launch
    • launch/patient
    • api:fhir (fhir which are the /fhir/ endpoints)
      • patient/AllergyIntolerance.read
      • patient/Appointment.read
      • patient/Binary.read
      • patient/CarePlan.read
      • patient/CareTeam.read
      • patient/Condition.read
      • patient/Coverage.read
      • patient/Device.read
      • patient/DiagnosticReport.read
      • patient/DocumentReference.read
      • patient/DocumentReference.$docref
      • patient/Encounter.read
      • patient/Goal.read
      • patient/Immunization.read
      • patient/Location.read
      • patient/MedicationRequest.read
      • patient/Medication.read
      • patient/Observation.read
      • patient/Organization.read
      • patient/Patient.read
      • patient/Person.read
      • patient/Practitioner.read
      • patient/Procedure.read
      • patient/Provenance.read
      • system/AllergyIntolerance.read
      • system/Binary.read
      • system/CarePlan.read
      • system/CareTeam.read
      • system/Condition.read
      • system/Coverage.read
      • system/Device.read
      • system/DiagnosticReport.read
      • system/DocumentReference.read
      • system/DocumentReference.$docref
      • system/Encounter.read
      • system/Goal.read
      • system/Group.read
      • system/Group.$export
      • system/Immunization.read
      • system/Location.read
      • system/MedicationRequest.read
      • system/Medication.read
      • system/Observation.read
      • system/Organization.read
      • system/Patient.read
      • system/Patient.$export
      • system/Person.read
      • system/Practitioner.read
      • system/PractitionerRole.read
      • system/Procedure.read
      • system/Provenance.read
      • system/*.$bulkdata-status
      • system/*.$export
      • user/AllergyIntolerance.read
      • user/Binary.read
      • user/CarePlan.read
      • user/CareTeam.read
      • user/Condition.read
      • user/Coverage.read
      • user/Device.read
      • user/DiagnosticReport.read
      • user/DocumentReference.read
      • user/DocumentReference.$docref
      • user/Encounter.read
      • user/Goal.read
      • user/Immunization.read
      • user/Location.read
      • user/MedicationRequest.read
      • user/Medication.read
      • user/Observation.read
      • user/Organization.read
      • user/Patient.read
      • user/Person.read
      • user/Practitioner.read
      • user/Practitioner.write
      • user/PractitionerRole.read
      • user/Procedure.read
      • user/Provenance.read

Registration

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.

Note that all scopes are included in this example for demonstration purposes. For production purposes, should only include the necessary scopes.

curl -X POST -k -H 'Content-Type: application/json' -i https://localhost/oauth2/default/registration --data '{
   "application_type": "private",
   "redirect_uris":
     ["https://client.example.org/callback"],
   "post_logout_redirect_uris":
     ["https://client.example.org/logout/callback"],
   "client_name": "A Private App",
   "token_endpoint_auth_method": "client_secret_post",
   "contacts": ["me@example.org", "them@example.org"],
   "scope": "openid offline_access api:fhir 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/transaction.read user/transaction.write user/vital.read user/vital.write user/AllergyIntolerance.read user/CareTeam.read user/Condition.read user/Coverage.read user/Encounter.read user/Immunization.read user/Location.read user/Medication.read user/MedicationRequest.read user/Observation.read user/Organization.read user/Organization.write user/Patient.read user/Patient.write user/Practitioner.read user/Practitioner.write user/PractitionerRole.read user/Procedure.read patient/encounter.read patient/patient.read patient/AllergyIntolerance.read patient/CareTeam.read patient/Condition.read patient/Coverage.read patient/Encounter.read patient/Immunization.read patient/MedicationRequest.read patient/Observation.read patient/Patient.read patient/Procedure.read"
  }'

Response:

{
    "client_id": "LnjqojEEjFYe5j2Jp9m9UnmuxOnMg4VodEJj3yE8_OA",
    "client_secret": "j21ecvLmFi9HPc_Hv0t7Ptmf1pVcZQLtHjIdU7U9tkS9WAjFJwVMav0G8ogTJ62q4BATovC7BQ19Qagc4x9BBg",
    "registration_access_token": "uiDSXx2GNSvYy5n8eW50aGrJz0HjaGpUdrGf07Agv_Q",
    "registration_client_uri": "https:\/\/localhost\/oauth2\/default\/client\/6eUVG0-qK2dYiwfYdECKIw",
    "client_id_issued_at": 1604767861,
    "client_secret_expires_at": 0,
    "contacts": ["me@example.org", "them@example.org"],
    "application_type": "private",
    "client_name": "A Private App",
    "redirect_uris": ["https:\/\/client.example.org\/callback"],
    "token_endpoint_auth_method": "client_secret_post",
    "scope": "openid offline_access api:fhir 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/transaction.read user/transaction.write user/vital.read user/vital.write user/AllergyIntolerance.read user/CareTeam.read user/Condition.read user/Coverage.read user/Encounter.read user/Immunization.read user/Location.read user/Medication.read user/MedicationRequest.read user/Observation.read user/Organization.read user/Organization.write user/Patient.read user/Patient.write user/Practitioner.read user/Practitioner.write user/PractitionerRole.read user/Procedure.read patient/encounter.read patient/patient.read patient/AllergyIntolerance.read patient/CareTeam.read patient/Condition.read patient/Coverage.read patient/Encounter.read patient/Immunization.read patient/MedicationRequest.read patient/Observation.read patient/Patient.read patient/Procedure.read"
}

...

Smart on FHIR Registration

SMART Enabled Apps are supported.

SMART client can be registered at /interface/smart/register-app.php. For example https:///localhostdrc-india.drcloudemr.com/drcloud/interface/smart/register-app.php

After registering the SMART client, can then Enable it in DrCloudEHR at Administration->System->API Clients

...

Example:

curl -X POST -k -H 'Content-Type: application/x-www-form-urlencoded'
-i 'https://localhost/oauth2/default/token'
--data 'grant_type=refresh_token
&client_id=LnjqojEEjFYe5j2Jp9m9UnmuxOnMg4VodEJj3yE8_OA
&refresh_token=def5020089a766d16...'

Response:

{
  "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJrYn...",
  "token_type": "Bearer",
  "expires_in": 3599,
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJrYnl1RkRp...",
  "refresh_token": "def5020017b484b0add020bf3491a8a537fa04eda12..."
}

Password Grant

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)'.

...

Example for users role:

curl -X POST -k -H 'Content-Type: application/x-www-form-urlencoded'
-i 'https://localhost/oauth2/default/token'
--data 'grant_type=password
&client_id=LnjqojEEjFYe5j2Jp9m9UnmuxOnMg4VodEJj3yE8_OA
&scope=openid%20offline_access%20api%3Adrcloud%20api%3Afhir%20user%2Fallergy.read%20user%2Fallergy.write%20user%2Fappointment.read%20user%2Fappointment.write%20user%2Fdental_issue.read%20user%2Fdental_issue.write%20user%2Fdocument.read%20user%2Fdocument.write%20user%2Fdrug.read%20user%2Fencounter.read%20user%2Fencounter.write%20user%2Ffacility.read%20user%2Ffacility.write%20user%2Fimmunization.read%20user%2Finsurance.read%20user%2Finsurance.write%20user%2Finsurance_company.read%20user%2Finsurance_company.write%20user%2Finsurance_type.read%20user%2Flist.read%20user%2Fmedical_problem.read%20user%2Fmedical_problem.write%20user%2Fmedication.read%20user%2Fmedication.write%20user%2Fmessage.write%20user%2Fpatient.read%20user%2Fpatient.write%20user%2Fpractitioner.read%20user%2Fpractitioner.write%20user%2Fprescription.read%20user%2Fprocedure.read%20user%2Fsoap_note.read%20user%2Fsoap_note.write%20user%2Fsurgery.read%20user%2Fsurgery.write%20user%2Ftransaction.read%20user%2Ftransaction.write%20user%2Fvital.read%20user%2Fvital.write%20user%2FAllergyIntolerance.read%20user%2FCareTeam.read%20user%2FCondition.read%20user%2FCoverage.read%20user%2FEncounter.read%20user%2FImmunization.read%20user%2FLocation.read%20user%2FMedication.read%20user%2FMedicationRequest.read%20user%2FObservation.read%20user%2FOrganization.read%20user%2FOrganization.write%20user%2FPatient.read%20user%2FPatient.write%20user%2FPractitioner.read%20user%2FPractitioner.write%20user%2FPractitionerRole.read%20user%2FProcedure.read
&user_role=users
&username=admin
&password=pass'

Example for patient role:

curl -X POST -k -H 'Content-Type: application/x-www-form-urlencoded'
-i 'https://localhost/oauth2/default/token'
--data 'grant_type=password
&client_id=LnjqojEEjFYe5j2Jp9m9UnmuxOnMg4VodEJj3yE8_OA
&scope=openid%20offline_access%20api%3Aport%20api%3Afhir%20patient%2Fencounter.read%20patient%2Fpatient.read%20patient%2FAllergyIntolerance.read%20patient%2FCareTeam.read%20patient%2FCondition.read%20patient%2FCoverage.read%20patient%2FEncounter.read%20patient%2FImmunization.read%20patient%2FMedication.read%20patient%2FMedicationRequest.read%20patient%2FObservation.read%20patient%2FPatient.read%20patient%2FProcedure.read
&user_role=patient
&username=Phil1
&password=phil
&email=heya@invalid.email.com'

Response:

{
  "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJrYn...",
  "token_type": "Bearer",
  "expires_in": 3599,
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJrYnl1RkRp...",
  "refresh_token": "def5020017b484b0add020bf3491a8a537fa04eda12..."
}

Client Credentials Grant

...