SMART Health Links — secure patient data sharing via QR codes

SMART Health Links SDK

Build an International Patient Summary, encrypt it as a SMART Health Link, and generate a QR code — in under 20 lines of code.


Installation

npm install @fhirfly-io/shl

If using FHIRfly API enrichment (recommended — adds display names and SNOMED cross-mappings automatically):

npm install @fhirfly-io/shl @fhirfly-io/terminology

1. Build an IPS Bundle

import { IPS, SHL } from "@fhirfly-io/shl";
import Fhirfly from "@fhirfly-io/terminology";

const client = new Fhirfly({ apiKey: process.env.FHIRFLY_API_KEY });

const bundle = new IPS.Bundle({
  given: "Maria",
  family: "Garcia",
  birthDate: "1985-03-15",
  gender: "female",
});

// Add clinical data (FHIRfly enriches with SNOMED, display names, etc.)
bundle.addMedication({ byNDC: "00071015523", fhirfly: client.ndc });
bundle.addCondition({ byICD10: "E11.9", fhirfly: client.icd10 });
bundle.addAllergy({ bySNOMED: "387207008" });
bundle.addImmunization({ byCVX: "208", fhirfly: client.cvx });
bundle.addResult({
  byLOINC: "2339-0",
  fhirfly: client.loinc,
  value: 95,
  unit: "mg/dL",
});

const fhirBundle = await bundle.build();

Each add* method accepts multiple input formats: code-based with enrichment (byNDC, byICD10, byCVX, byLOINC), SNOMED direct (bySNOMED), existing FHIR resources (fromResource), or manual code/system/display.

No API key? Use bySNOMED (no API call needed) or manual code/system/display input. The FHIRfly API adds display names and SNOMED cross-mappings but isn't required.


2. Create an SHL

// Option A: FHIRfly hosted (zero infrastructure)
const storage = new SHL.FhirflyStorage({
  apiKey: process.env.FHIRFLY_API_KEY,
});

// Option B: Local storage (for development)
// const storage = new SHL.LocalStorage({
//   directory: "./shl-data",
//   baseUrl: "http://localhost:3456/shl",
// });

const result = await SHL.create({
  bundle: fhirBundle,
  storage,
  passcode: "1234",
  label: "Maria's Health Summary",
});

console.log(result.url);     // shlink:/eyJ...
console.log(result.qrCode);  // data:image/png;base64,...

This does four things:

  1. Generates a random 256-bit encryption key and SHL ID
  2. Encrypts the FHIR bundle as a JWE (AES-256-GCM, DEFLATE compression)
  3. Stores three files: content.jwe, manifest.json, metadata.json
  4. Builds the shlink:/ URL (with the key embedded) and a QR code PNG

FhirflyStorage is included free in all plans with per-plan limits on active SHLs and attachments. The decryption key is never sent to FHIRfly — only opaque encrypted blobs are stored. See Pricing and Storage Adapters for details.


3. Share

The result.url is a complete SMART Health Link. Share it by:

  • QR Code — Save result.qrCode as a PNG image for scanning
  • Deep Link https://fhirfly.io/shl/viewer#shlink:/eyJ...
  • Text — Send the shlink:/ URL directly

4. View

Open the SHL Viewer and paste the link, or use the deep link format above. All decryption happens in the browser — the encryption key never leaves the page.


CLI alternative

For quick testing without writing code:

# Full demo with sample patient data
npx @fhirfly-io/shl demo

# Create from an existing FHIR Bundle file
npx @fhirfly-io/shl create my-bundle.json --passcode 1234

# Start a local server
npx @fhirfly-io/shl serve --dir ./shl-data --port 3456

# Validate a FHIR Bundle against IPS
npx @fhirfly-io/shl validate bundle.json

# Decode an SHL URL
npx @fhirfly-io/shl decode shlink:/eyJ...

How encryption works

The SDK uses a zero-knowledge architecture. The encryption key lives only in the shlink:/ URL — it is never sent to the server. The server stores and serves opaque encrypted blobs. Only someone with the URL (or QR code) can decrypt the data.

DataWhere it lives
Patient health dataEncrypted (AES-256-GCM) on your storage backend
Decryption keyEmbedded in the shlink:/ URL only
PasscodeSHA-256 hashed in server metadata
Access controlsServer-side metadata (expiration, max accesses)

Next steps

EHR Integration GuideMap HL7v2, CCDA, FHIR R4, and flat database records to IPS bundles
Server GuideSelf-host SHL endpoints with Express, Fastify, or Lambda
Storage AdaptersCompare FhirflyStorage, S3, Azure, GCS, and local filesystem
Security & ComplianceZero-knowledge architecture, HIPAA, compliance checklist
CLI ReferenceAll CLI commands and options
TroubleshootingCommon issues and patient input format guide