NAV
code

Overview

This specification describes a “hook”-based pattern for invoking decision support from within a clinician’s EHR workflow. The API supports:

How it works

User activity inside the EHR triggers CDS hooks in real-time. For example:

When a triggering activity occurs, the EHR notifies each CDS service registered for the activity. These services must then provide near-real-time feedback about the triggering event. Each service gets basic details about the EHR context (via the context parameter of the hook) plus whatever service-specific data are required (via the pre-fetch-template parameter).

CDS Hooks Overview

CDS Cards

Each CDS service can return any number of cards in response to the hook. Cards convey some combination of text (information card), alternative suggestions (suggestion card), and links to apps or reference materials (app link card). A user sees these cards — one or more of each type — embedded in the EHR, and can interact with them as follows:

CDS Decisions

In addition to cards, a CDS service may also return decisions — but only after a user has interacted with the service via an app link card. Returning a decision allows the the CDS service to communicate the user’s choices to the EHR without displaying an additional card. For example, a user might launch a hypertension management app, and upon returning to the EHR’s prescription page she expects her new blood pressure prescription to “just be there”. By returning a decision instead of a card, the CDS service achieves this expected behavior. (Note: To return a decision after a user interaction, the CDS service must maintain state associated with the request’s hookInstance; when the EHR invokes the hook for a second time with the same hookInstance, the service can respond with decisions on as well as cards.)

Try it!

You can try CDS Hooks in our test harness at http://sandbox.cds-hooks.org

CDS Services

Discovery

curl "https://example.com/cds-services"

The above command returns JSON structured like this:

{
  "services": [
    {
      "hook": "patient-view",
      "title": "Static CDS Service Example",
      "description": "An example of a CDS service that returns a static set of cards",
      "id": "static-patient-greeter",
      "prefetch": {
        "patientToGreet": "Patient/{{Patient.id}}"
      }
    },
    {
      "hook": "medication-prescribe",
      "title": "Medication Echo CDS Service",
      "description": "An example of a CDS service that simply echos the medication being prescribed",
      "id": "medication-echo",
      "prefetch": {
        "patient": "Patient/{{Patient.id}}",
        "medications": "MedicationOrder?patient={{Patient.id}}"
      }
    }
  ]
}

Developers of CDS Services must provide a well-known endpoint allowing the EHR to discover all available CDS Services, including information such as the purpose of the CDS Service, when it should be invoked, and any data that is requested to be prefetched.

HTTP Request

The discovery endpoint is always available at {baseUrl}/cds-services. For example, if the baseUrl is https://example.com, the EHR would invoke:

GET https://example.com/cds-services

Response

The response to the discovery endpoint is an object containing a list of CDS Services.

Field Description
services array. An array of CDS Services

Each CDS Service is described by the following attributes.

Field Description
hook string or url. The hook this service should be invoked on. See Hook Catalog
title string. The human-friendly name of this service
description string. The description of this service
id string. The {id} portion of the URL to this service which is available at
{baseUrl}/cds-services/{id}
prefetch object. An object containing key/value pairs of FHIR queries to data that this service would like the EHR prefetch and provide on
each service call. The key is a string that describes the type
of data being requested and the value is a string representing
the FHIR query.
(todo: link to prefetching documentation)

HTTP Status Codes

Code Description
200 OK A successful response

Calling a CDS Service

curl
  -X POST \
  -H 'Content-type: application/json' \
  --data @hook-details-see-example-below
  "https://example.com/cds-services/static-patient-greeter"
{
   "hookInstance" : "d1577c69-dfbe-44ad-ba6d-3e05e953b2ea",
   "fhirServer" : "http://hooks.smarthealthit.org:9080",
   "hook" : "patient-view",
   "redirect" : "http://hooks2.smarthealthit.org/service-done.html",
   "user" : "Practitioner/example",
   "context" : [],
   "patient" : "1288992",
   "prefetch" : {
      "patientToGreet" : {
         "response" : {
            "status" : "200 OK"
         },
         "resource" : {
            "resourceType" : "Patient",
            "gender" : "male",
            "birthDate" : "1925-12-23",
            "id" : "1288992",
            "active" : true
         }
      }
   }
}

