{"openapi":"3.1.0","info":{"title":"NEDOCS Integration API","version":"1.0.0","description":"Ingest HL7 v2 (ADT/ORU/ORM) or REST score inputs; read the computed NEDOCS score/level. Authentication uses a per-hospital API key sent as `Authorization: Bearer <key>`, `X-API-Key: <key>`, or an `id` field.","contact":{"name":"NEDOCS","url":"https://nedocs.org/Home/RequestAccess"},"license":{"name":"Proprietary"}},"servers":[{"url":"https://nedocs.org"}],"tags":[{"name":"HL7 ingest","description":"HL7 v2 message ingestion."},{"name":"Hospital API v2","description":"JSON score submit/read (bearer auth; keys never in URLs)."},{"name":"Bed tracking","description":"Live bed board: units, beds, patient flow, events, and the FHIR R4 facade."},{"name":"NEDOCS Protocol (NP/1)","description":"Open federation: registry, signed beacons, routing exchange."}],"externalDocs":{"description":"HL7 & EHR integration guide","url":"https://nedocs.org/Product/HL7"},"paths":{"/api/hl7/message":{"post":{"summary":"Ingest any HL7 message (routed by MSH-9)","operationId":"ingestHl7Message","tags":["HL7 ingest"],"security":[{"bearerAuth":[]},{"apiKeyHeader":[]},{"apiKeyQuery":[]}],"parameters":[{"name":"ack","in":"query","required":false,"schema":{"type":"string","enum":["hl7"]},"description":"Set to 'hl7' to receive a raw HL7 ACK instead of JSON."}],"requestBody":{"description":"Raw HL7 v2 message, or JSON wrapping it.","required":true,"content":{"text/plain":{"schema":{"type":"string","example":"MSH|^~\\&|EPIC|HOSP|NEDOCS|HOSP|20260701120000||ADT^A04|M1|P|2.5\rEVN|A04|20260701120000\rPV1|1|E|EMERG^ED^BED1|||||||||||||||||V1001^^^HOSP^VN"}},"application/hl7-v2":{"schema":{"type":"string"}},"application/json":{"schema":{"type":"object","required":["message"],"properties":{"message":{"type":"string","description":"Raw HL7 v2 message."}}}}}},"responses":{"200":{"description":"Message accepted (AA). May include a freshly computed score.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestResult"}},"application/hl7-v2":{"schema":{"type":"string","description":"HL7 ACK (MSA|AA|...) when ?ack=hl7 or Accept: application/hl7-v2."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestError"}}}},"422":{"description":"Application error while processing (AE).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestResult"}}}}}}},"/api/hl7/adt":{"post":{"summary":"Ingest an HL7 ADT message","operationId":"ingestHl7Adt","tags":["HL7 ingest"],"security":[{"bearerAuth":[]},{"apiKeyHeader":[]},{"apiKeyQuery":[]}],"parameters":[{"name":"ack","in":"query","required":false,"schema":{"type":"string","enum":["hl7"]},"description":"Set to 'hl7' to receive a raw HL7 ACK instead of JSON."}],"requestBody":{"description":"Raw HL7 v2 message, or JSON wrapping it.","required":true,"content":{"text/plain":{"schema":{"type":"string","example":"MSH|^~\\&|EPIC|HOSP|NEDOCS|HOSP|20260701120000||ADT^A04|M1|P|2.5\rEVN|A04|20260701120000\rPV1|1|E|EMERG^ED^BED1|||||||||||||||||V1001^^^HOSP^VN"}},"application/hl7-v2":{"schema":{"type":"string"}},"application/json":{"schema":{"type":"object","required":["message"],"properties":{"message":{"type":"string","description":"Raw HL7 v2 message."}}}}}},"responses":{"200":{"description":"Message accepted (AA). May include a freshly computed score.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestResult"}},"application/hl7-v2":{"schema":{"type":"string","description":"HL7 ACK (MSA|AA|...) when ?ack=hl7 or Accept: application/hl7-v2."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestError"}}}},"422":{"description":"Application error while processing (AE).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestResult"}}}}}}},"/api/hl7/oru":{"post":{"summary":"Ingest an HL7 ORU^R01 (flowsheet) message","operationId":"ingestHl7Oru","tags":["HL7 ingest"],"security":[{"bearerAuth":[]},{"apiKeyHeader":[]},{"apiKeyQuery":[]}],"parameters":[{"name":"ack","in":"query","required":false,"schema":{"type":"string","enum":["hl7"]},"description":"Set to 'hl7' to receive a raw HL7 ACK instead of JSON."}],"requestBody":{"description":"Raw HL7 v2 message, or JSON wrapping it.","required":true,"content":{"text/plain":{"schema":{"type":"string","example":"MSH|^~\\&|EPIC|HOSP|NEDOCS|HOSP|20260701120000||ADT^A04|M1|P|2.5\rEVN|A04|20260701120000\rPV1|1|E|EMERG^ED^BED1|||||||||||||||||V1001^^^HOSP^VN"}},"application/hl7-v2":{"schema":{"type":"string"}},"application/json":{"schema":{"type":"object","required":["message"],"properties":{"message":{"type":"string","description":"Raw HL7 v2 message."}}}}}},"responses":{"200":{"description":"Message accepted (AA). May include a freshly computed score.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestResult"}},"application/hl7-v2":{"schema":{"type":"string","description":"HL7 ACK (MSA|AA|...) when ?ack=hl7 or Accept: application/hl7-v2."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestError"}}}},"422":{"description":"Application error while processing (AE).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestResult"}}}}}}},"/api/hl7/orm":{"post":{"summary":"Ingest an HL7 ORM^O01 (order) message","operationId":"ingestHl7Orm","tags":["HL7 ingest"],"security":[{"bearerAuth":[]},{"apiKeyHeader":[]},{"apiKeyQuery":[]}],"parameters":[{"name":"ack","in":"query","required":false,"schema":{"type":"string","enum":["hl7"]},"description":"Set to 'hl7' to receive a raw HL7 ACK instead of JSON."}],"requestBody":{"description":"Raw HL7 v2 message, or JSON wrapping it.","required":true,"content":{"text/plain":{"schema":{"type":"string","example":"MSH|^~\\&|EPIC|HOSP|NEDOCS|HOSP|20260701120000||ADT^A04|M1|P|2.5\rEVN|A04|20260701120000\rPV1|1|E|EMERG^ED^BED1|||||||||||||||||V1001^^^HOSP^VN"}},"application/hl7-v2":{"schema":{"type":"string"}},"application/json":{"schema":{"type":"object","required":["message"],"properties":{"message":{"type":"string","description":"Raw HL7 v2 message."}}}}}},"responses":{"200":{"description":"Message accepted (AA). May include a freshly computed score.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestResult"}},"application/hl7-v2":{"schema":{"type":"string","description":"HL7 ACK (MSA|AA|...) when ?ack=hl7 or Accept: application/hl7-v2."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestError"}}}},"422":{"description":"Application error while processing (AE).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestResult"}}}}}}},"/api/hl7/status":{"get":{"summary":"HL7 pipeline status for the authenticated hospital","operationId":"hl7Status","tags":["HL7 ingest"],"security":[{"bearerAuth":[]},{"apiKeyHeader":[]},{"apiKeyQuery":[]}],"responses":{"200":{"description":"Pipeline status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Hl7Status"}}}},"401":{"description":"Missing or invalid API key."}}}},"/api/v2/scores":{"post":{"summary":"Submit NEDOCS score inputs (Hospital API v2, JSON)","operationId":"submitScoreV2","tags":["Hospital API v2"],"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Replay-safe writes: identical retries within 24h return the stored response."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoreInputsV2"}}}},"responses":{"201":{"description":"Score computed and saved.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoreResourceV2"}}}},"401":{"description":"Missing or invalid API key (problem+json)."},"422":{"description":"Validation failed; per-field errors (problem+json)."}}},"get":{"summary":"Score history","operationId":"listScoresV2","tags":["Hospital API v2"],"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"parameters":[{"name":"from","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"limit","in":"query","schema":{"type":"integer","maximum":500,"default":200}}],"responses":{"200":{"description":"Scores in range, oldest first."}}}},"/api/v2/scores/current":{"get":{"summary":"Read the current NEDOCS score","operationId":"getCurrentScoreV2","tags":["Hospital API v2"],"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"responses":{"200":{"description":"Current score.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoreResourceV2"}}}},"404":{"description":"No score recorded yet (problem+json)."}}}},"/api/v2/hospital":{"get":{"summary":"Hospital identity, bed counts, and NP/1 protocol status","operationId":"getHospitalV2","tags":["Hospital API v2"],"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"responses":{"200":{"description":"Hospital resource."}}}},"/api/v2/beacon":{"get":{"summary":"This hospital's signed NP/1 capacity beacon","operationId":"getOwnBeaconV2","tags":["Hospital API v2"],"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"responses":{"200":{"description":"Signed np.beacon document (see /np/v1/schemas/beacon.json)."}}}},"/np/v1/registry":{"get":{"summary":"NEDOCS Protocol node registry (public)","operationId":"npRegistry","tags":["NEDOCS Protocol (NP/1)"],"parameters":[{"name":"kind","in":"query","schema":{"type":"string"}},{"name":"state","in":"query","schema":{"type":"string"}},{"name":"lat","in":"query","schema":{"type":"number"}},{"name":"lng","in":"query","schema":{"type":"number"}},{"name":"radiusKm","in":"query","schema":{"type":"number","default":80}}],"responses":{"200":{"description":"Registered nodes with keys and endpoints."}}}},"/np/v1/nodes/{nodeId}/beacon":{"get":{"summary":"A node's signed capacity beacon (grant-aware detail)","operationId":"npBeacon","tags":["NEDOCS Protocol (NP/1)"],"parameters":[{"name":"nodeId","in":"path","required":true,"schema":{"type":"string"}}],"security":[{"bearerAuth":[]},{}],"responses":{"200":{"description":"Signed np.beacon. Anonymous callers get band-level detail per node policy; agency keys with an active grant get full detail."},"401":{"description":"Node does not publish a public beacon."},"403":{"description":"No active data-sharing grant."}}}},"/api/v2/beds":{"get":{"summary":"List units and beds with live status (bed tracking)","operationId":"listBeds","tags":["Bed tracking"],"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"parameters":[{"name":"unit","in":"query","schema":{"type":"string"},"description":"Filter to one unit id."}],"responses":{"200":{"description":"Beds with status, patient-flow snapshot, and FHIR links."}}}},"/api/v2/beds/{bedId}":{"post":{"summary":"Apply a bed operation (status | assign | patientStatus | release)","operationId":"updateBed","tags":["Bed tracking"],"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"parameters":[{"name":"bedId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["op"],"properties":{"op":{"type":"string","enum":["status","assign","patientStatus","release"]},"status":{"type":"string","description":"Bed status (op=status) or patient status (op=patientStatus)."},"toStatus":{"type":"string","description":"Bed status after release (default Dirty)."},"patient":{"type":"object","description":"For op=assign. De-identified label only.","properties":{"label":{"type":"string"},"visitNumber":{"type":"string"},"status":{"type":"string"},"acuity":{"type":"integer","minimum":1,"maximum":5},"attending":{"type":"string"},"note":{"type":"string"}}}}}}}},"responses":{"200":{"description":"Updated bed + any newly fired flow triggers."},"422":{"description":"Invalid op or transition (problem+json)."}}}},"/api/v2/beds/events":{"get":{"summary":"Bed-flow event log (placements, releases, status changes, triggers)","operationId":"listBedEvents","tags":["Bed tracking"],"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"parameters":[{"name":"from","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"limit","in":"query","schema":{"type":"integer","maximum":1000,"default":200}}],"responses":{"200":{"description":"Events, newest first, with time-in-status durations."}}}},"/fhir/r4/Location":{"get":{"summary":"Beds and units as FHIR R4 Location resources","operationId":"fhirLocations","tags":["Bed tracking"],"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"parameters":[{"name":"physical-type","in":"query","schema":{"type":"string","enum":["bd","wa"]}},{"name":"operational-status","in":"query","schema":{"type":"string"},"description":"HL7 v2-0116 code (U O K H C I)."},{"name":"partof","in":"query","schema":{"type":"string"},"description":"Location/unit-<unitId>"}],"responses":{"200":{"description":"FHIR searchset Bundle. operationalStatus uses v2-0116."}}}},"/np/v1/routing/requests":{"post":{"summary":"Create a routing request (RFR) — the structured ringdown","operationId":"npCreateRoutingRequest","tags":["NEDOCS Protocol (NP/1)"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"See /np/v1/schemas/routing-request.json (de-identified; PHI is schema-forbidden)."}}}},"responses":{"201":{"description":"RFR created; signed offers from every granted candidate node are returned inline."},"422":{"description":"No protocol-enabled candidates with an active grant."}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Authorization: Bearer <hospital-api-key> (or agency key on NP/1 endpoints)"},"apiKeyHeader":{"type":"apiKey","in":"header","name":"X-API-Key"},"apiKeyQuery":{"type":"apiKey","in":"query","name":"id","description":"Legacy HL7-ingest only; not accepted by /api/v2."}},"schemas":{"IngestResult":{"type":"object","properties":{"ok":{"type":"boolean"},"ack":{"type":"string","enum":["AA","AE","AR"]},"family":{"type":"string","enum":["ADT","ORU","ORM","ACK","OTHER"]},"messageType":{"type":"string","example":"ADT^A02"},"messageControlId":{"type":"string"},"visitNumber":{"type":"string"},"scored":{"type":"boolean","description":"True when a new NEDOCS score was written."},"score":{"type":"integer"},"scaleColor":{"type":"string","enum":["Green","Yellow","Orange","Red","Black"]},"level":{"type":"integer","minimum":1,"maximum":5},"census":{"$ref":"#/components/schemas/Census"},"error":{"type":"string"}}},"IngestError":{"type":"object","properties":{"ok":{"type":"boolean","example":false},"ack":{"type":"string"},"error":{"type":"string"}}},"Census":{"type":"object","properties":{"totalPatients":{"type":"integer"},"totalAdmits":{"type":"integer"},"totalEDBeds":{"type":"integer"},"totalIPBeds":{"type":"integer"},"totalVentilators":{"type":"integer"},"longestAdmitMinutes":{"type":"integer"},"lastBedTimeMinutes":{"type":"integer"}}},"ScoreInputsV2":{"type":"object","required":["totalPatients","boardingAdmits","edBedsTotal","inpatientBedsTotal","criticalCarePatients","longestBoardMinutes","doorToBedMinutes"],"properties":{"totalPatients":{"type":"integer","minimum":0,"description":"Total patients in the ED (hallways, chairs, admits, waiting room)."},"boardingAdmits":{"type":"integer","minimum":0,"description":"Inpatient admits waiting (boarding) in the ED."},"edBedsTotal":{"type":"integer","minimum":0,"description":"Total ED beds, including hallways and chairs."},"inpatientBedsTotal":{"type":"integer","minimum":0,"description":"Total inpatient beds (excluding peds and OB)."},"criticalCarePatients":{"type":"integer","minimum":0,"description":"Critical care patients in the ED (1:1, ventilators)."},"longestBoardMinutes":{"type":"integer","minimum":0,"description":"Longest admit waiting in the ED, minutes."},"doorToBedMinutes":{"type":"integer","minimum":0,"description":"Door-to-bed time of the last patient bedded, minutes."}}},"ScoreResourceV2":{"type":"object","properties":{"id":{"type":"string"},"hospitalId":{"type":"string"},"eventTimeUtc":{"type":"string","format":"date-time"},"score":{"type":"integer"},"level":{"type":"integer","minimum":1,"maximum":5},"band":{"type":"string","enum":["Green","Yellow","Orange","Red","Black"]},"label":{"type":"string"},"inputs":{"$ref":"#/components/schemas/ScoreInputsV2"},"links":{"type":"object","additionalProperties":{"type":"string"}}}},"Hl7Status":{"type":"object","properties":{"ok":{"type":"boolean"},"hospitalId":{"type":"string"},"connected":{"type":"boolean"},"lastMessageAt":{"type":"string","format":"date-time","nullable":true},"lastMessageType":{"type":"string","nullable":true},"messages24h":{"type":"integer"},"activeEdEncounters":{"type":"integer"}}}}}}