FHIR R4
Send FHIR R4 to EDFlow: batch Bundles, the $ingest operation for collection, searchset and Subscriptions Backport notifications, $process-message, how each resource maps to events, Epic and Oracle Health notes, and a worked example.
The FHIR adapter maps FHIR R4 resources to the same normalized events as HL7 v2, following the HL7 V2-to-FHIR concept maps where they apply, so HL7 and FHIR sites get the same behaviour. Raw resources are never stored.
Endpoints
| Endpoint | Accepts | Notes |
|---|---|---|
POST /v1/fhir | batch Bundles (up to 200 entries) | Each entry processed independently. transaction is refused (422 transaction_not_supported) |
POST /v1/fhir/$ingest | collection, searchset and history Bundles, including Subscriptions Backport notifications | Handshakes and heartbeats produce no events; heartbeats keep the feed healthy |
POST /v1/fhir/$process-message | message Bundles with a MessageHeader | Duplicates detected by Bundle.id + MessageHeader.id for 30 days |
GET /v1/fhir/metadata | CapabilityStatement | Public |
GET /v1/fhir/.well-known/smart-configuration | SMART Backend Services discovery | private_key_jwt only |
Accept: application/fhir+json returns a batch-response Bundle with an OperationOutcome per entry; Accept: application/json returns the normalized results. A transient failure returns 503 with Retry-After for the whole request; entries already committed return duplicate on retry.
printf '%s' '{"entry":[],"meta":{"tag":[{"code":"HTEST","system":"http://terminology.hl7.org/CodeSystem/v3-ActReason"}]},"resourceType":"Bundle","type":"batch"}' > body.jsoncurl -sS -X POST 'https://api.sandbox.edflow.space/v1/fhir' \ -H 'Content-Type: application/fhir+json' \ -H "Authorization: Bearer $EDFLOW_ACCESS_TOKEN" \ --data-binary @body.jsonSubscription rest-hooks
Backport rest-hook channels send static headers, so a 5-minute token doesn't fit. Use a static API key scoped to fhir:write only in Subscription.channel.header. In customer test and live it needs an IP allowlist and expires within 90 days; update the Subscription before it expires.
Sandbox test marker
In the sandbox, Bundles must carry the HTEST tag (http://terminology.hl7.org/CodeSystem/v3-ActReason#HTEST) in meta.tag; in live it's refused.
Resource mapping
| Resource | Condition | Events |
|---|---|---|
Encounter | class = EMER, or an ED location | First arrived/in-progress → encounter.arrived (period.start); a triaged status history entry → encounter.triaged; active location → encounter.location_changed; participant → careteam.snapshot; onleave → out of department; finished → encounter.departed with the discharge disposition; cancelled → encounter.cancelled |
Observation | Code is one of the profile's CTAS codes | encounter.triaged. Every other Observation is ignored |
ServiceRequest | Linked to an ED encounter; laboratory, imaging or ECG category | order.placed / order.status_changed: active → placed, on-hold → on hold, revoked/entered-in-error → cancelled. Consult categories → consult.status_changed |
Specimen | References a known order | Collected, received |
ImagingStudy | basedOn an order | Started → in progress; available → performed |
DiagnosticReport | basedOn an order | registered → in the lab; partial/preliminary → preliminary; final → resulted; amended/corrected/appended → corrected. result, conclusion, conclusionCode and presentedForm are dropped unread |
Appointment | basedOn an order | Scheduled, with start |
CareTeam | Encounter-level team (Oracle) | careteam.snapshot |
Task | focus is an order | Optional hints for in-progress and performed |
Practitioner, PractitionerRole, Location | Enrichment only |
Event ids are {sourceId}:fhir:{resourceType}/{id}/_history/{versionId or meta.lastUpdated}:{n}; recordedAt comes from meta.lastUpdated.
Vendor notes
Epic. The ED treatment team comes back as Encounter.participant, not CareTeam. Encounter search is scoped per patient in the public catalogue, and a general FHIR Subscription API isn't published, so most Epic sites send HL7 v2 (Bridges) for the real-time feed and use FHIR for enrichment or a SMART launch. Backend services use client_credentials with a private_key_jwt assertion signed with RS384 or ES384.
Oracle Health Millennium. CareTeam supports encounter-level teams with roles and periods, which fits the ED well. R4 Subscriptions aren't in the public documentation, so real-time events usually come from HL7 v2 outbound through Oracle's interface tooling.
Any vendor. A FHIR relay or subscription product in front of the EHR works with $ingest.
Worked example (synthetic, sandbox)
{
"resourceType": "Bundle",
"type": "batch",
"meta": { "tag": [{ "system": "http://terminology.hl7.org/CodeSystem/v3-ActReason", "code": "HTEST" }] },
"entry": [{
"resource": {
"resourceType": "Encounter", "id": "syn-enc-1", "meta": { "versionId": "1", "lastUpdated": "2026-09-14T12:02:14Z" },
"status": "arrived",
"class": { "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode", "code": "EMER" },
"identifier": [{ "system": "urn:example:visit", "value": "SYN3000123" }],
"period": { "start": "2026-09-14T08:02:11-04:00" },
"location": [{ "location": { "reference": "Location/edwr", "display": "Waiting room" }, "status": "active" }]
},
"request": { "method": "PUT", "url": "Encounter/syn-enc-1" }
}]
}This produces encounter.arrived at 08:02:11 in the waiting room.
Related
Dernière mise à jour le
Cette page vous a-t-elle été utile?
system.heartbeat
Feed liveness.
HL7 v2
Send HL7 v2 to EDFlow over HTTPS: supported versions and vendors (Epic Bridges, Oracle Health Millennium, MEDITECH), triggers and the events they produce, result and order status maps, the field map, character sets and escapes, the ACK table, and a worked example stream.