HTTP Request

An EHR calls a CDS service by POSTing a JSON document to the service endpoint, which can be constructed from the CDS Service base URL and an individual service id as {baseUrl}/cds-services/{service.id}. The CDS Hook call includes a JSON POST body with the following input fields:

Field Description
hook string or URL. The hook that triggered this CDS Service call
(todo: link to hook documentation)
hookInstance string. A UUID for this particular hook call (see more information below)
fhirServer URL. The base URL EHR’s FHIR server. The scheme should be https
oauth object. The OAuth2 authorization providing access to the EHR’s FHIR server (see more information below)
redirect URL. The URL an app link card should redirect to (see more information below)
user string. The FHIR resource type + id representing the current user.
The type is one of: Practitioner, Patient, or RelatedPerson.
For example, Practitioner/123
patient string. The FHIR Patient.id of the current patient in context
encounter string. The FHIR Encounter.id of the current encounter in context
context object. Hook-specific contextual data that the CDS service will need.
For example, with the medication-prescribe hook this will include MedicationOrder being prescribed.
prefetch object. The FHIR data that was prefetched by the EHR (see more information below)

hookInstance

While working in the EHR, a user can perform multiple activities in series or in parallel. For example, a clinician might prescribe two drugs in a row; each prescription activity would be assigned a unique hookInstance. The [[activity catalog|Activity]] provides a description of what events should initiate and terminate a given hook. This allows an external service to associate requests with activity state, which is necessary to support the following app-centric decision sequence, where the steps are tied together by a common hookInstance:

  1. EHR invokes CDS hook
  2. CDS service returns app link card
  3. User clicks app link and interacts with app
  4. Flow returns to EHR, which re-invokes CDS hook
  5. CDS service returns decision with user’s choice

Note: the hookInstance is globally unique and should contain enough entropy to be un-guessable.

oauth

Security details allowing the CDS service to connect to the EHR’s FHIR server. These fields allow the CDS service to access EHR data in a context limited by the current user’s privileges. expires expresses the token lifetime as an integer number of seconds. scope represents the set of scopes assigned to this token (see SMART on FHIR scopes). Finally, token is a bearer token to be presented with any API calls the CDS service makes to the EHR, by including it in an Authorization header like:

Authorization: Bearer {{token}}

redirect

This field is only used by services that will return an app link card: when a user clicks the card’s link to launch an app, it becomes the app’s job to send the user to this redirect URL upon completion of user interaction. (Design note: this field is supplied up-front, as part of the initial request, to avoid requiring the EHR to append any content to app launch links. This helps support an important “degenerate” use case for app link cards: pointing to static content. See below for details.)

prefetch

As a performance tweak, the EHR may pass along data according to the service’s [[Prefetch-Template]]. This helps provide the service with all the data it needs to efficiently compute a set of recommendations. Each key matches a key described in the CDS Service Discovery document; and each value is a FHIR Bundle.entry indicating a response status and returned resource.

Note that in the absence of prefetch, an external service can always execute FHIR REST API calls against the EHR server to obtain additional data ad-hoc.)

CDS Service Response

Example response

{
  "cards": [
    {
      "summary": "Example Card",
      "indicator": "info",
      "detail": "This is an example card.",
      "source": {
        "label": "Static CDS Service Example",
        "url": "https://example.com",
        "icon": "https://example.com/img/icon-100px.png"
      },
      "links": [
        {
          "label": "Google",
          "url": "https://google.com",
          "type": "absolute"
        },
        {
          "label": "Github",
          "url": "https://github.com",
          "type": "absolute"
        },
        {
          "label": "SMART Example App",
          "url": "https://smart.example.com/launch",
          "type": "smart"
        }
      ]
    },
    {
      "summary": "Another card",
      "indicator": "warning",
      "source": {
        "label": "Static CDS Service Example"
      }
    }
  ]
}
Field Description
cards array. An array of Cards. Cards can provide a combination of information (for reading), suggested actions (to be applied if a user selects them), and links (to launch an app if the user selects them). The EHR decides how to display cards, but we recommend displaying suggestions using buttons, and links using underlined text.
decisions array. An array of Decisions. A decision should only be generated after interacting with the user through an app link. Decisions are designed to convey any choices the user made in an app session.

