As described in the SMART on FHIR Authorization Flow to make API calls to Elation EMR FHIR API the App provide an access token as a bearer token.

Access token SHALL be obtained during auth flow by calling the authorize endpoint on the authorization server. The link for the authorization endpoint may be observed from here. An application using 2-legged authentication (system to system) can call the token endpoint directly to obtain an access token, while an applications using 3-legged authentication must first call the authorize endpoint to request and obtain an end user's consent. The token endpoint response for 3-legged authentication applications may also contain an Id token, refresh token, or launch context.

Note: Proof key for code exchange, or “PKCE”, is required for all public FHIR clients not using a client secret.

Authorize

The authorize endpoint is used for end user login, limits to requested by application scopes and consent as a prerequisite to requesting an access token. This endpoint SHOULD be obtained from the authorize endpoint temporarily redirects the end user to the Elation EMR FHIR API login, in which the user is asked to log in or automatically authenticated using an existing session, prompted for scopes limitations and consent form. Then finally redirected back to the requesting app with an authorization code. The app then provides this authorization code to the token endpoint to obtain an access token.

This flow is a browser flow only because authorization server will redirect the user's browser to provided redirect url.

The default value for the refresh token is 90 days. The application need to use offline token at least once during this period. Otherwise offline session will expired.

METHOD GET

GET [authorization_endpoint]?response_type=code&client_id=[client_id]&redirect_uri=[redirect_uri]&scope=[scope]&state=[state]&aud=[aud]

PARAMS
authorization_endpoint - authorization endpoint SHALL observed from the FHIR base url Authorization observation endpoint
client_id - client ID for registered developers application
redirect_uri - uri for for developers application which browser redirect after successfull authorization. Must exactly match a redirect URI configured for the developers application client credentials during registration
scope - requested optional scopes by application delimited by space, case sensitive. At minimum client must request the OpenID Connect scope (openid) for successful authentication and to obtain an ID token in the token endpoint response. To obtain a refresh token in the token endpoint response, the client must request the offline_access scope. To perform a SMART App Launch sequence, the client must request either the launch or launch/patient scope (for provider EHR launch or patient standalone launch) in addition to resource-level scopes for those FHIR endpoints you will access through your app launch. Detailed about scopes
state - a one-time use arbitrary string provided by developers application (client) and subsequently returned by the authorize endpoint. The intent of this parameter, per OAuth specification, is for application to compare the request and response values to prevent cross-site request forgery attacks.
aud - FHIR base URL, used to specify the organization for which the end user will be authenticated
code_challenge - PKCE code challenge generated from a cryptographically-random code verifier value. This parameter is only used by public FHIR clients without a client secret.
code_challenge_method - Method used to generate the PKCE code challenge. The only supported value is S256. This parameter is only used by public FHIR clients without a client secret.

RESPONSES
code - authorization code generated by Elation EMR FHIR API authorization server and required to make a token request
state - identical value to the state parameter provided in client app’s authorize request

Example

https://sandbox.fhir.elationemr.com/smart/authorize?response_type=code&client_id=my-app&redirect_uri=https%3A%2F%2Fmy.app.com%2Fsuites%2Fcustom%2Fsmart%2Fredirect&scope=launch%2Fpatient+openid+fhirUser+offline_access+patient%2FMedication.read+patient%2FAllergyIntolerance.read+patient%2FCarePlan.read+patient%2FCareTeam.read+patient%2FCondition.read+patient%2FDevice.read+patient%2FDiagnosticReport.read+patient%2FDocumentReference.read+patient%2FEncounter.read+patient%2FGoal.read+patient%2FImmunization.read+patient%2FLocation.read+patient%2FMedicationRequest.read+patient%2FObservation.read+patient%2FOrganization.read+patient%2FPatient.read+patient%2FPractitioner.read+patient%2FProcedure.read+patient%2FProvenance.read+patient%2FPractitionerRole.read+patient%2FServiceRequest.read&state=e75c105d-04b4-47e6-b4af-a36773cc2600&aud=https%3A%2F%2Fsandbox.fhir.elationemr.com%2Ffhir

Access token

Obtain an access token. The token endpoint is using for 2-legged authorization applications. This method works only if the client supports this type of authorization.

