NAV Navbar
Logo cerner
hidden ruby

HealtheIntent API Workshop

Course Objective

These sessions will teach you how to consume Population Health concepts using the Cerner HealtheIntent APIs.

The HealtheIntent slide deck can be found here.

Prerequisites

For this workshop you will need an HTTP client to call the APIs with. Postman is a popular application that we recommend. Alternatively, you can use an HTTP client library in the language of your choice. Listed below are some of the options you can use. The examples in this workshop will use Ruby’s HTTParty throughout. If you are not familiar with ruby, don’t worry! The ruby quickstart guide will help you get started.

Click the Ruby tab at the top of the right column to view Ruby code used to solve each exercise.

Introduction to HealtheIntent APIs

URI Structure

URIs for HealtheIntent APIs generally adhere to one of two structures. The structure used by a specific API can be found in the documentation for that API.

Since HealtheIntent is a multi-tenant platform, both structures include a client mnemonic in the hostname to identify the HealtheIntent client for which API calls are being made.

Most APIs discussed in this workshop use the new platform URI structure, which is:

https://{tenant-mnemonic}.api.us.healtheintent.com/{api-name}/{version}

For this workshop, we will be using the cernerdemo tenant. So the URI structure will look like:

https://cernerdemo.api.us.healtheintent.com/{api-name}/{version}

To make calls to your production tenant, you would replace cernerdemo with your tenant mnemonic.

Authentication and Authorization

HealtheIntent‘s APIs support two different mechanisms for authentication.

For detailed documentation on how to authenticate against the HealtheIntent APIs, please see the documentation we have for Authentication.

Authentication using a Bearer Token

For this workshop bearer token authentication should be used. To create the Authorization header simply take the bearer token value, prefix it with the word Bearer, and place into the Authorization header.

Authorization: Bearer <bearer token value>

The bearer token can be found at tinyurl.com/y9cygfac

For use with ruby, this value can be stored in a variable.

auth_header = 'Bearer <bearer token Value>'

Exercise 1

Create an Authorization header using the bearer token at tinyurl.com/y9cygfac

Note We will be disabling this token at the end of the workshop.

Make the following API call using cURL or Postman to confirm the authorization header is correct:

curl -H 'Authorization: <auth_header>' https://cernerdemo.api.us.healtheintent.com/patient/v1/populations/1424e81d-8cea-4d6b-b140-d6630b684a58/patients/a2f6a16d-1331-4ccc-8f70-6c4d953ba70b/demographics

A JSON response body should be returned.

Note The Authorization header created as part of this exercise will be used in the later exercises.

Authorization

The system account we will be using has already been created. It has permissions to access the APIs used in this workshop.

Note We will be disabling this account at the end of this workshop. To request a new system account to pursue further development against our platform, follow the instructions here.

Request Headers

The following headers must be set before you can call the HealtheIntent APIs:

Patient APIs

The Cerner longitudinal record is designed to provide a normalized and standardized aggregation of clinical data for a patient. A patient in HealtheIntent represents the demographic information necessary to identify an individual person in the context of a given population. A person in real life may be represented as multiple patients in multiple populations across one or more tenants.

We will be using the cernerdemo tenant mnemonic and following population ID for all of our exercises: 1424e81d-8cea-4d6b-b140-d6630b684a58. For all exercises, you will need to use the Authorization header created in the authorization exercise.

Patient Lookup

This API retrieves the HealtheIntent patient IDs for a given patient using the local source person IDs and data partition IDs.

Patient ID Lookup API: GET /populations/{populationId}/patient-id-lookup

The Patient API docs can be found here.

Exercise 1

query_parameters = {
  'dataPartitionId' => '8dee150d-505f-4635-b009-1bef63d7cf5a',
  'sourcePersonId' => '3601867'
}

response = HTTParty.get('https://cernerdemo.api.us.healtheintent.com/patient/v1/populations/1424e81d-8cea-4d6b-b140-d6630b684a58/patient-id-lookup', headers: {'Accept' => 'application/json', 'Authorization' => <auth_header>}, query: query_parameters)