represents a user’s choice made while interacting with the CDS Provider’s external app. The first call to a service should never include any decisions, since no user interaction has occurred yet.

Each Card is described by the following attributes.

Field Description
summary string. one-sentence, <140-character summary message for display to the user inside of this card.
detail string. optional detailed information to display, represented in (GitHub Flavored) Markdown. (For non-urgent cards, the EHR may hide these details until the user clicks a link like “view more details…”.)
indicator string. urgency/importance of what this card conveys. Allowed values, in order of increasing urgency, are: info, warning, hard-stop. The EHR can use this field to help make UI display decisions such as sort order or coloring. The value hard-stop indicates that the workflow should not be allowed to proceed.
source object. grouping structure for the Source of the information displayed on this card. The source should be the primary source of guidance for the decision support the card represents.
suggestions array of Suggestions, which allow a service to suggest a set of changes in the context of the current activity (e.g. changing the dose of the medication currently being prescribed, for the medication-prescribe activity). Note that suggestions are implicitly OR’d.
links array of Links, which allow a service to suggest a link to an app that the user might want to run for additional information or to help guide a decision.

The Source is described by the following attributes.

Field Description
label string. A short, human-readable label to display for the source of the information displayed on this card. If a url is also specified, this may be the text for the hyperlink.
url URL. An optional absolute URL to load (via GET, in a browser context) when a user clicks on this link to learn more about the organization or data set that provided the information on this card. Note that this URL should not be used to supply a context-specific “drill-down” view of the information on this card. For that, use link.url instead.
icon URL. An optional absolute URL to an icon for the source of this card. The icon returned by this URL should be in PNG format, an image size of 100x100 pixels, and must not include any transparent regions.

Each Suggestion is described by the following attributes.

Field Description
label string. human-readable label to display for this suggestion (e.g. the EHR might render this as the text on a button tied to this suggestion).
uuid string. unique identifier for this suggestion. For details see Suggestion Tracking Analytics
actions array. array of objects, each defining a suggested action. Within a suggestion, all actions are logically AND’d together, such that a user selecting a suggestion selects all of the actions within it.

Each Action is described by the following attributes.

Field Description
type string. The type of action being performed. Allowed values are: create, update, delete.
description string. human-readable description of the suggested action. May be presented to the end-user.
resource object. depending upon the type attribute, new resource(s) or id(s) of resources. For a type of create, the resource attribute contains new FHIR resources to apply within the current activity (e.g. for medication-prescribe, this holds the updated prescription as proposed by the suggestion). For delete, id(s) of any resources to remove from the current activity (e.g. for the order-review activity, this would provide a way to remove orders from the pending list). In activities like medication-prescribe where only one “content” resource is ever relevant, this field may be omitted. For update, existing resources to modify from the current activity (e.g. for the order-review activity, this would provide a way to annotate an order from the pending list with an assessment). This field may be omitted.

Each Link is described by the following attributes.

Field Description
label string. human-readable label to display for this link (e.g. the EHR might render this as the underlined text of a clickable link).
url URL. URL to load (via GET, in a browser context) when a user clicks on this link. Note that this may be a “deep link” with context embedded in path segments, query parameters, or a hash. In general this URL should embed enough context for the app to determine the hookInstance, and redirect url upon downstream launch, because the EHR will simply use this url as-is, without appending any parameters at launch time.
type string. The type of the given URL. There are two possible values for this field. A type of absolute indicates that the URL is absolute and should be treated as-is. A type of smart indicates that the URL is a SMART app launch URL and the EHR should ensure the SMART app launch URL is populated with the appropriate SMART launch parameters.

Each Decision is described by the following attributes.

