F POLARIS · FHIR
sdk · examples

API examples for common MIRA workflows.

Copyable TypeScript examples for the flows developers usually ask about first: finding patients, writing patient resources, opening encounters, and adding billable charge items.

setup

Connect to Aidbox with a small transport.

The SDK does not ship a default HTTP client. This adapter is the reusable setup used by the examples below.

import {
  FhirDeHttpError,
  createFhirDeClient,
} from '@polaris/sdk/fhir'
import type { FhirResource, FhirTransport } from '@polaris/sdk/fhir'

const baseUrl = 'https://aidbox.example.com/fhir'

const transport: FhirTransport = {
  async request(method, path, init) {
    const normalizedPath = path.startsWith('/') ? path : `/${path}`
    const url = new URL(`${baseUrl.replace(/\/$/, '')}${normalizedPath}`)

    if (init?.query) {
      for (const [key, value] of Object.entries(init.query)) {
        const values = Array.isArray(value) ? value : [value]
        for (const item of values) url.searchParams.append(key, item)
      }
    }

    const res = await fetch(url, {
      method,
      headers: {
        'Content-Type': 'application/fhir+json',
        Accept: 'application/fhir+json',
        Authorization: `Bearer ${process.env.AIDBOX_TOKEN}`,
        ...init?.headers,
      },
      body: init?.body == null ? undefined : JSON.stringify(init.body),
    })

    const body = res.status === 204 ? null : await res.json().catch(() => null)
    if (!res.ok) throw new FhirDeHttpError(res.status, body)
    return body
  },
}

const client = createFhirDeClient({ baseUrl, transport })

async function putResource<T extends FhirResource>(resource: T): Promise<T> {
  if (!resource.id) throw new Error('PUT requires resource.id')
  return await transport.request(
    'PUT',
    `/${resource.resourceType}/${resource.id}`,
    { body: resource }
  ) as T
}

patient lookup

Find and read patients.

Use the typed client when you want profile-wrapped resources and strict profile validation on server responses.

import {
  KBV_PR_FOR_PatientProfile,
  SYSTEM_KVID_10,
} from '@polaris/fhir-de'

const patients = client.forProfile(KBV_PR_FOR_PatientProfile, 'Patient')

// Lookup by GKV KVID-10 identifier
const matches = await patients.search({
  identifier: `${SYSTEM_KVID_10}|A123456789`,
  _count: '10',
})

// Read by stable FHIR id
const patient = await patients.read('pat-001')
if (patient === null) {
  // Patient was not found. read(id) treats 404 as a valid absence.
}

patient write

Create or update a patient resource.

Builder output is a plain FHIR resource. It can be written directly to Aidbox, NDJSON, or another FHIR server.

import { buildPatient } from '@polaris/fhir-de'

const patient = buildPatient({
  id: 'pat-001',
  firstName: 'Anna',
  lastName: 'Müller',
  birthDate: '1985-04-12',
  gender: 'female',
  kvid10: 'A123456789',
  address: {
    line: ['Hauptstraße 1'],
    city: 'München',
    postalCode: '80331',
    country: 'DE',
  },
})

await putResource(patient)

visit

Open or update an encounter.

This mirrors a typical practice workflow: patient arrives, gets called, and the encounter is linked back to patient and organization.

import { buildEncounter } from '@polaris/fhir-de'

const encounter = buildEncounter({
  id: 'enc-2026-04-27-001',
  status: 'in-progress',
  class: {
    system: 'http://terminology.hl7.org/CodeSystem/v3-ActCode',
    code: 'AMB',
    display: 'ambulatory',
  },
  subject: { reference: 'Patient/pat-001' },
  serviceProvider: { reference: 'Organization/org-001' },
  period: { start: '2026-04-27T09:00:00+02:00' },
  arrivalTime: '2026-04-27T08:55:00+02:00',
  calledTime: '2026-04-27T09:05:00+02:00',
})

await putResource(encounter)

billing

Add EBM and GOÄ charge items.

ChargeItems link billable services to the patient and encounter. EBM uses the German ChargeItem EBM profile; GOÄ and other private billing systems are emitted as plain R4 ChargeItem resources.

import {
  SYSTEM_EBM,
  SYSTEM_GOAE,
  buildChargeItem,
} from '@polaris/fhir-de'

const ebm03000 = buildChargeItem({
  id: 'charge-ebm-03000-001',
  status: 'billable',
  code: {
    system: SYSTEM_EBM,
    code: '03000',
    display: 'Versichertenpauschale',
  },
  subject: { reference: 'Patient/pat-001' },
  context: { reference: 'Encounter/enc-2026-04-27-001' },
  occurrenceDateTime: '2026-04-27T09:15:00+02:00',
  performer: [{ actor: { reference: 'Practitioner/prac-001' } }],
  quantity: { value: 1 },
})