puts JSON.pretty_generate(response.to_h)

We need to find the HealtheIntent patient ID for Felix K. Dupont. In this case, we’ll assume that 8dee150d-505f-4635-b009-1bef63d7cf5a is the data partition ID for an EMR source and that 3601867 is the person_id from that source.

The unformatted response object is hard to read, so let’s make it look pretty by using pretty_generate!

Click here for the answer Patient ID for Felix K. Dupont is d4c283a6-1a5c-4427-82ce-ef4ef8e35d30

Patient Demographics

We just found the Healtheintent Patient Id for Felix K. Dupont. Now let’s learn a little more about him, by using the Patient Demographics API.

Patient Demographics API: GET /populations/{populationId}/patients/{patientId}/demographics

Exercise 2

response = HTTParty.get('https://cernerdemo.api.us.healtheintent.com/patient/v1/populations/1424e81d-8cea-4d6b-b140-d6630b684a58/patients/d4c283a6-1a5c-4427-82ce-ef4ef8e35d30/demographics', headers: {'Accept' => 'application/json', 'Authorization' => <auth_header>})

puts JSON.pretty_generate(response.to_h)

Find out Felix K. Dupont’s known addresses.

Click here for the answer 1608 SW SUMMIT VALLEY LN LEES SUMMIT, MO 64081-3781 US

Patient Medications

Time to check out the medications prescribed to Felix.

Medication API: GET /populations/{populationId}/patients/{patientId}/medications

The Medication API docs can be found here.

Exercise 3

response = HTTParty.get('https://cernerdemo.api.us.healtheintent.com/medication/v1/populations/1424e81d-8cea-4d6b-b140-d6630b684a58/patients/d4c283a6-1a5c-4427-82ce-ef4ef8e35d30/medications', headers: {'Accept' => 'application/json', 'Authorization' => <auth_header>})

puts JSON.pretty_generate(response.to_h)

Find out all the medications that Felix has been prescribed. What is the most recent medication that Felix has been presribed?

Click here for the answer Plavix was presribed on Aug 24, 2018.

Patient Allergies

Before we prescribe any new medications to Felix, let’s check out what they have been allergic to.

Allergy API: GET /populations/{populationId}/patients/{patientId}/allergies

The Allergy API docs can be found here.

Exercise 4

response = HTTParty.get('https://cernerdemo.api.us.healtheintent.com/allergy/v1/populations/1424e81d-8cea-4d6b-b140-d6630b684a58/patients/d4c283a6-1a5c-4427-82ce-ef4ef8e35d30/allergies', headers: {'Accept' => 'application/json', 'Authorization' => <auth_header>})

puts JSON.pretty_generate(response.to_h)

Find out if Felix is allergic to anything.

Click here for the answer Felix is currently allergic to sulfa drugs. Take note of the status attribute for ‘cancelled’ allergies.

Patient Conditions

Now it’s time to see all the conditions Felix has. We can use the Condition API to find them.

Condition API: GET /populations/{populationId}/patients/{patientId}/conditions

The Condition API docs can be found here.

Exercise 5

response = HTTParty.get('https://cernerdemo.api.us.healtheintent.com/condition/v1/populations/1424e81d-8cea-4d6b-b140-d6630b684a58/patients/d4c283a6-1a5c-4427-82ce-ef4ef8e35d30/conditions', headers: {'Accept' => 'application/json', 'Authorization' => <auth_header>})

puts JSON.pretty_generate(response.to_h)

Take a look at all the conditions Felix has. What is the most recently asserted condition for Felix?

Click here for the answer Diabetes was asserted on Sep 24 2018. It has been asserted multiple time by multiple sources (as have a number of his other conditions).

Patient Procedures

Let’s check out all the procedures we know about for Felix.

Procedure API: GET /populations/{populationId}/patients/{patientId}/procedures

The Procedure API docs can be found here.

Exercise 6