Field Description
create array of strings. id(s) of new resource(s) that the EHR should create within the current activity (e.g. for medication-prescribe, this would be the updated prescription that a user had authored in an app session).
delete array of strings. id(s) of any resources to remove from the current activity (e.g. for the order-review activity, this would provide a way to remove orders from the pending list). In activities like medication-prescribe where only one “content” resource is ever relevant, this field may be omitted.

No Decision Support

Response when no decision support is necessary for the user

{
  "cards": []
}

If your CDS Service has no decision support for the user, your service should return a 200 HTTP response with an empty array of cards.

Analytics

Whenever a user clicks a button from a “suggestion” card, the EHR uses the suggestion uuid to notify the CDS Service’s analytics endpoint via a POST with an empty body:

POST {baseUrl}/cds-services/{serviceId}/analytics/{uuid}

If a suggestion has no uuid, the EHR does not send a notification.

Prefetch

A performance tweak

If real-world performance were no issue, an EHR could launch a CDS Service passing only context data, and without passing any additional clinical data up-front. The CDS Service could then request any data it needed via the EHR’s FHIR REST API.

But CDS services must respond quickly (on the order of 500 ms), and so we provide a performance tweak that allows a CDS Service to register a set of “prefetch templates” with the EHR ahead of time.

The prefetch templates are a dictionary of read and search requests to supply relevant data, where the following variables are defined:

variable meaning
{{Patient.id}} The id of the patient in context for this activity (e.g. 123)
{{User.id}} The type and id of the user for this session (e.g. Practitioner/123)

An EHR may choose to honor some or all of the desired prefetch templates from an appropriate source. For example:

Regardless of how the EHR satisfies the prefetched templates (if at all), it is important that the prefetched data given to the CDS Service is equivalent to the CDS Service making its own call to the EHR FHIR server, where {{Patient.id}} is replaced with the id of the current patient (e.g. 123) inside of any URL strings and using read and search operations to the server’s “transaction” endpoint as a FHIR batch-type bundle.

The resulting response, which must be rendered in a single page — no “next page” links allowed — is passed along to the CDS Service using the prefetch parameter (see below for a complete example).

The CDS Service must not receive any prefetch template key that the EHR chooses not to satisfy. Additionally, if the EHR encounters an error while retrieving any prefetched data, the prefetch template key should not be sent to the CDS Service. It is the CDS Service’s responsibility to check to see what prefetched data was satisfied (if any) and manually retrieve any necessary data.

Example prefetch request

{
  "prefetch": {
    "p": "Patient/{{Patient.id}}",
    "a1c": "Observation?patient={{Patient.id}}&code=4548-4&_count=1&sort:desc=date",
    "u": "Practitioner/{{User.id}}"
  }
}

Here is an example prefetch property from a CDS service discovery endpoint. The goal is to know, at call time:

Key Description
p Patient demographics
a1c Most recent Hemoglobin A1c reading for this patient
u Information on the current user (Practitioner)

Example prefetch response

{
  "prefetch": {
    "p":{
      "response": {
        "status": "200 OK"
      },
      "resource": {
        "resourceType": "Patient",
        "gender": "male",
        "birthDate": "1974-12-25",
        "...": "<snipped for brevity>"
      }
    },
    "a1c": {
      "response": {
        "status": "200 OK"
      },
      "resource":{
        "resourceType": "Bundle",
        "type": "searchset",
        "entry": [{
          "resource": {
            "resourceType": "Observation",
            "code": {
              "coding": [{
                "system": "http://loinc.org",
                "code": "4548-4",
                "display": "Hemoglobin A1c"
              }]
            },
            "...": "<snipped for brevity>"
          }
        }]
      }
    }
  }
}

The response is augmented to include two prefetch values, where the dictionary keys match the request keys (p and a1c in this case).

Note that the missing u key indicates that either the EHR has decided not to satisfy this particular prefetch template or it was not able to retrieve this prefetched data. The CDS Service is responsible for retrieving this Practitioner data from the FHIR server (if required).

Prefetch query restrictions

To reduce the implementation burden on EHRs that support CDS services, CDS Hooks recommends that prefetch queries only use a subset of the full functionality available in the FHIR specification. Valid prefetch URLs should only contain:

