Universal Ingestion Flow
This guide explains how to send patient-intake data (demographics, vitals, presenting symptom, conditions and more) to HAMI through a single FHIR-native endpoint. It also shows how that one call leads to patient intake, the AI summary and, optionally, HAMI Scribe for the clinician.
Introduction
Section titled “Introduction”- Purpose: Let referral partners and EHRs send patient-intake data to HAMI in one FHIR request.
- High-level flow: Partner submits a FHIR Bundle (type=transaction) → HAMI validates the FHIR structure → HAMI matches or creates the patient, creates the appointment and stores the bundle → HAMI responds with a
transactionIdand any links enabled for your group. All of this happens synchronously, within the request. - Standards: FHIR R4 (HL7). UCUM for units, LOINC/SNOMED CT/ICD-10 for terminology.
- Audience: Partner engineers, EHR integrators, interface analysts, health-data vendors.
API Overview
Section titled “API Overview”Base URL
Section titled “Base URL”{HAMI_API_BASE_URL}/api/g/{group-slug}/ingestion/fhir/v4
HAMI provides the base URL for each environment, your group slug and your API key during onboarding.
Authentication
Section titled “Authentication”- An API key is issued per group and sent in the
X-API-KEYheader.
Supported Use Cases & Resource Scope
Section titled “Supported Use Cases & Resource Scope”Minimum Viable Referral
Section titled “Minimum Viable Referral”- Required: a
Bundlewithtype: "transaction"that contains aPatient. - Strongly recommended:
Patient.telecom(phone) and/or an MRN identifier, so the patient is matched rather than duplicatedPatient.genderandPatient.birthDatePatient.communication(preferred language)- An
Appointment, for the visit date and time - An
Observationwith categorysymptom, for the presenting symptom
Resource Types
Section titled “Resource Types”Any structurally valid FHIR R4 resource is accepted and stored with the transaction. HAMI actively uses Patient, Appointment and symptom Observation resources. See Supported Resource Types.
Rule: References inside the bundle should resolve to a fullUrl in the same bundle.
API Endpoints
Section titled “API Endpoints”Submit Transaction
Section titled “Submit Transaction”POST /api/g/{group-slug}/ingestion/fhir/v4
Headers:
Content-Type: application/jsonX-API-KEY: <group-api-key>x-correlation-id: <your-id>(optional; echoed back so you can trace the request)
Body: FHIR Bundle (type: "transaction")
Success (201 Created)
{ "transactionId": "0192f3a1-7c4e-7b2a-9d1f-3e5a6b7c8d90", "url": "https://hamiapp.bostonhealth.ai/g/group-slug/transaction/0192f3a1-7c4e-7b2a-9d1f-3e5a6b7c8d90"}Depending on your group’s configuration, the response can also include qrCodeImage, embedUrl, scribeLaunchUrl and appointmentUrl. See the response reference.
End-to-End Flow
Section titled “End-to-End Flow”One ingestion call can drive the whole visit, from patient intake to the signed clinical note:
Your system HAMI Patient / Clinician ─────────── ──── ─────────────────── 1. POST FHIR Bundle ───────────────► Store bundle, match or create patient, create appointment ◄──────────── 201 { transactionId, url, qrCodeImage?, embedUrl?, appointmentUrl?, scribeLaunchUrl? }
2. Hand the intake to the patient: • show qrCodeImage (kiosk / printout) ───────────────────────────► Patient scans, completes intake • load embedUrl in your iframe ──────────────────────────────────► Patient completes intake in your portal • send appointmentUrl / url (SMS, email) ────────────────────────► Patient opens link, completes intake
3. ◄──────────── Intake Summary Webhook { appointmentId, transactionId, emergency_patient, intakeSummary, ... }
4. Open scribeLaunchUrl in your EHR ────────────────────────────────► Clinician signs in, records visit, signs off SOAP note 5. ◄──────────── Scribe Webhook { soapNote, transcript, icdCodes, cptCodes, afterVisitSummary, sourcePatientId, ... }| Step | Feature | Reference |
|---|---|---|
| 1 | Universal Ingestion API | Universal Ingestion API |
| 2 | QR code, embedded intake, appointment link | Optional response features, Iframe Embedding |
| 3 | Intake summary push | Intake Summary Webhook |
| 4 | Embedded Scribe | Scribe Embedding |
| 5 | Scribe note push | Scribe Webhook |
Each step after step 1 is optional and enabled per group. Most integrations start with steps 1–3 and add Scribe (steps 4–5) later.
What to include in your bundle
Section titled “What to include in your bundle”| To get… | Include… |
|---|---|
| A matched (not duplicated) patient | A phone number in Patient.telecom (matched together with first and last name), and/or an MRN in Patient.identifier with type code MR (used when there is no phone number) |
| Correct demographics | Patient.gender and Patient.birthDate. HAMI stores placeholder values if they are missing. |
| Intake in the patient’s language | Patient.communication with the preferred language |
| Your IDs back in the webhooks | Stable fullUrl values on the Patient and Appointment entries, and an MR identifier on the Patient |
| The visit time on the physician dashboard | An Appointment resource. Without one, HAMI creates an appointment at the time of ingestion. |
| Presenting symptom passed to the AI intake | An Observation with category code symptom and the symptom in valueCodeableConcept.text |
Validation
Section titled “Validation”HAMI validates every resource in the bundle against the FHIR R4 structure definitions. Unknown elements and wrongly typed values are rejected with 400 Bad Request. Terminology bindings and profiles are not checked on the server, so validate your bundles locally before sending (for example with the HL7 FHIR Validator).
Recommended Terminology
Section titled “Recommended Terminology”- 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.
- Units: UCUM (e.g., mm[Hg], kg, Cel, /min).
Recommended Conventions
Section titled “Recommended Conventions”Bundle.typeshould be"transaction".- References: point to a
fullUrlwithin the bundle. Preferurn:uuid:values. - Identifiers: put MRNs and external IDs in
identifier[]with system URIs. Mark the MRN with type codeMR. - Narratives:
text.divmust be valid XHTML. Never put secrets or keys in narratives.
Duplicates and Retries
Section titled “Duplicates and Retries”The API is not idempotent. Every successful request creates a new transaction and a new appointment. The patient profile is reused when it matches (see How the patient is matched).
- Send one bundle per visit, and don’t resubmit after a
201. - Retry only
5xxresponses and network failures, with exponential backoff. If you’re unsure whether a timed-out request succeeded, contact support with yourx-correlation-idbefore resending.
Errors
Section titled “Errors”All errors return { statusCode, message, correlationId }:
| Status | When |
|---|---|
400 | Invalid JSON, or the bundle fails FHIR R4 structural validation |
401 | X-API-KEY missing or not valid for this group |
404 | Unknown group slug |
500 | Unexpected server error. Contact support with the correlationId. |
See Error Responses for examples.
Limits
Section titled “Limits”- Maximum request size: 50 MB.
- Contact support before sending bulk or backfill volumes.
Best Practices for Partners
Section titled “Best Practices for Partners”- Use stable identifiers: always send
identifier.systemURIs (MRN, external referral ID). - Normalize vitals: UCUM units, one LOINC code per Observation.
- Choose plausible values: e.g., adult body weight ≥ 30 kg unless a pediatric context is explicit.
- Reference hygiene: every reference should resolve to a
fullUrlinside the transaction. - Time semantics: use UTC ISO 8601 (e.g.,
2025-09-25T09:41:00Z). - Testing: validate bundles locally before submitting, and start in the HAMI test environment provided at onboarding.
Frequently Asked Questions
Section titled “Frequently Asked Questions”Q: Can we send partial data?
A: Yes. Only a Patient is required. Send what you have and HAMI’s AI intake collects the rest from the patient.
Q: How do we update a prior record?
A: Records can’t be updated through this API. A new submission creates a new transaction and appointment for the same (matched) patient. Contact support if you need a correction.
Q: Can we send PDFs/images?
A: A DocumentReference with base64 content is accepted and stored with the transaction (up to the 50 MB request limit). It is not currently passed to the AI intake.