response = HTTParty.get('https://cernerdemo.api.us.healtheintent.com/procedure/v1/populations/1424e81d-8cea-4d6b-b140-d6630b684a58/patients/d4c283a6-1a5c-4427-82ce-ef4ef8e35d30/procedures', headers: {'Accept' => 'application/json', 'Authorization' => <auth_header>})

puts JSON.pretty_generate(response.to_h)

Check out all the procedures Felix has undergone. When was his colonoscopy?

Click here for the answer His colonoscopy was in January 2015.

Patient Immunizations

Let’s check out all the immunizations we know about for Felix.

Immunization API: GET /populations/{populationId}/patients/{patientId}/immunizations

The Immunization API docs can be found here.

Exercise 7

response = HTTParty.get('https://cernerdemo.api.us.healtheintent.com/immunization/v1/populations/1424e81d-8cea-4d6b-b140-d6630b684a58/patients/d4c283a6-1a5c-4427-82ce-ef4ef8e35d30/immunizations', headers: {'Accept' => 'application/json', 'Authorization' => <auth_header>})

puts JSON.pretty_generate(response.to_h)

Let’s check out Felix’s immunization record. What immunizations has he had?

Click here for the answer He has 2 immunizations: Influenza and TDap. Neither have been asserted more than once. He definitely needs to get his seasonal flu shot!

Patient Observations

Let’s check out all the observations we know about for Felix.

Observation API: GET /populations/{populationId}/patients/{patientId}/observations

The Observation API docs can be found here.

Exercise 8

response = HTTParty.get('https://cernerdemo.api.us.healtheintent.com/observation/v1/populations/1424e81d-8cea-4d6b-b140-d6630b684a58/patients/d4c283a6-1a5c-4427-82ce-ef4ef8e35d30/observations', headers: {'Accept' => 'application/json', 'Authorization' => <auth_header>})

puts JSON.pretty_generate(response.to_h)

Check out what the most recent observation for Felix happens to be.

Click here for the answer Looks like it is a Height measurement from Sep 24, 2018. Felix is 170 cm tall or about 5’ 6".

Patient Risk Assessments

A risk assessment represents the quantified likelihood of certain outcomes for a patient, for example, the risk of potentially preventable encounters (PPEs) or the likelihood that a patient might suffer from cardiac arrest. In addition to to the type, a risk assessment includes attributes that indicate the method used to inform the assessment and the condition if the assessment pertains to one. Today, the Risk Assessment API only surfaces Risk Assessment generated by the HealtheIntent platform, it does not yet expose Risk Assessments that were sent in from an external source.

Felix doesn’t have any Risk Assessments so let’s switch patients really quick to Joanne Batjes: 106824bb-a35c-4870-97fa-145c7079bc2a.

Risk Assessments API: GET /populations/{populationId}/patients/{patientId}/risk-assessments

The Risk Assessment API docs can be found here.

Exercise 9

response = HTTParty.get('https://cernerdemo.api.us.healtheintent.com/risk-assessment/v1/populations/1424e81d-8cea-4d6b-b140-d6630b684a58/patients/106824bb-a35c-4870-97fa-145c7079bc2a/risk-assessments', headers: {'Accept' => 'application/json', 'Authorization' => <auth_header>})

puts JSON.pretty_generate(response.to_h)

Find out what type of Risk Assessment Joanna has.

Click here for the answer A cardiovascular morbidity prediction with a score of ‘2.7’ that wast last calculated Oct 4, 2018.

Bonus Exercise

With Joanne’s patient-id in hand(106824bb-a35c-4870-97fa-145c7079bc2a) go ahead and run through the previous exercises in order to inspect her normalized and standardized aggregation of longitudinal data!

HealtheRegistries

A registry is an aggregation of an organization’s patients who share particular clinical characteristics.

Detailed API documentation for HealtheRegistries can be found here

The HealtheRegistries API uses the legacy URL structure, which can be found here.

Person Registries Summaries

Person Registries summary lets you fetch a person’s registry data using the HealtheIntent person id.