Security

CDS Hooks defines the agreed upon security model between an EHR and the CDS Service. Like SMART on FHIR, the security model of CDS Hooks leverages the same open and well supported standards like OAuth 2 and JSON web tokens. However, as CDS Hooks differs from SMART, the manny in which these standards are used is specific to CDS Hooks.

Trusting CDS Services

As the EHR initiates every interaction with the CDS Service, it is responsible for establishing trust with the CDS Services it intends to call. This trust is established via a TLS connection to the CDS Service. Thus, all CDS Service endpoints must be deployed to a TLS protected URL (https). This includes both the Discovery and individual CDS Service endpoints.

EHRs should use accepted best practices for verifying the authenticity and trust of these TLS connections. For instance, rfc5280 and rfc6125. Additionally, it is assumed that EHRs configure the CDS Services they connect to via some offline process according to the business rules and practices of both the EHR and CDS Service organizations.

Trusting EHRs

Since the CDS Service is invoked by the EHR, the CDS Service does not have the same mechanism as EHRs to establish trust of the EHR invoking it. To establish trust of the EHR, JSON web tokens (JWT) are used. Specifically, the JWT is the same id_token used in SMART on FHIR.

Each time the EHR makes a request to the CDS Service, it should send an Authorization header where the value is Bearer <token>, replacing <token> with the actual JWT. Note that this is for every single CDS Service call, whether that be Discovery calls, CDS Service invocations, etc.

Example JSON web token payload

{
  "iss": "https://fhir-ehr.example.com/",
  "sub": "some-username",
  "aud": "44b16507-8a59-4369-96f9-1e9b1f9a0ace",
  "exp": 1422568860,
  "iat": 1311280970
}

Using the above JWT payload, the complete JWT as passed in the Authorization HTTP header would be:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2ZoaXItZWhyLmV4YW1wbGUuY29tLyIsImF1ZCI6Imh0dHBzOi8vY2RzLmV4YW1wbGUub3JnL2Nkcy1zZXJ2aWNlcyIsImV4cCI6MTQyMjU2ODg2MCwianRpIjoiMmFmNWU4YTUtYjVlZi00ZmQwLThkOTMtYzU2MGRhYzQwYzk4In0.ahR57rtcMFhvrHEEo9w13vVdLrhZs_gRY2NV6R2GAoU

The JWT from the EHR is signed with the EHR’s private key and contains the following fields:

Field Value
iss The base URL of the EHR’s FHIR server. This must be the same URL as the fhirServer field in a CDS Service request.
sub The unique identifer for the current user
aud The OAuth 2 client id of the CDS Service
exp Expiration time integer for this authentication JWT, expressed in seconds since the “Epoch” (1970-01-01T00:00:00Z UTC).
iat The time at which this JWT was issued, expressed in seconds since the “Epoch” (1970-01-01T00:00:00Z UTC).

Note that the use of JWT in CDS Hooks resembles the SMART on FHIR Backend Services usage of JWT. However, there are differences due to the differing use cases and concerns between CDS Hooks and SMART Backend Services.

https://jwt.io/ is a great resource not only for learning about JSON web tokens, but also for parsing a JWT value into its distinct parts to see how it is constructed. Try taking the example JWT here and pasting it into the form at https://jwt.io/ to see how the token is constructed.

Mutual TLS

Mutual TLS (mTLS) can be used between an EHR and CDS Service and that would allow the CDS Service to establish trust of the EHR. However, if mTLS is used, this should be in addition to using JSON web tokens to establish trust of the EHR. As mTLS is not well supported across all platforms and technologies, it is not the standard means of establishing trust with the EHR.

FHIR Resource Access

The CDS Service is able to use the FHIR server of the EHR to obtain any additional data it needs in order to perform its decision support. This is similar to SMART on FHIR where the SMART app can obtain additional data via the provided FHIR server.