const goae1 = buildChargeItem({
  id: 'charge-goae-1-001',
  status: 'billable',
  code: {
    system: SYSTEM_GOAE,
    code: '1',
    display: 'Beratung',
  },
  subject: { reference: 'Patient/pat-001' },
  context: { reference: 'Encounter/enc-2026-04-27-001' },
  occurrenceDateTime: '2026-04-27T09:20:00+02:00',
  performer: [{ actor: { reference: 'Practitioner/prac-001' } }],
  quantity: { value: 1 },
  factorOverride: 2.3,
})

await putResource(ebm03000)
await putResource(goae1)

billing lookup

Load charge items for an encounter.

For resource types without a profile-scoped client, call the same transport directly and keep the result as a FHIR Bundle.

const chargeItemBundle = await transport.request('GET', '/ChargeItem', {
  query: {
    context: 'Encounter/enc-2026-04-27-001',
    _count: '50',
  },
})

// chargeItemBundle is the raw FHIR Bundle returned by the server.

llm gateway

Route LLM requests with capability checks.

Import PII-safe prompt types, capability routing, and PII scanning from @polaris/sdk/llm. Use @polaris/fhir-de directly for resource builders (buildPatient, buildEncounter, etc.) — @polaris/sdk/llm is for the LLM gateway client API.

import {
  AnonymizedPrompt,
  routeRequest,
  scanForPii,
  NoopAuditStore,
} from '@polaris/sdk/llm'

// Construct a PII-safe prompt (must have been anonymized before calling from())
const prompt = AnonymizedPrompt.from({ anonymizedText: 'Diagnose: Hypertonie' })

// Check text for PII before constructing an AnonymizedPrompt
const piiResult = scanForPii('Patient: Max Mustermann, geb. 01.01.1980')
if (piiResult.hasPii) {
  // Anonymize or redact before proceeding
  console.log('PII detected:', piiResult.matches)
}

// Route a request through the LLM gateway
const auditStore = new NoopAuditStore()
const result = await routeRequest(
  { intentId: 'summarize-encounter', prompt },
  { auditStore }
)

anonymized mode

Anonymisierte Antworten mit piiMode.

Mit piiMode: 'anonymized' werden PII-Felder (Namen, Adressen, Kontaktdaten) aus allen FHIR-Antworten entfernt, bevor sie zurückgegeben werden. Nützlich für Entwicklungs- und Testumgebungen oder für KI-Agenten ohne direkten Patientendatenzugriff.

import {
  createFhirDeClient,
  AnonymizingTransport,
} from '@polaris/sdk/fhir'
import { KBV_PR_FOR_PatientProfile } from '@polaris/fhir-de'

// POLARIS_ANON_SALT must be set in the environment.
// createFhirDeClient throws synchronously if it is missing.
// process.env.POLARIS_ANON_SALT = 'my-secret-salt'

const anonClient = createFhirDeClient({
  baseUrl,
  transport,
  piiMode: 'anonymized',
})

const patients = anonClient.forProfile(KBV_PR_FOR_PatientProfile, 'Patient')

// Patient names, addresses, identifiers, and contact info are removed.
// IDs are deterministically hashed: SHA-256(salt:id) → 'anon-<12hex>'.
const patient = await patients.read('pat-001')
// patient.id             → 'anon-3f8a1c20b7d9'   (hashed)
// patient.resource.name  → undefined               (PII removed)
// patient.resource.address → undefined             (PII removed)

// References within resources are also rewritten consistently:
// 'Patient/pat-001' → 'Patient/anon-3f8a1c20b7d9'

// To use AnonymizingTransport directly (e.g. to pass an explicit salt in tests):
const anonTransport = new AnonymizingTransport(transport, 'test-salt')
const testClient = createFhirDeClient({ baseUrl, transport: anonTransport })

Resource builders stay in @polaris/fhir-de.

buildPatient, buildEncounter, and the other builders are exported from @polaris/fhir-de directly. @polaris/sdk/fhir exposes the typed client API — not the builders.

LLM types live in @polaris/sdk/llm.

All LLM gateway types — AnonymizedPrompt, routeRequest, scanForPii — are available from @polaris/sdk/llm. Hono and server-runtime symbols are excluded from this subpath.

Use Polaris Platform for operations.

The SDK builds and reads FHIR resources. Sync scheduling, PVS writeback, audit trails, and multi-tenant lifecycle are handled by the Polaris Platform and adapter APIs.