Person Registries summary API: GET api/populations/{population_id}/people/{person_id}/registries

Exercise 1

require 'httparty'

# psssst... remember to create the authorization header

response = HTTParty.get('https://cernerdemo.registries.healtheintent.com/api/populations/1424e81d-8cea-4d6b-b140-d6630b684a58/people/6faf92f6-f3d3-4e0e-b633-48a45df383db/registries',headers: {'Accept' => 'application/json', 'Authorization' => <auth_header>})

puts JSON.pretty_generate(response.to_h)

MARA risk score is a metric that is used to gauge a patient’s cost of care to the hospital. Average risk score for a person is 1. The cost of care will be more expensive for a patient with a higher risk score.

Tammy Butler’s person_id is 6faf92f6-f3d3-4e0e-b633-48a45df383db, which can be used to fetch her registry. What is the MARA score for Tammy?

Click here for the answer The MARA score is 0.0

Exercise 2

query_parameters = {fields: 'mara_total_risk_score'}

response = HTTParty.get('https://cernerdemo.registries.healtheintent.com/api/populations/1424e81d-8cea-4d6b-b140-d6630b684a58/people/6faf92f6-f3d3-4e0e-b633-48a45df383db/registries',headers: {'Accept' => 'application/json', 'Authorization' => <auth_header>}, query: query_parameters)

puts JSON.pretty_generate(response.to_h)

Now using the query parameters filter the response so that you only get the MARA score.

Hint Use the “fields” query parameter to filter the mara_total_risk_score field.

Exercise 3

query_parameters = { measures_status_filter: 'due' }

response = HTTParty.get('https://cernerdemo.registries.healtheintent.com/api/populations/1424e81d-8cea-4d6b-b140-d6630b684a58/people/6faf92f6-f3d3-4e0e-b633-48a45df383db/registries',headers: {'Accept' => 'application/json', 'Authorization' => <auth_header>}, query: query_parameters)

puts JSON.pretty_generate(response.to_h)

As Tammy’s primary care provider you want to know all the measures that are due.

Fetch her registry and find out all the measures that are due under Chronic Obstructive Pulmonary Disease.

Hint Use the “measures_status_filter” query parameter to filter only those measures that are due.

Click here for the answer These are the measures that are due are “Influenza vaccination current season”, “spirometry evaluation” and “tobacco use screening and cessation”.

Person Measure Component Group

Supporting facts for a measure can be fetched using the component group API.

Person Measure Component Group API: GET api/populations/{population_id}/people/{person_id}/registries/{program_id}/measures/{fqn}/componentGroup

fqn is the fully qualified name of the measure (its identifier); an example of this is cernerstandard.adultwellness.org2014.clinical/body-mass-index. Also, program_id is the HealtheIntent program id to which the corresponding measure belongs to; an example of this is cernerdemo.adultwellness.org.clinical.cernerdemo-adult-wellness.

Exercise 4

response = HTTParty.get('https://cernerdemo.registries.healtheintent.com/api/populations/1424e81d-8cea-4d6b-b140-d6630b684a58/people/6faf92f6-f3d3-4e0e-b633-48a45df383db/registries/cernerdemo.diabetes.org.clinical.cernerdemo-diabetes/measures/cernerstandard.diabetesmellitus.org2014.clinical%2Fbp-less-than-140-80/componentGroup' ,headers: {'Accept' => 'application/json', 'Authorization' => <auth_header>})

puts JSON.pretty_generate(response.to_h)

Let’s take a look at what Tammy’s last measured blood pressure is. Fetch supporting facts for cernerstandard.diabetesmellitus.org2014.clinical/bp-less-than-140-80 measure from cernerdemo.diabetes.org.clinical.cernerdemo-diabetes program.

Hint The “/” in the measure needs to be changed to “%2F”.

Click here for the answer Blood Pressure 112/60 mmHg.

Bonus questions

Exercise 5

