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://drc-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

After it is enabled, the SMART App will then be available to use in the Patient Summary screen (SMART Enabled Apps widget).

See this github issue for an example of a Smart App installation: #4148

Authorization Code Grant

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/oauth2/default. Standard OAUTH2 clients will retrieve the authorize URL from the FHIR /metadata endpoint, but if you are building your own client you can access the metadata or go directly to the https://localhost/oauth2/default/authorize endpoint.

Note that a refresh token is only supplied if the offline_access scope is provided when requesting authorization grant.

You will need to pass the scopes you are requesting, the redirect_uri (must be one that was registered at the time of your client registration), and a state parameter which can be any value. Once authorization has finished the browser will be redirected to the URL specified in redirect_uri with an encrypted code value and the state value sent in the initial authorize request.

Example GET (this must be done in a browser):

GET /oauth2/default/authorize?client_id=yi4mnmVadpnqnJiOigkcGshuG-Kayiq6kmLqCJsYrk4&response_type=code&scope=launch%2Fpatient%20openid%20fhirUser%20offline_access%20patient%2FAllergyIntolerance.read%20patient%2FCarePlan.read%20patient%2FCareTeam.read%20patient%2FCondition.read%20patient%2FDevice.read%20patient%2FDiagnosticReport.read%20patient%2FDocumentReference.read%20patient%2FEncounter.read%20patient%2FGoal.read%20patient%2FImmunization.read%20patient%2FLocation.read%20patient%2FMedication.read%20patient%2FMedicationRequest.read%20patient%2FObservation.read%20patient%2FOrganization.read%20patient%2FPatient.read%20patient%2FPractitioner.read%20patient%2FProcedure.read%20patient%2FProvenance.read&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcallback&state=9512151b-e5ca-cb4b-1ddc-aaf4cd8c6ecc

The client application must then make a request for an access token by hitting the /token endpoint. Note the redirect_uri MUST match what what was sent in /authorize endpoint. If your application is registered as a public application you must include the client_id in the POST request. If you are registered as a confidential app you must use HTTP Basic Authentication where the client_id is your username and the password is your client_secret. HTTP Basic Authentication follows the algorithm of base64_encode(username:client_secret). In PHP this would be base64_encode($client_id . ':' . $client_secret); Note that this mechanism should ONLY be used over an encrypted protocol such as TLS to prevent leaking your client_secret.

Example Public Application POST

curl -X POST -k -H 'Content-Type: application/x-www-form-urlencoded'
'https://localhost/oauth2/default/token'
--data 'grant_type=authorization_code&client_id=yi4mnmVadpnqnJiOigkcGshuG-Kayiq6kmLqCJsYrk4redirect_uri=https%3A%2F%2Fclient.example.org%2Fcallback&code=def50...'

Example Private Application POST

curl -X POST -k -H 'Content-Type: application/x-www-form-urlencoded' \
    -H 'Authorization: Basic c3Z2TThFX1hISEhYUmtoZzUyeWoyNjdIOEYwQnpmT09pRmE4aUZBT290WTptbzZpZEFPaEU0UVYxb0lacUR5YTFHR1JHVGU5VDQzNWpzeTlRbWYxV2NiVFQ4NXhuZW5VdUpaUFR0bUZGT1QxVkhmYjZiclVvWWZ2Znd2NTFQejFldw==' \
    'https://localhost/oauth2/default/token' \
    --data 'grant_type=authorization_code&client_id=yi4mnmVadpnqnJiOigkcGshuG-Kayiq6kmLqCJsYrk4redirect_uri=https%3A%2F%2Fclient.example.org%2Fcallback&code=def50...'

Refresh Token Grant

Note that a refresh token is only supplied if the offline_access scope is provided when requesting authorization or password grant.

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

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

Note that a refresh token is only supplied if the offline_access scope is provided when requesting password grant.

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

This is an advanced grant that uses JSON Web Key Sets(JWKS) to authenticate and identify the client. This credential grant is required to be used for access to any system/*.$export scopes. API clients must register either web accessible JWKS URI that hosts a RSA384 compatible key, or provide their JWKS as part of the registration. Client Credentials Grant access tokens are short lived and valid for only 1 minute and no refresh token is issued. Tokens are requested at /oauth2/default/token To walk you through how to do this process you can follow this guide created by HL7.

Logout

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/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.

Terms of Use

This is a legal agreement ("Agreement") between you, the "User", and EnSoftek Inc ("Company").  BY ACCEPTING THIS AGREEMENT, YOU ARE CONSENTING TO BE BOUND BY ITS TERMS. Read the terms of the agreement here. 

Definitions

As used herein: the "Software" means the DrCloudEHR Application Programming Interface (API).

License Grant

All Users SHALL possess an active DrCloudEHR license agreement.   Use of this Software SHALL BE COVERED BY THE TERMS OF THAT LICENSE AGREEMENT. If you do not have a license, existing customers can email support@drcloudemr.com. New Customers, please email info@drcloudehr.com


Limitation of Liability

Limitation of Liability for this Software SHALL BE COVERED BY THE TERMS OF THAT LICENSE AGREEMENT.

License Restrictions

The Company may limit the number of persons that can use the Software.  

Usage

If you become aware of any unauthorized access or use of the Software, you shall immediately notify the Company.


  • No labels