METHOD POST

[token_endpoint]

PARAMS
[token_endpoint url] - token endpoint SHALL observed from the FHIR base url Authorization observation endpoint

BODY
Body SHALL provide as x-www-form-url-encoded

client_id - ID for the client registered app
grant_type - 'client_credentials'
client_secret - client secret for the registered app. This parameter is only used by confidential FHIR clients that have a client secret.
scopes - requested optional scopes delimeted by space (e.g., patient/*.read launch/patient)
code_verifier - the PKCE cryptographically-random code generated previously and used for obtaining the code_challenge authorization endpoint value. This parameter is only used by public FHIR clients without a client secret.

HEADERS

The Authorization token SHALL be obtained during Authentication and Authorization process. Goto Authentication and Authorization for further details.

HeaderTypeRequired/OptionalValue
Content-Typestringrequiredapplication/x-www-form-urlencoded

RESPONSES

CodeDescriptionComment
200OKThe request was processed successfullyl and access token returned
400Bad requestInvalid request parameters, e.g. client id or grant type
401UnauthorizedInvalid client secret
404no Route matched with those valuesThe request was able to communicate with a given server, but the server could not find what was requested
500Internal Server ErrorThe server has encountered a situation it doesn't know how to handle

The Body will contain the JSON request response. If token has obtained successfully the body SHALL contain:

  • access_token - signed base64 JWT access token
  • id_token - signed OpenID Connect ID token. This value is only returned when the openid scope is requested.
  • expires_in - time in seconds to token expiration
  • refresh_expires_in - time in seconds to token expiration
  • token_type - fixed value: Bearer
  • scope - list of the granted default client's scope
  • patient - an optional identifier of the selected patient that is returned when any of the patient/ scopes or the launch/patient scope were requested.

EXAMPLE:

curl --location --request POST 'sandbox.fhir.elationemr/smart/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=my-app' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'client_secret=QmFzZTY0IGVuY29kaW5nIHN0cmluZw' \
--data-urlencode 'scopes=patient/*.read launch/patient'
  • decoded access_token example
{
  "ver": 1,
  "jti": "AT.2Nj0aWpgoy2twvv7Xv3f46EvRKhuc0KmIA67-bcEcoA",
  "iss": "https://sso.sandbox.elationemr.com/oauth2/aus12345678901234567",
  "aud": "https://sandbox.fhir.elationemr.com/fhir",
  "sub": "[email protected]",
  "iat": 1688701088,
  "exp": 1688704688,
  "cid": "0oa12345678901234567",
  "uid": "00u12345678901234567",
  "auth_time": 1688701077,
  "hsp": "sandbox1",
  "patient_id": "sandbox1-1234567890",
  "valid_consent": "true",
  "scope": "fhirUser launch launch/patient patient/*.read openid",
  "practice_ids": [
    "sandbox1-1234567890"
  ]
}

Token Introspection

Checks the status and content of a JWT token.

METHOD POST

POST [introspection_endpoint]

PARAMS
[introspection_endpoint] - token intorspection endpoint uri SHALL observed from the FHIR base url Authorization observation endpoint

BODY
Body SHALL provide as x-www-form-url-encoded

client_id - ID for the client registered app
client_secret - client secret for the registered app
token - token value for the introspection

This endpoint can only be used by confidential FHIR clients with a client secret.

HEADERS

The Authorization token SHALL be obtained during Authentication and Authorization process. Goto Authentication and Authorization for further details.

HeaderTypeRequired/OptionalValue
Content-Typestringrequiredapplication/x-www-form-urlencoded

RESPONSES

CodeDescriptionComment
200OKThe request was processed successfullyl and access token returned
400Bad requestInvalid request parameters, e.g. client id or grant type
401UnauthorizedInvalid client secret
404no Route matched with those valuesThe request was able to communicate with a given server, but the server could not find what was requested
500Internal Server ErrorThe server has encountered a situation it doesn't know how to handle

The Body will contain the JSON request response. If token has obtained successfully the body SHALL contain:

  • active - true or false. If token is active the additional token information will be provided
  • exp - time to token expiration (seconds since Unix epoch)
  • iat - time when token was issued (seconds since Unix epoch)
  • jti - JWT id, uniq token id
  • sub - list of the granted default client's scope
  • iss - token issuer and signer
  • typ - type of the token
  • azp - clinet (application)
  • acr - authentiocation context class
  • scope - granted scopes for the token
  • clientId - optional client id
  • clientHost - optional host
  • clientAddress - optional host

EXAMPLE:

curl --location --request POST 'https://sandbox.fhir.elationemr.com/smart/introspect' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.OTkgW2VudGFjdCBpcyB0aGUgbWVzc2FnZSBvZiA1MCBjaGFyYWN0ZXJzIHN0b3JlZCB0byBkZWFsIGVtYWlsIHZpYSBNSU1FLgo.MTU5IFt0aGVyZSBpcyBhIG5lZWQgZm9yIGVtYWlsIHZpYSBNSU1FLCB3aXRob3V0IG1vZGlmaWNhdGlvbiBpcyBjb21wbGV0ZWx5IHN0b3JlZCB0byBkZWFsIGVtYWlsIHZpYSBNSU1FLgo' \
--data-urlencode 'client_id=my-app' \
--data-urlencode 'client_secret=QmFzZTY0IGVuY29kaW5nIHN0cmluZw'
  • RESPONSE:
{
    "active": true,
    "scope": "fhirUser launch launch/patient patient/*.read openid",
    "username": "[email protected]",
    "exp": 1688704688,
    "iat": 1688701088,
    "sub": "[email protected]",
    "aud": "https://sandbox.fhir.elationemr.com/fhir",
    "iss": "https://sso.sandbox.elationemr.com/oauth2/aus12345678901234567",
    "jti": "AT.2Nj0aWpgoy2twvv7Xv3f46EvRKhuc0KmIA67-bcEcoA",
    "token_type": "Bearer",
    "client_id": "0oa12345678901234567",
    "uid": "00u12345678901234567",
    "hsp": "sandbox1",
    "valid_consent": "true",
    "patient_id": "sandbox1-1234567890",
    "practice_ids": [
        "sandbox1-1234567890"
    ]
}

Token Revokation

The Token Revocation is a mechanism for clients to indicate to the Elation EMR FHIR API authorization server that an access token is no longer needed. This is used to enable a "log out" feature in clients, allowing the authorization server to clean up any security credentials associated with the authorization.

METHOD POST

POST [revocation_endpoint]

PARAMS
[revocation_endpoint] - token revocation endpoint uri SHALL observed from the FHIR base url Authorization observation endpoint

BODY
Body SHALL provide as x-www-form-url-encoded

client_id - ID for the client registered app
client_secret - client secret for the registered app
token - token value for the revocation

HEADERS

The Authorization token SHALL be obtained during Authentication and Authorization process. Goto Authentication and Authorization for further details.

HeaderTypeRequired/OptionalValue
Content-Typestringrequiredapplication/x-www-form-urlencoded

RESPONSES

CodeDescriptionComment
200OKThe request was processed successfullyl and the token has revoced
400Bad requestInvalid request parameters, e.g. client id or client_secret or token
404no Route matched with those valuesThe request was able to communicate with a given server, but the server could not find what was requested
500Internal Server ErrorThe server has encountered a situation it doesn't know how to handle

EXAMPLE:

curl --location --request POST 'https://sandbox.fhir.elationemr.com/smart/revoke' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=my-app' \
--data-urlencode 'client_secret=QmFzZTY0IGVuY29kaW5nIHN0cmluZw' \
--data-urlencode 'token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.OTkgW2VudGFjdCBpcyB0aGUgbWVzc2FnZSBvZiA1MCBjaGFyYWN0ZXJzIHN0b3JlZCB0byBkZWFsIGVtYWlsIHZpYSBNSU1FLgo.MTU5IFt0aGVyZSBpcyBhIG5lZWQgZm9yIGVtYWlsIHZpYSBNSU1FLCB3aXRob3V0IG1vZGlmaWNhdGlvbiBpcyBjb21wbGV0ZWx5IHN0b3JlZCB0byBkZWFsIGVtYWlsIHZpYSBNSU1FLgo'