response = HTTParty.get('https://cernerdemo.registries.healtheintent.com/api/populations/1424e81d-8cea-4d6b-b140-d6630b684a58/programs', headers: {'Accept' => 'application/json', 'Authorization' => <auth_header>})

puts JSON.pretty_generate(response.to_h)

Retrieve all the programs for the population.

Hint Need to use the Programs API: “GET api/populations/{population_id}/programs”.

Exercise 6

response = HTTParty.get('https://cernerdemo.registries.healtheintent.com/api/populations/1424e81d-8cea-4d6b-b140-d6630b684a58/programs/cernerdemo.asthma.org.clinical.cernerdemo-asthma-care', headers: {'Accept' => 'application/json', 'Authorization' => <auth_header>})

puts JSON.pretty_generate(response.to_h)

How many measures does the cernerdemo.asthma.org.clinical.cernerdemo-asthma-care program have?

Hint Need to use the Programs API: “GET /populations/{population_id}/programs/{program_id}” to retrieve a single program.

Click here for the answer cernerdemo.asthma.org.clinical.cernerdemo-asthma-care program has 5 measures.

Exercise 7

request_body = { person_ids: ['ae3a2060-1261-43a3-a42b-013b0d700fca', 'a6facde2-b5b3-41e0-b939-3d9c87b258c9', '6faf92f6-f3d3-4e0e-b633-48a45df383db'],
  program_ids: [ 'cernerdemo.adultwellness.org.clinical.cernerdemo-adult-wellness']
}

query_parameters = { measures_status_filter: 'due' }

response = HTTParty.post('https://cernerdemo.registries.healtheintent.com/api/populations/1424e81d-8cea-4d6b-b140-d6630b684a58/people/registries', headers: {'Authorization' => <auth_header>}, body: request_body, query: query_parameters)

puts JSON.pretty_generate(response.to_h)

Stephanie (ae3a2060-1261-43a3-a42b-013b0d700fca), Jason (a6facde2-b5b3-41e0-b939-3d9c87b258c9) and Tammy (6faf92f6-f3d3-4e0e-b633-48a45df383db) are coming in today for a checkup. Fetch their registries and find out what measures are due for their Cerner adult wellness program. The program id for “Cerner adult wellness” is cernerdemo.adultwellness.org.clinical.cernerdemo-adult-wellness.

Hint Need to use the Multiple People registries API: “POST /populations/{population_id}/people/registries” to retrieve multiple registries. You will also have to use the “measures_status_filter” query parameter.

Click here for the answer The measures due for Stephanie, Jason, and Tammy are 10, 10, and 7 respectively.

Hierarchical Condition Categories (HCC)

HCC

Hierarchical Condition Categories (HCCs) are used by Medicare Advantage (MA) plans for reimbursement. The HCC API lets you fetch HCC defined conditions that are persistent from last year and also conditions that are suspected for a person using the HealtheIntent person id.

Detailed API documentation for HCC can be found here

The HCC API uses the legacy URL structure, which can be found here.

Exercise 1

response = HTTParty.get('https://cernerdemo.programs.healtheintent.com/api/populations/1424e81d-8cea-4d6b-b140-d6630b684a58/people/6faf92f6-f3d3-4e0e-b633-48a45df383db/hcc_diagnoses', headers: {'Authorization' => <auth_header>})

puts JSON.pretty_generate(response.to_h)

The HCC Code attribute is composed of the code number and description.

Tammy Butler got her checkup done. Let’s check the code which has a diagnosis code value of J44.9 for Tammy Butler, using her person id from the last exercise (6faf92f6-f3d3-4e0e-b633-48a45df383db).

Hint Need to use the HCC API: “GET /populations/{population_id}/people/{person_id}/hcc_diagnoses” to retrieve HCC diagnoses data of a person.

Click here for the answer HCC111 Chronic Obstructive Pulmonary Disease

Exercise 2

HCC Data can be of two types. Two types are suspected and persistent. The conditions that are suspected will include a stratification field that categorizes the level of suspicion. The possible values of stratification are NOT SUSPECTED, MODERATELY SUSPECTED and HIGHLY SUSPECTED.

