CDS Hooks Architecture Design

Technical guide for implementing CDS Hooks services.


What is CDS Hooks?

CDS Hooks is an HL7 specification for integrating Clinical Decision Support (CDS) services with EHR workflows. It provides:

  • Standardised trigger points (hooks)
  • Consistent request/response format
  • EHR-agnostic architecture

Architecture Overview

┌─────────────────────────────────────────────────────────┐
│                     EHR System                          │
│                                                         │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────┐  │
│  │ Order Entry │  │  Patient    │  │  Medication     │  │
│  │    Hook     │  │  View Hook  │  │  Prescribe Hook │  │
│  └──────┬──────┘  └──────┬──────┘  └────────┬────────┘  │
└─────────┼────────────────┼──────────────────┼───────────┘
          │                │                  │
          ▼                ▼                  ▼
┌─────────────────────────────────────────────────────────┐
│                  CDS Hooks Service                       │
│                                                          │
│  ┌─────────────────────────────────────────────────┐    │
│  │              Discovery Endpoint                  │    │
│  │              GET /cds-services                   │    │
│  └─────────────────────────────────────────────────┘    │
│                                                          │
│  ┌─────────────────────────────────────────────────┐    │
│  │              Service Endpoints                   │    │
│  │     POST /cds-services/{service-id}              │    │
│  └─────────────────────────────────────────────────┘    │
│                                                          │
└─────────────────────────────────────────────────────────┘

Standard Hooks

patient-view

Triggered when a patient's record is opened.

{
  "hook": "patient-view",
  "hookInstance": "uuid",
  "context": {
    "userId": "Practitioner/123",
    "patientId": "Patient/456"
  }
}

order-select

Triggered when a clinician selects medications.

{
  "hook": "order-select",
  "hookInstance": "uuid",
  "context": {
    "userId": "Practitioner/123",
    "patientId": "Patient/456",
    "selections": ["MedicationRequest/draft-123"],
    "draftOrders": {...}
  }
}

order-sign

Triggered when signing orders.

{
  "hook": "order-sign",
  "context": {
    "draftOrders": {...}
  }
}

Service Discovery

GET /cds-services

{
  "services": [
    {
      "hook": "order-select",
      "title": "Drug Repurposing Insights",
      "description": "Shows potential new uses for selected medications",
      "id": "sgtxgnn-repurposing",
      "prefetch": {
        "patient": "Patient/",
        "medications": "MedicationRequest?patient="
      }
    }
  ]
}

Response Cards

Card Structure

{
  "cards": [
    {
      "uuid": "card-uuid",
      "summary": "Brief message",
      "detail": "Detailed explanation",
      "indicator": "info|warning|critical",
      "source": {
        "label": "SgTxGNN",
        "url": "https://sgtxgnn.yao.care"
      },
      "suggestions": [...],
      "links": [...]
    }
  ]
}

Indicator Values

Indicator Use Case
info Informational message
warning Needs attention
critical Requires action

Suggestions

{
  "suggestions": [
    {
      "label": "Review repurposing evidence",
      "uuid": "suggestion-uuid",
      "actions": [
        {
          "type": "create",
          "description": "Create task to review",
          "resource": {...}
        }
      ]
    }
  ]
}
{
  "links": [
    {
      "label": "View drug details",
      "url": "https://sgtxgnn.yao.care/drugs/db00945",
      "type": "absolute"
    },
    {
      "label": "Launch SMART app",
      "url": "https://sgtxgnn.yao.care/smart/launch.html",
      "type": "smart",
      "appContext": "drug=DB00945"
    }
  ]
}

Prefetch

Purpose

Prefetch allows the CDS service to request needed data upfront, reducing latency.

Template Syntax

{
  "prefetch": {
    "patient": "Patient/",
    "conditions": "Condition?patient=",
    "medications": "MedicationRequest?patient=&status=active"
  }
}

Handling Missing Prefetch

If EHR doesn't support prefetch, service can query FHIR server:

async function handleRequest(request) {
  const medications = request.prefetch?.medications
    || await fetchMedications(request.fhirServer, request.context.patientId);
  // Process medications...
}

Implementation Example

Node.js Service

const express = require('express');
const app = express();

// Discovery
app.get('/cds-services', (req, res) => {
  res.json({
    services: [{
      hook: 'order-select',
      id: 'sgtxgnn-repurposing',
      title: 'Drug Repurposing Insights'
    }]
  });
});

// Service endpoint
app.post('/cds-services/sgtxgnn-repurposing', (req, res) => {
  const { context, prefetch } = req.body;

  // Analyse medications
  const cards = analyseForRepurposing(context.draftOrders);

  res.json({ cards });
});

app.listen(3000);

Security

Authentication

CDS Hooks supports OAuth 2.0 bearer tokens:

Authorization: Bearer {access_token}

CORS

Enable CORS for EHR integration:

app.use(cors({
  origin: '*',
  methods: ['GET', 'POST', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization']
}));

Resources


Back to top

Copyright © 2026 Yao.Care. For research purposes only. Not medical advice.

This site uses Just the Docs, a documentation theme for Jekyll.