Skip to content

Universal Ingestion Flow

This guide describes how to integrate with HAMI’s Universal Ingestion API to send patient-intake data (demographics, vitals, chief complaint, observations, conditions, etc.) via a single FHIR-native endpoint.

  • Purpose: Enable referral partners to send patient-intake data (demographics, vitals, chief complaint, observations, conditions, etc.) via a single FHIR-native endpoint.
  • High-level flow: Partner submits a FHIR Bundle (type=transaction) → API validates/profile-checks → API acknowledges with a transaction token → asynchronous processing and deduplication → stored in HAMI for further processing.
  • Standards: FHIR (HL7), UCUM for units, LOINC/SNOMED/ICD terminology.
  • Audience: Partner engineers, EHR integrators, interface analysts, health-data vendors.
  • Universal intake: Accept a minimal-yet-extensible subset of FHIR resources to represent referrals at any stage of completeness.
  • Interoperability & safety: Enforce baseline conformance (profiles, required codings, resolvable references) without overfitting to a single EHR.
  • Idempotency & deduplication: Prevent duplicates across retries and multi-system forwards.
  • Observability: Provide consistent acknowledgment (token), status tracking, and rich error reporting.
  • Security & privacy: Protect PHI/PII in transit and at rest, align with regulatory expectations (e.g., HIPAA/GDPR where applicable).
  • Production Base: https://hamiapi.bostonhealth.ai/api/g/group-slug/ingestion/fhir/v4
  • FHIR resources within requests. Note: (using R4 in the implementation right now)
  • API-KEY assigned per group
  • Required: Bundle(type=transaction), Patient, at least one of:
    • Condition (chief complaint/diagnosis) or
    • Observation (e.g., vitals) or
    • Appointment/Encounter context
  • Strongly Recommended: Encounter (if care context exists), Observation(vitals), Condition (chief complaint/working dx).

Patient, Appointment, Encounter, Condition, Observation, AllergyIntolerance, MedicationRequest, MedicationStatement, Procedure, ServiceRequest, Provenance, DocumentReference, Coverage, RelatedPerson, Organization, Practitioner, PractitionerRole.

Rule: All intra-bundle references must resolve within the bundle or to stable external URIs the partner controls.

POST /ingestion

Headers:

  • Content-Type: application/fhir+json
  • X-API-KEY: <group-api-key>
  • Idempotency-Key: <UUID> (required for safe retries)

Body: FHIR Bundle (type=“transaction”)

Success (202 Accepted)

{
"transactionId": "xx7qHZgRJP8jUjMoA6JLvQ"
}
  • Publish canonical profiles for: Patient, Observation (vitals), Condition (encounter-dx), Encounter, Appointment.
  • Validate against: structure, terminology, invariants, intra-bundle references.
  • Vitals: LOINC (e.g., BP 85354-9, HR 8867-4, RR 9279-1, Temp 8310-5, SpO₂ 59408-5 for pulse-ox).
  • Diagnoses/Complaints: SNOMED CT preferred; ICD-10-CM accepted for billing alignment.
  • Units: UCUM (e.g., mm[Hg], kg, Cel, 1/min).
  • Bundle.type must be “transaction”.
  • entry[].request.method ∈ {POST,PUT,DELETE} and consistent with resource intent.
  • References: Every reference must point to a fullUrl within the bundle or an absolute URL resolvable by the partner/EHR.
  • Identifiers: MRNs, national IDs, and external IDs should appear in identifier[] with system URIs.
  • Narratives: text.div must be valid XHTML. Avoid secrets/keys in narratives.

Idempotency, Deduplication & Reconciliation

Section titled “Idempotency, Deduplication & Reconciliation”
  • Idempotency-Key: Required; same key + same payload ⇒ safe re-ack (same transaction_token).
  • Dedup strategy:
    • Patient by stable identifiers (identifier.system+value), then probabilistic match (name+DOB+telecom) if allowed by BAAs/policies.
    • Observation by (subject, code, effectiveDateTime, valueQuantity, performer) hash.
    • Condition by (subject, code, recordedDate) tuple.
  • Actions: created | updated | linked | skipped.
  • Quarantine: Records violating hard constraints but potentially recoverable (e.g., unknown code systems). Partners can correct and resubmit.
  • Transport: TLS 1.2+; strong cipher suites; optional mTLS.
  • Access controls: Least privilege; audited access to PHI.
  • Audit trails: Record submitter, IP, correlation IDs, validation results, mapping outcomes.
  • Data retention: Configurable retention windows for raw bundles (e.g., 30-90 days) and logs.
  • Consent & legal: Partners attest to right to share data; optional Consent resource accepted and honored.
  • Breach/incident response: Defined timelines and partner notification channels.
  • Default: 300 requests/min per client; burst tokens documented.
  • Max payload size: e.g., 5 MB per bundle (configurable).
  • Retry policy: On 429 or transient 5xx, backoff with jitter; reuse same Idempotency-Key.
  • Top-level fields: error, correlation_id, issues[].
  • Issue format: severity (fatal|error|warning), code (FHIR IssueType when applicable), expression[] (FHIRPath), human-readable detail.
  • Mapping to HTTP:
    • 400 validation failures
    • 401/403 auth problems
    • 409 resource conflict/idempotency mismatch
    • 422 semantic issues (terminology/profiles)
    • 500/503 transient server issues
  • Use stable identifiers: Always send identifier.system URIs (MRN, national ID, external referral ID).
  • Normalize vitals: UCUM units; single LOINC per Observation code (don’t mix ABG and pulse-ox).
  • Choose plausible values: e.g., adult body weight >= 30 kg unless a pediatric context is explicit.
  • Reference hygiene: Every reference must resolve; prefer fullUrl URNs inside the transaction.
  • Time semantics: Use UTC ISO 8601 (e.g., 2025-09-25T09:41:00Z).
  • Encounter.class: In R5, Encounter.class is a single Coding, not an array.
  • Idempotency: Always send Idempotency-Key for every POST; reuse on retries.
  • Chunking: Large cases ⇒ split logically across multiple transactions linked by an external referral ID in Bundle.identifier.
  • Provenance: Include Provenance when possible to trace device/system sources.
  • Testing: Validate locally (FHIR validators) before submitting; start in Sandbox.

Data Mapping & Normalization (Server-side)

Section titled “Data Mapping & Normalization (Server-side)”
  • Identifiers: Map incoming identifiers to internal master patient index (MPI); maintain crosswalk.
  • Codes: Validate against terminology server; auto-map common equivalents; quarantine unknowns.
  • Units: Auto-convert to canonical UCUM (store canonical + original).
  • Dates/times: Normalize to UTC; persist original timezone offset where present.
  • Text vs coded: Prefer coded elements; retain text for display.
  • Correlation IDs: Return correlation_id in all error responses; accept incoming X-Request-Id.
  • Metrics: Submission counts, validation failures by rule, dedup rates, latency histograms.
  • Dashboards: Partner-specific views for success/failure trends and quarantine queues.

Q: Can we send partial data?

A: Yes—send what you have; the same patient/referral can be enriched later with new transactions.

Q: How do we update a prior record?

A: Submit a new transaction referencing the same identifiers; server dedup/reconciliation will apply.

Q: Can we send PDFs/images?

A: Yes via DocumentReference with binary links or Base64; observe payload limits.