NAV
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

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.

All APIs discussed in this workshop use the legacy URI structure, which is:

https://{tenant}.{solution}.healtheintent.com/api

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

https://cernerdemo.{solution}.healtheintent.com/api

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>

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 given (available in the slide deck PDF) bearer token.

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

Make the following API call using curl to confirm the authorization header is correct:

curl -H 'Authorization: \<auth_header\>' https://cernerdemo.record.healtheintent.com/api/populations/1424e81d-8cea-4d6b-b140-d6630b684a58/people

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 HealtheRecord, HealtheRegistries and HCC APIs.

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:

HealtheRecord

The Cerner longitudinal record, HealtheRecord, is designed to provide an organized, coherent representation of the aggregated clinical data for a member. We will use HealtheRecord to demonstrate how to use the APIs.

Detailed API documentation for HealtheRecord can be found here.

We will be using the httparty gem as our ruby HTTP client for the examples in this workshop.

This API is used for searching among the people in a population. You can also refine your search using query parameters.

Person Search API: GET /api/populations/{population_id}/people

We will be using the following population ID for all our exercises: 1424e81d-8cea-4d6b-b140-d6630b684a58

Exercise 2

query_parameters = {
  'date_of_birth' => '1972-01-22',
  'q' => 'butler'
}

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

puts JSON.pretty_generate(response.to_h)

We need to find the person ID for Tammy Butler, whose birth date is 1972-01-22. You will need to use the Authorization header created in the previous exercise.

The unformatted response object is hard to read, so let’s make it look pretty by using pretty_generate (after converting the HTTParty response to a hash).

Click here for the answer Person ID for Tammy Butler is 6faf92f6-f3d3-4e0e-b633-48a45df383db

Person Demographics

We just found the person_id for Tammy Butler. Now let’s learn a little more about her using the Person Demographics API.

Person Demographics API: GET /api/populations/{population_id}/people/{person_id}

Exercise 3

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

puts JSON.pretty_generate(response.to_h)

Find out Tammy Butler’s insurance plan names and how long has she been on each plan.

Click here for the answer Her first plan name is Healthe and she has been on the plan since 2015-09-06. Her second plan is HealtheYou and she has been on the plan since 2014-01-01.

Medications

Time to check out the medications currently prescribed to Tammy.

Medication Groups API: GET /api/populations/{population_id}/people/{person_id}/medication_groups

Exercise 4

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

puts JSON.pretty_generate(response.to_h)

Find out all the medications that Tammy has been prescribed. How many medications has she been prescribed?

Click here for the answer 16

Allergies

Before we prescribe any new medications to Tammy, let’s check out what she is allergic to.

Allergen Groups API: GET /api/populations/{population_id}/people/{person_id}/allergen_groups

Exercise 5

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

puts JSON.pretty_generate(response.to_h)

Find out if Tammy is allergic to anything.

Click here for the answer Tammy is allergic to nuts and penicillin.

Conditions

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

Condition Groups API: GET /api/populations/{population_id}/people/{person_id}/condition_groups

Exercise 6

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

puts JSON.pretty_generate(response.to_h)

Take a look at all the conditions Tammy has. How many conditions does she have?

Click here for the answer She has 18 conditions.

Procedures

Let’s check out all the procedures we know about for Tammy. The Procedure Groups API consolidates procedures for easier viewing.

Procedure Groups API: GET /api/populations/{population_id}/people/{person_id}/procedure_groups

Exercise 7

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

puts JSON.pretty_generate(response.to_h)

Find out all the procedures Tammy has undergone.

Click here for the answer Tammy has undergone 7 procedures: ‘Pap Test’, ‘Retinal Eye Exam’, ‘Abdomen Ultrasound’, ‘Foot Exam’, and ‘Laparoscopy’, ‘Anorectal myomectomy’, and ‘Urine pregnancy test, by visual color comparison methods’.

Bonus Questions

Exercise 8

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

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

puts JSON.pretty_generate(response.to_h)

Find out what dates Tammy was vaccinated against polio.

Hint You will need to call “/api/populations/{population_id}/people/{person_id}/vaccine_groups” first to figure out the “vaccine_group_id” for polio.

Click here for the answer The answer is ‘2009-01-05’ and ‘2010-04-12’.

Exercise 9

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

Find out the total number of healthcare providers for Tammy.

Hint You will have to use the provider_relationships API.

Click here for the answer The answer is 20.

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

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 10

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.

Using Tammy Butler’s person_id from the previous exercise fetch her registry. What is the MARA score for Tammy?

Click here for the answer The MARA score is 0.0

Exercise 11

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 12

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 13

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 14

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 15

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 16

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 6 respectively.

Hierarchical Condition Categories (HCC)

HCC

Hierarchical Condition Categories (HCCs) are used by Medicare Advantage (MA) plans for reimbursement. The HCC API let’s 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

Exercise 17

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. Lets 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 18

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 19

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 20

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

Platform APIs

Since the release of the original (Legacy) APIs, HealtheIntent has commited to a more rich API platform. All new platform APIs will have new features such as common versioning and error handling. Authorizaion and authentication will be the same.

URI Structure

The URI structure for platform APIs is different than that of the legacy APIs. The new URI structure is:

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

As before, we will use cerenrdemo as the tenant. Additionally, all APIs are on version 1, so v1 will be the version identifier.

Exercise 21

response = HTTParty.get('https://cernerdemo.api.us-1.healtheintent.com/patient/v1/populations/1424e81d-8cea-4d6b-b140-d6630b684a58/patient-id-lookup?dataPartitionId=877307a0-b5f5-4a01-9d4b-9fead6bcf788&sourcePersonId=134358', headers: {'Accept' => 'application/json', 'Authorization' => <auth_header>})

puts JSON.pretty_generate(response.to_h)

The Patient ID Lookup endpoint allows you to retrieve a list of HealtheIntent patient IDs using a local source person ID and data partition ID. Because HealtheIntent collects data from many different sources, the HealtheIntent patient ID is used to identify patients and consolidate their information within HealtheIntent. Retrieving the HealtheIntent patient ID is the first step to sending many requests to the HealtheIntent APIs. Let’s give it a try.

Given a data partition ID of 877307a0-b5f5-4a01-9d4b-9fead6bcf788, and a local ID of 134358, what is the HealtheIntent patient ID?

Click here for the answer The patient ID is 2f23d5ec-bf22-470e-a122-1a6a2dd67af6

Exercise 22

response = HTTParty.get('https://cernerdemo.record.healtheintent.com/api/populations/1424e81d-8cea-4d6b-b140-d6630b684a58/people/2f23d5ec-bf22-470e-a122-1a6a2dd67af6', headers: {'Accept' => 'application/json', 'Authorization' => <auth_header>})

puts JSON.pretty_generate(response.to_h)

Using the ID from Exercise 21, what is the name of our patient?

Hint Trick question! Go back and use the legacy HealtheRecord API.

Click here for the answer The patient’s name is Sam Adams

Now that you have the patient ID for Sam, use it to explore some of the other platform APIs. Use the Allergy API to find his allergies, or the Immunization API to see if he’s had his flu shot for the year.