query_parameters = { type: 'suspected' }

response = HTTParty.get('https://cernerdemo.programs.healtheintent.com/api/populations/1424e81d-8cea-4d6b-b140-d6630b684a58/data_partitions/8dee150d-505f-4635-b009-1bef63d7cf5a/people/3584536/hcc_diagnoses', headers: {'Authorization' => <auth_header>}, query: query_parameters)

puts JSON.pretty_generate(response.to_h)

Use Tammy’s data_partition_person_id 3584536 and data_partition_id 8dee150d-505f-4635-b009-1bef63d7cf5a to find the stratification value of the code HCC96 Specified Heart Arrhythmias?

Hint Need to use the HCC API: “GET /populations/{population_id}/data_partitions/{data_partion_id}/people/{data_partition_person_id}/hcc_diagnoses?type=suspected” to retrieve HCC diagnoses suspected data of a person.

Click here for the answer Highly Suspected

Risk Adjustment Factor (RAF)

Fetches the RAF score data of a person based on population ID and HealtheIntent person ID.

Exercise 3

response = HTTParty.get('https://cernerdemo.programs.healtheintent.com/api/populations/1424e81d-8cea-4d6b-b140-d6630b684a58/people/6faf92f6-f3d3-4e0e-b633-48a45df383db/raf_scores', headers: {'Authorization' => <auth_header>})

puts JSON.pretty_generate(response.to_h)

For Tammy Butler with person ID (faf92f6-f3d3-4e0e-b633-48a45df383db), how many types of RAF scores are present?

Hint Need to use the RAF_SCORE API: “GET /populations/{population_id}/people/{person_id}/raf_scores” to retrieve Raf scores of a person.

Click here for the answer 4

Exercise 4

response = HTTParty.get('https://cernerdemo.programs.healtheintent.com/api/populations/1424e81d-8cea-4d6b-b140-d6630b684a58/people/6faf92f6-f3d3-4e0e-b633-48a45df383db/raf_scores', headers: {'Authorization' => <auth_header>})

puts JSON.pretty_generate(response.to_h)

For the person ID faf92f6-f3d3-4e0e-b633-48a45df383db, what is the Potential RAF score value?

Click here for the answer 0.322

Consumer Portal

Creating a Pagelet for the Consumer Portal

Prerequisites

Exercise 1 - Create pagelet HTML

Update the pagelet’s <html> tag to have a hidden attribute.

<html hidden lang="en-us">

Include SDK inside the pagelet’s <head> tag

<script src="https://d3rc9bvtvjyh73.cloudfront.net/healthelife-sdk/healthelife_sdk.js"></script>

Initialize SDK with wildcard ACL for simplicity. It belongs inside the <body> tag.

<script type="text/javascript">
  $HL.App.init({ acls: ['*'] })
</script>

Add CSS to HTML for pagelet loading and embedding to the <style> tag at the top of the document.

/* Hide pagelet until loaded by trusted page */
html[hidden] {
  display: none;
  visibility: hidden;
}

/* Prevent bars and clipping. */
html, body {
  overflow: hidden;
  margin: 0px;
  padding: 0px;
}

/* Allow proper sizing of pagelets in sdk, even if they have float components */
body:after {
  content: "";
  display: block;
  height: 0;
  clear: both;
}

A pagelet is a web page embedded into the Consumer Portal. It needs to be deployed and available to your users on the internet. For simplicity of this exercise, we will be using GitHub’s Pages functionality that provides an easy way to host web pages. You create an HTML file in a GitHub project and Github will host the file at a dedicated URL. In a real pagelet, you would deploy your pagelet to your own servers and manage them that way.