Like SMART on FHIR, CDS Hooks requires that access to the FHIR server be controlled by an Authorization server utilizing the OAuth 2 framework. Thus, the CDS Service is able to consume the given FHIR server via an access (bearer) token just like a SMART app. While CDS Hooks shares the underlying technical framework and standards as SMART on FHIR, there are very important differences between SMART and CDS Hooks.

Obtaining an Access Token

In SMART on FHIR, the SMART app requests and ultimately obtains an access token from the Authorization server using the SMART launch workflow. This process utilizes the authorization code grant model as defined by the OAuth 2.0 Authorization Framework in rfc6749.

With CDS Hooks, the EHR provides the access token directly in the request to the CDS Service. Thus, the CDS Service does not need to request the token from the authorization server as a SMART app would. This is done purely for performance reasons as the authorization code grant model in OAuth 2 involves several HTTPS calls and redirects. In contrast with a SMART app, a CDS Service may be invoked many times during a workflow. Going through the authorization code grant model on every hook invocation would likely result in a slow performing CDS Service due to the authorization overhead.

{
  "fhirAuthorization" : {
    "access_token" : "some-opaque-fhir-access-token",
    "token_type" : "code",
    "expires_in" : 300,
    "scope" : "patient/Patient.read patient/Observation.read"
  }
}

Access Token

The access token is specified in the CDS Service request via the fhirAuthorization request parameter. This parameter is an object that contains both the access token as well as other related information.

Field Description
access_token string. This is the OAuth 2 access token that provides access to the FHIR server.
token_type string. Always the value code
expires_in integer. The lifetime in seconds of the access token.
scope string. The scopes the access token grants the CDS Service.

It is recommended that the expires_in value be very short lived as the access token should be treated as a transient value by the CDS Service.

It is recommended that the scope value contain just the scopes that the CDS Service needs for its logic and no more.

As the CDS Service is executing on behalf of a user, it is important that the data the CDS Service has access to is under the same restrictions/authorization as the current user. As such, the access token should be scoped to:

Frequently Asked Questions

  1. How is the user (clinician) prompted to authorize the CDS Service to obtain an access token on behalf of the user? If we’re aligning with how security works for SMART apps, this is what happens today.

Not quite. There is actually no requirement that there be any user interaction to authorize a SMART app to obtain an access token. More generally, the OAuth 2 framework does not prescribe how authorization is determined. That is, authorization may be determined via some user interruptive decision, some pre-existing business rules, or even by random chance! The authorization server is free to determine how it grants access to the resources it protects.

With SMART on FHIR, we have seen real production behavior in which the authorization server:

  1. The FHIR access token model places quite a bit of work on the EHRs. Why?

Yes, requiring the EHRs to obtain and share the access token with each CDS Service on each hook invocation isn’t trivial work. However, the need to control the performance of the CDS Service invocations necessitates a different approach than SMART on FHIR. By putting the burden on the EHRs to obtain this access token, it is left to the EHR to manage this cost appropriately. Given the authorization server and EHR are controlled by the same organization, it is assumed the EHR is in a much better position to implement strategies to both obtain and manage access tokens in a performant manner in a model like CDS Hooks.

Unlike SMART apps, CDS Services should treat access tokens as transient tokens used during the course of a single evaluation of decision support. If the EHRs did not bear the responsibility of obtaining the access token on behalf of the CDS Service, each CDS Service would need to not only obtain the token themselves, but also determine a performant manner to optimize token (re)use when their service is invoked for the same user/patient.

Cross-Origin Resource Sharing

Cross-origin resource sharing (CORS) is web security mechanism that is built into browsers. In short, CORS allows servers to control how browsers access resources on the server, including the accessible HTTP response headers. CORS is only honored by web browsers and as such, is a client-side security mechanism.

For CDS Services, implementing CORS is required if your CDS Service is to be called from a web browser. As the CDS Hooks Sandbox is a browser application, you must implement CORS to test your CDS Service in the CDS Hooks Sandbox.

You should carefully consider how you support CORS, but a quick starting point for testing would be to ensure your CDS Service returns the following HTTP headers:

