Huli FHIR Core Implementation Guide (R5)
0.1.0 - Release Latin America and the Caribbean

Huli FHIR Core Implementation Guide (R5) - Local Development build (v0.1.0) built by the FHIR (HL7® FHIR® Standard) Build Tools. See the Directory of published versions

Home

Official URL: https://fhir.huli.ai/r5/ImplementationGuide/huli.fhir.core.r5 Version: 0.1.0
Active as of 2026-09-11 Computable Name: HuliFHIRCoreR5

Huli FHIR Core Implementation Guide (R5)

FHIR R5 facade profiles for the Huli healthcare platform, targeting Latin American ambulatory care workflows. This IG package describes the R5 surface; the R4 surface is published as a separate package (huli.fhir.core.r4, canonical https://fhir.huli.ai/r4).

URLs you will see in this IG

  • Canonical URLhttps://fhir.huli.ai/r5. The IG identifier used as the prefix for every profile, extension, and CodeSystem URL emitted by this IG and by the Huli Public API R5 runtime. Per FHIR convention, the canonical URL does not need to resolve in a browser — it is an opaque identifier that establishes ownership and stability across versions. The /r5 segment disambiguates R5 artifacts from their R4 siblings in meta.profile arrays and extension URLs.
  • API basehttps://api.huli.io/fhir/R5. The wire URL where resources are read and written. The published GET .../metadata CapabilityStatement and implementation.url use this base (implementation.url = issuer + /R5).
  • Published sitehttps://developers.huli.ai/fhir/r5/. Where this IG is hosted for human consumption.

Scope

This Implementation Guide covers the resources exposed by the Huli Public FHIR R5 API at https://api.huli.io/fhir/R5 — the ten clinical resources plus the four read/search-only booking-discovery resources:

  • Patient — read, search, create, update
  • Appointment — read, search, create, update (incl. recurring series via the R5 recurrenceTemplate element + the _recurrenceScope query-param convention; series cancellation is a PUT with status = cancelled — there is no REST delete on this API)
  • Encounter — read, search, create, update
  • Observation — read, search, create, update
  • MedicationRequest — read, search, create, update (clinical Plan; BAA-gated)
  • ServiceRequest — read, search, create, update (clinical Plan; BAA-gated)
  • Composition — read, search, create, update (clinical-note projection of an Encounter; optimistic concurrency via If-Match)
  • DocumentReference — read, search, create, update, $upload (BAA-gated)
  • Practitioner — read, search
  • Organization — read, search
  • HealthcareService — read, search (booking discovery)
  • PractitionerRole — read, search (booking discovery)
  • Schedule — read, search (booking discovery; serviceType is an R5 CodeableReference)
  • Slot — search (booking discovery; computed availability)

The remaining R4-only surfaces — Location, Device, terminology (ValueSet/$expand, CodeSystem), and Subscription — are not part of the R5 surface; they remain on the R4 IG.

Plus Latin-America-specific extensions for naming conventions, blood type, ethnicity, private insurance, cancellation audit trails, and the regulatory metadata required by NOM-024-SSA3 in Mexico.

R4 → R5 structural deltas surfaced here

  • Encounterclass is now CodeableConcept (0..*, was a single Coding); periodactualPeriod; participant.individualparticipant.actor; diagnosis.condition is a CodeableReference and diagnosis.rank was dropped (primary/secondary rides diagnosis.use); reasonCodereason; the Huli completed status maps directly to the R5 completed code (R4 used finished).
  • Appointment — adds recurrenceTemplate, recurrenceId, and subject; serviceType is now a CodeableReference (coding on serviceType.concept); participant.required is a boolean; priority is a CodeableConcept; commentary moved from comment to note[]; cancelationReasoncancellationReason.
  • Organization — top-level telecom/address removed; folded into the contact backbone.
  • Observation — compatible (new triggeredBy/bodyStructure not surfaced).
  • MedicationRequestmedication is a single CodeableReference (R5 collapsed the R4 medication[x] choice); the drug rides medication.concept. reported is a boolean. reasonCodereason (CodeableReference).
  • ServiceRequestcode is a CodeableReference (was a CodeableConcept in R4); the ordered service rides code.concept. reasonCodereason.
  • Composition — compatible; section[] is still sliced by LOINC code and encounter is a single Reference.
  • DocumentReferencecontext is flattened to a Reference list (R5 dropped the R4 context backbone); the bound encounter is a direct context Reference. content.format (R4 Coding) → content.profile. A single attachment per document is retained.
  • Patient / Practitioner — compatible.

Version

0.1.0. The published GET /fhir/R5/metadata CapabilityStatement on the Public API is kept in lockstep with this IG.

Where to start

  • Patient Mapping
  • Appointment Mapping — recurring series + cancellation/confirmation workflows.
  • Encounter Mapping — the R5 Encounter deltas.
  • Artifact Index — the clinical-Plan profiles (MedicationRequest, ServiceRequest), the clinical-note projection (Composition), and the patient document ($upload) surface (DocumentReference); all four BAA-gated.
  • Extensions — full list of Huli-defined extensions.
  • Terminology — bound value sets and code systems.

API

Authentication uses SMART on FHIR client_credentials + private_key_jwt. Discovery: GET https://api.huli.io/.well-known/smart-configuration.

Optimistic concurrency

This is a server-behavior contract enforced identically on the R4 (4.0.1) and R5 surfaces — an R4 integrator on /fhir/R4 gets the same behavior.

DocumentReference, Encounter, MedicationRequest, Composition, and Appointment support optimistic concurrency on update. A read returns a weak ETag; echo it back in an If-Match header on the PUT to condition the write on the version you last read. A stale precondition is rejected with 409 Conflict (HPB-00103); a PUT with no If-Match updates unconditionally.

The resource body's meta.versionId mirrors the ETag version — both derive from the resource's modified_on and advance on every update — so a client may detect and condition on changes from either. A conditional PUT echoes the ETag back in the If-Match header.

Patient and Observation do not currently enforce optimistic concurrency: a PUT to either resource always applies, and If-Match is not honored on those two. This is a deliberate, symmetric exemption for now, not a per-version asymmetry.

Write constraints

This is a server-behavior contract enforced identically on the R4 (4.0.1) and R5 surfaces — an R4 integrator on /fhir/R4 gets the same behavior.

A well-formed request that violates a resource business rule is rejected with 422 Unprocessable Entity and an OperationOutcome whose issue.code is business-rule and whose issue.expression points at the offending element — rather than silently succeeding and dropping the value.

  • Illegal status transitions. A PUT requesting a status transition the resource lifecycle forbids (e.g. an Appointment cancelled -> booked) is rejected 422 business-rule at Appointment.status. The set of allowed transitions is unchanged.
  • Elements this surface does not persist. These are rejected on write instead of being accepted and dropped: Composition.title (the note title is fixed), DocumentReference.type (there is no classifier on this surface), and Observation.referenceRange. A request that omits the element — or echoes the exact value the API emits on read — is accepted, so a read-then-write round-trip never trips the guard.
  • Server-derived fields. The Appointment confirmation-status extension is read-only: a write that changes it is rejected 422 business-rule, while an echo of the current value is accepted.

Search behavior

Encounter?status= accepts both the R4 (finished) and R5 (completed) status codes on either version and maps them to the same stored encounter state — an intentional lenient dual-vocabulary mapping, so a client migrating between versions can search by either code. An unknown status value still matches nothing.

Contract

This IG is the wire contract for the Huli Public FHIR R5 API. Profiles, extensions, terminology, and the CapabilityStatement published here describe exactly what the API at https://api.huli.io/fhir/R5 produces and accepts.

Data handling and compliance

The resources described in this IG carry protected health information (PHI): national identifiers (CURP, INE, CED, DIMEX, DPI, passport), dates of birth, addresses, blood type, private-insurance details, and ICD-10-coded conditions. Integrators are responsible for handling that data under HIPAA (US-touching deployments), NOM-024-SSA3 (México), and country-specific data-protection law (LFPDPPP, LPDP, …). Minimum obligations: do not log identifiers in plaintext; apply minimum-necessary SMART scope; respect data-subject rectification/deletion signals; TLS-only transport; maintain your own per-request audit trail. This is a checklist, not legal advice.