NOTE: GitHub Pages sites have a limit of 10 builds per hour. If your page isn’t updating, this could be the reason.

  1. Fork chc2018-pagelet-exercise project on Github
  2. Navigate to https://<your-gh-username>.github.io/chc2018-pagelet-exercise to verify pagelet exists
  3. Update the index.html file in the project using the Github UI. NOTE: The code changes appear to the right in this documentation.
    • Click the pencil icon to enter Edit mode
    • Update the pagelet’s <h1> tag to contain your name
    • Update the pagelet’s <html> tag to have a hidden attribute.
      • This is done so that the contents do not appear until the pagelet authorizes the Consumer Portal is in its ACL list.
    • Include SDK inside the pagelet’s <head> tag
    • Initialize SDK with wildcard ACL for simplicity. It belongs inside the <body> tag.
    • Add CSS to HTML for pagelet loading and embedding to the <style> tag at the top of the document.
    • Click the “Commit changes” button
  4. Navigate to https://<your-gh-username>.github.io/chc2018-pagelet-exercise to verify changes have been applied. You should see your name on the page now.

Exercise 2 - Display pagelet in portal

Your new pagelet is now ready for display in the Consumer Portal. Currently, the only way to display your pagelet is to work with your Cerner support team to update your portal configuration. We will eventually have a way for you as an administrator to configure the Consumer Portal to display the pagelet. For the purposes of this exercise, we have created a workaround for you to display your pagelet in the Consumer Portal without updating any configuration. Follow the steps below to display the pagelet.

  1. Using the Consumer Portal URL and credentials given to you in the prerequisites, login to the Consumer Portal.
  2. You should see a page that allows you to enter a URL and display your pagelet in the portal.
  3. Enter your pagelet URL (https://<your-gh-username>.github.io/chc2018-pagelet-exercise) in the text box
  4. Click the “Open Pagelet” button
  5. Your pagelet should now appear on the page.

Exercise 3 - Scroll into view

Let’s explore some more functionality that the HealtheLife SDK provides for pagelets. Sometimes a pagelet is quite long and there are actions in the pagelet that require the user to jump back to the top of the pagelet. The SDK provides a scrollIntoView() method for this. This exercise will show you how to use this functionality.

  1. Go back to your Consumer Portal URL used in the previous exercise to open your pagelet.
  2. Enter this pagelet URL from your GitHub Pages - https://<your-gh-username>.github.io/chc2018-pagelet-exercise/scrollIntoView and click the “Open Pagelet” button.
  3. At the very bottom of the page is a “Scroll to Top” button. It currently does nothing if you click it. We will change the click behavior so that it will scroll the pagelet back to top of the iFrame.
  4. Edit the scrollIntoView.html file in your GitHub repo using the UI.
  5. Modify the button to have an “onclick” handler as follows:
<button class="btn" onclick="$HL.App.scrollIntoView()">Scroll to Top</button>
  1. Commit your changes to the file.
  2. Repeat steps 1 - 2
  3. Scroll down and click the “Scroll to Top” button. It should take you back to the top of pagelet.

Exercise 4 - Navigate to new route

Another thing a pagelet may want to do is route the user to another page in the portal. The SDK provides a routeTo() method for this. This exercise will show you how to use this functionality. We will take the pagelet created in exercise 1 and enhance it to route you to the dashboard of the Consumer Portal.

<button class="btn" onclick="$HL.App.routeTo({path: '/pages/home'})">Go to Dashboard</button>

Data Syndication

Data syndication facilitates the bulk delivery of HealtheIntent data. It provides direct, low-level, asynchronous access to the information that HealtheIntent solutions create, curate, and operate against. This API is used mainly to populate a data warehouse or other third-party data store for research, reporting, or analytical activities.

The Data Syndication API docs can be found here.

Terminology

Term Definition
Feed types The types of available data sets, for example, Longitudinal Record.
Feeds The set of data that you want to receive on a schedule, for example, Longitudinal Record for population ABC.
Bundles The output of a feed, for example, Changes to the Longitudinal Record for population ABC between 2018-04-01 and 2018-04-02.
Channel Types The ways you can have bundles delivered. Currently, the only supported mechanism is download, which makes the data available as archive files you can download using this API. Support for other mechanisms is planned.
Channels Specifies that you want to receive a feed’s bundles using a particular channel type and provides any necessary configuration for the channel type. For example, a channel could specify that you want to receive your Longitudinal Record for Population ABC feed using the download channel type.
Deliveries The status of delivering a particular bundle using a particular channel. For example, you would use the Deliveries endpoint to determine whether the archive file for changes to the Longitudinal Record for population ABC between 2018-04-01 and 2018-04-02 bundle is available for you to download.

To help understand these concepts, consider an analogy to the delivery of physical products. Suppose you want to have a newspaper, the Cerner Post, delivered to you by the postal service every day, but that you are only interested in the classifieds section. In this example:

Find New Bundle

For this series of exercises, we will check for and then download the newest bundle in our feed.

Exercise 1

response = HTTParty.get('https://cernerdemo.api.us.healtheintent.com/syndication/v1/feeds/', headers: {'Accept' => 'application/json', 'Authorization' => <auth_header>})

puts JSON.pretty_generate(response.to_h)

Normally, your Feed ID and Channel ID will be given to you when they are set up. But for now, let’s pretend that they were not. You can use the /feeds endpoint to search for the feeds associated with your tenant. Find the Feed ID for the Longitudinal Record, Cerner Demo Population feed.

Click here for the answer The Longitudinal Record feed for the Cernerdemo tenant is: a7d5f3cc-ff2c-44cb-a95e-23a08510d469

Exercise 2

response = HTTParty.get('https://cernerdemo.api.us.healtheintent.com/syndication/v1/channels?feedId=a7d5f3cc-ff2c-44cb-a95e-23a08510d469', headers: {'Accept' => 'application/json', 'Authorization' => <auth_header>})

puts JSON.pretty_generate(response.to_h)

Again, normally you would be given your Channel ID, but for fun, let’s use the API to find it instead. You can use the /channels endpoint to find channels.

Click here for a hint.You can filter the channels by feedId, which we have from Exercise 1.

Click here for the answer.Channel ID: 57e55d2e-3865-4f82-9f6b-f4f58d430338

Exercise 3

response = HTTParty.get('https://cernerdemo.api.us.healtheintent.com/syndication/v1/feeds/a7d5f3cc-ff2c-44cb-a95e-23a08510d469/bundles', headers: {'Accept' => 'application/json', 'Authorization' => <auth_header>})

puts JSON.pretty_generate(response.to_h)

Now that we have the Feed ID and the Channel ID, the next thing we’ll need to do is find the most recent bundle.

Click here for the answer As of 10/7/18, BundleID 54486dfb-824f-47be-be6b-d0d159c9892f is the latest.

Find Delivery ID

Now that we know the latest bundle, we need to find the Delivery ID, as that is what will be used to download the bundle.

Exercise 4

response = HTTParty.get('https://cernerdemo.api.us.healtheintent.com/syndication/v1/channels/57e55d2e-3865-4f82-9f6b-f4f58d430338/deliveries?bundleReleasedAfter=2018-10-06T00:00:00.000Z', headers: {'Accept' => 'application/json', 'Authorization' => <auth_header>})

puts JSON.pretty_generate(response.to_h)

What is the latest delivery as of 10/7/18?

Click here for the answer.Latest Delivery as of 10/7/18: 1bd910a9-9e5c-4eba-90e4-b6aabd5b9242

Download Delivery

With the Delivery ID, we will be able to download the latest bundle.

response = HTTParty.get('https://cernerdemo.api.us.healtheintent.com/syndication/v1/downloads/86a339c3-bb6b-4c4b-b8e4-b66aa42f5f64', headers: {'Accept' => 'application/octet-stream', 'Authorization' => <auth_header>})

File.binwrite('bundle.tar.gz', response.body)

Note: Given the nature of the Data Syndication API, the bundles can be quite large (10’s or 100’s of gigabytes). Therefore, we ask that you do NOT actually download the bundles over the wifi for bandwidth’s sake.