Header Value
Access-Control-Allow-Credentials true
Access-Control-Allow-Methods GET, POST, OPTIONS
Access-Control-Allow-Origin *
Access-Control-Expose-Headers Origin, Accept, Content-Location, Location, X-Requested-With

Hook Catalog

Pre-defined CDS hooks

We describe a set of hooks to support common use cases out of the box. But this is not a closed set; anyone can define new hooks to address new use cases. To propose a new hooks please add it to the proposed hooks page of our wiki.

Note that each hook (e.g. medication-prescribe) represents something the user is doing in the EHR; various hooks might respond to the same hook (e.g. a “price check” service and a “prior authorization” service might both respond to medication-prescribe).

Note also that each hook name in our official catalog is a simple string. If you want to define custom hooks without submitting them to the catalog, then you should use a URI (e.g. http://my-organization/custom-hooks/patient-transmogrify).

medication-prescribe

{
  "context": {
    "resourceType": "MedicationOrder",
    "medicationCodeableConcept": {
      "...": "<snipped for brevity>"
    }
  }
}

Purpose: Inform an external CDS service that the user is in the process of prescribing a new medication, and solicit feedback about the prescription-in-progress.

Contextual data: The set of proposed medication prescriptions. using the FHIR MedicationOrder resource. See example in the sidebar.

order-review

{
  "context": {
    "resourceType": "DiagnosticOrder",
    "...": "<snipped for brevity>"
  }
}

Purpose: Inform an external CDS service that the user is in the process of reviewing a set of orders (sometimes known as a “shopping cart”), and solicit feedback about the orders being reviewed.

Contextual data: The set of orders being reviewed on-screen, represented using a combination of MedicationOrder, DiagnosticOrder, DeviceUseRequest, ReferralRequest, and ProcedureRequest. See example in the sidebar.

patient-view

Purpose: Inform an external CDS service that the user has just opened a new patient record and is viewing a summary screen or “face sheet”, and solicit feedback about this patient.

Contextual data: None required beyond default context.

Community

Get Involved

There are several ways in which you can get involved with the CDS Hooks community.

CDS Hooks Sprint Program

Objectives

Want to help build our test infrastructure?

Examples

CDC Guideline for Prescribing Opioids for Chronic Pain

CDS Service Request

The example illustrates a prescription for Acetaminophen/Hydrocodone Bitartrate for a patient that already has a prescription for Oxycodone Hydrochloride:

{
  "hookInstance": "d1577c69-dfbe-44ad-ba6d-3e05e953b2ea",
  "fhirServer": "http://fhir.example.com",
  "hook": "medication-prescribe",
  "user": "Practitioner/example",
  "context": [
    {
      "resourceType": "MedicationOrder",
      "id": "medrx001",
      "dateWritten": "2017-05-05",
      "status": "draft",
      "patient": {
        "reference": "Patient/example"
      },
      "medicationCodeableConcept": {
        "coding": [
          {
            "system": "http://www.nlm.nih.gov/research/umls/rxnorm",
            "code": "857001",
            "display": "Acetaminophen 325 MG / Hydrocodone Bitartrate 10 MG Oral Tablet"
          }
        ]
      },
      "dosageInstruction": [
        {
          "text": "Take 1 tablet Oral every 4 hours as needed",
          "timing": {
            "repeat": {
              "frequency": 6,
              "frequencyMax": 6,
              "period": 1,
              "unit": "d"
            }
          },
          "asNeededBoolean": true,
          "doseQuantity": {
            "value": 10,
            "unit": "mg",
            "system": "http://unitsofmeasure.org",
            "code": "mg"
          }
        }
      ]
    }
  ],
  "patient": "Patient/example",
  "prefetch": {
    "medication": {
      "response": {
        "status": "200 OK"
      },
      "resource": {
        "resourceType": "MedicationOrder",
        "id": "medrx002",
        "dateWritten": "2017-04-25",
        "status": "active",
        "patient": {
          "reference": "Patient/example"
        },
        "medicationCodeableConcept": {
          "coding": [
            {
              "system": "http://www.nlm.nih.gov/research/umls/rxnorm",
              "code": "1049621",
              "display": "Oxycodone Hydrochloride 5 MG Oral Tablet"
            }
          ]
        },
        "dosageInstruction": [
          {
            "text": "Take 1 tablet by mouth every 4 hours as needed for pain.",
            "timing": {
              "repeat": {
                "frequency": 6,
                "period": 1,
                "periodUnits": "d"
              }
            },
            "asNeededBoolean": true,
            "doseQuantity": {
              "value": 5,
              "unit": "mg",
              "system": "http://unitsofmeasure.org",
              "code": "mg"
            }
          }
        ]
      }
    }
  }
}

This example illustrates the use of the CDS Hooks medication-prescribe hook to implement Recommendation #5 from the CDC guideline for prescribing opioids for chronic pain.

This example is taken from the Opioid Prescribing Support Implementation Guide, developed in partnership with the Centers for Disease Control and Prevention (CDC).

CDS Service Response

The opioid guideline request results in the following response that indicates the patient is at high risk for opioid overdose according to the CDC guidelines, and the dosage should be tapered to less than 50 MME. Links are provided to the guideline, as well as to the MME conversion tables provided by CDC.

{
  "summary": "High risk for opioid overdose - taper now",
  "indicator": "warning",
  "links": [
    {
      "label": "CDC guideline for prescribing opioids for chronic pain",
      "type": "absolute",
      "url": "https://guidelines.gov/summaries/summary/50153/cdc-guideline-for-prescribing-opioids-for-chronic-pain---united-states-2016#420"
    },
    {
      "label": "MME Conversion Tables",
      "type": "absolute",
      "url": "https://www.cdc.gov/drugoverdose/pdf/calculating_total_daily_dose-a.pdf"
    }
  ],
  "detail": "Total morphine milligram equivalent (MME) is 125mg. Taper to less than 50."
}

Radiology Appropriateness

CDS Service Request

This example illustrates the use of the CDS Hooks order-review hook to implement Radiology Appropriateness scoring.

{
  "hookInstance": "d1577c69-dfbe-44ad-ba6d-3e05e953b2ea",
  "fhirServer": "http://fhir.example.com",
  "hook": "order-review",
  "user": "Practitioner/example",
  "context": [
    {
      "resourceType": "ProcedureRequest",
      "id": "procedure-request-1",
      "status": "draft",
      "intent": "proposal",
      "priority": "routine",
      "code": {
        "coding": [{
          "system": "http://www.ama-assn.org/go/cpt",
          "code": "70450",
          "display": "CT, head, wo iv contrast"
        }]
      },
      "subject": {
        "reference": "Patient/example"
      },
      "requester": {
        "agent": {
          "reference": "Practitioner/exampmle"
        }
      }
    }
  ],
  "patient": "Patient/example"
}

CDS Service Response

The appropriateness score is communicated via an update of the procedure request that adds an extension element to indicate the appropriateness rating.

{
  "cards": [
    {
      "summary": "Usually appropriate",
      "indicator": "info",
      "detail": "The requested procedure is usually appropriate for the given indications.",
      "suggestions": [
        {
          "label": "The appropriateness score for this procedure given these indications is 9, usually appropriate.",
          "actions": [{
            "type": "update",
            "description": "Update the order to record the appropriateness score.",
            "resource": {
              "resourceType": "ProcedureRequest",
              "id": "procedure-request-1",
              "extension": [
                {
                  "url": "http://hl7.org/fhir/us/qicore/StructureDefinition/procedurerequest-appropriatenessScore",
                  "valueDecimal": "9"
                }
              ],
              "status": "draft",
              "intent": "proposal",
              "priority": "routine",
              "code": {
                "coding": [{
                  "system": "http://www.ama-assn.org/go/cpt",
                  "code": "70450",
                  "display": "CT, head, wo iv contrast"
                }]
              },
              "subject": {
                "reference": "Patient/example"
              },
              "requester": {
                "agent": {
                  "reference": "Practitioner/exampmle"
                }
              }
            }
          }]
        }
      ]
    }
  ]
}