Integration guide

Connect your hospital systems to SkyScribe

SkyScribe speaks the protocols your systems already speak: HL7 v2 over HTTPS or MLLP, FHIR R4 for reads, and a DICOM modality worklist for imaging. You do not need an SDK, a library, or anything from us — a credential issued by the hospital and this page are the whole integration.

What you can build

  • Stop double registration. Send ADT when a patient registers in your HIS; they appear in SkyScribe with the same MRN.
  • Stop re-typing results.Send ORU from your LIS or RIS; values land on the patient’s record, on the trend chart, and into the clinical reasoning — and panic values raise an alert automatically.
  • Receive orders. When a doctor orders an investigation, SkyScribe sends you an ORM^O01 carrying a placer order number that comes back on your ORU, so the result files against the order, not just the patient.
  • Fill your modality worklists. Pull scheduled imaging as DICOM tags so the radiographer stops typing patient names into the console.
  • Read the record.Pull a patient’s full record as a FHIR R4 Bundle.

Getting a credential

The hospital issues it, not us. Their administrator goes to Settings → Integrations, clicks Add connector, and hands you the credential it shows. There is no approval queue and nothing to request from SkyScribe.

It looks like skc_live_a1b2c3d4e5f6a7b8.<secret> and is shown once. If it is lost, the administrator rotates it — which takes a few seconds and does not disturb the connector’s history. Send it as a bearer token:

Authorization: Bearer skc_live_a1b2c3d4e5f6a7b8.<secret>

The credential determines which hospital you are writing to. You never send a hospital id, and a facility name in MSH-4 does not change where data lands.

HL7 v2 over HTTPS

POST the raw message. Any of application/hl7-v2, text/hl7 or text/plain works. Segments are separated by \r (carriage return) as usual — not \n.

POST https://api.skyscribeai.com/api/v1/connectors/hl7
Authorization: Bearer skc_live_….<secret>
Content-Type: application/hl7-v2

MSH|^~\&|COBAS|CENTRALLAB|SKYSCRIBE|SKYSCRIBE|20260731003000||ADT^A04|MSG00001|P|2.5.1
…

You always get HTTP 200 with an ACK body, even when we refuse the message. Read MSA-1, not the HTTP status:

  • AA — accepted. We have taken responsibility; you may delete your copy.
  • AE — it reached us and we could not process it (bad data, unknown MRN). Do not retry blindly; MSA-3 says why.
  • AR — refused (auth, unsupported message type).

We return AE rather than AA whenever we could not file the data, precisely so a genuine result is never silently lost because you deleted it on our say-so.

ADT — patient registration

Supported triggers: A01 admit, A04 register, A05 pre-admit, A08/A28/A31 update, A03 discharge, A02 transfer.

PID-3 must carry an MRN. That is the only thing we match on. We do not match on name and date of birth, because that is how two people end up sharing one record. A message without an MRN gets an AE.

Sending the same message twice is safe — we upsert on the MRN. A08/A31 updates demographics on the existing patient; they never create a second one.

MSH|^~\&|HIS|MAINHOSP|SKYSCRIBE|SKYSCRIBE|20260731003000||ADT^A04|MSG00001|P|2.5.1
EVN|A04|20260731003000
PID|1||MRN-77219^^^MAINHOSP^MR||Kumar^Ramesh^^^Mr||19680411|M|||14 Residency Rd^^Bengaluru^KA^560025^IN||9845012345
PV1|1|O|OPD^^^MAINHOSP||||DOC001^Iyer^Meera^^^Dr

ORU — results

ORU^R01. One message may carry several OBR groups, each with its own OBX observations and NTE comments. We honour OBX-11 status: P preliminary, F final, C corrected, X/D cancelled (cancelled observations are not filed).

Populate OBR-2 with the placer order number we sent you on the ORM. That is what attaches the result to the order rather than merely to the patient.

If the patient’s MRN is unknown to us you get an AE — send the ADT first. We will not invent a patient from a result message.

MSH|^~\&|COBAS|CENTRALLAB|SKYSCRIBE|SKYSCRIBE|20260731004500||ORU^R01|MSG00002|P|2.5.1
PID|1||MRN-77219^^^CENTRALLAB^MR||Kumar^Ramesh
OBR|1|ORD-5501|LAB-98231|RENAL^Renal Profile^L|||20260731003000|||||||||DOC001^Iyer^Meera||||||20260731004400||F
OBX|1|NM|2823-3^Potassium^LN||7.4|mmol/L|3.5-5.1|H|||F|||20260731003000
OBX|2|NM|2160-0^Creatinine^LN||2.9|mg/dL|0.7-1.3|H|||F|||20260731003000
NTE|1|L|Haemolysis not detected.

A note on safety: SkyScribe runs its owndeterministic panic-value check over every numeric result, against published limits. If your OBX-8 flag is missing or wrong, a critical potassium still raises a critical alert. Send your flags — we use them — but they are not what the patient’s safety depends on.

ORM — orders out to your LIS

Register a connector with direction: outbound or bidirectional and an endpoint URL. When a doctor orders an investigation, we POST an ORM^O01 to that URL, MLLP-framed (0x0B … 0x1C 0x0D), because most engines forward the body straight onto a socket and drop an unframed message.

Each ordered item gets its own ORC+ORB pair — bundling several analytes under one OBR is legal but many LIS implementations quietly file only the first.

MSH|^~\&|SKYSCRIBE|SKYSCRIBE|LIS|CENTRALLAB|20260731010000||ORM^O01|SKY20260731010000|P|2.5.1
PID|1||MRN-77219^^^^MR||Kumar Ramesh||19680411|M
ORC|NW|WI-8842||||||20260731010000|||Dr Meera Iyer
OBR|1|WI-8842||RENAL^Renal Profile^L|R|20260731010000||||||||||Dr Meera Iyer

WI-8842 is the placer order number. Echo it in OBR-2 of your ORU and the loop closes.

MLLP over TCP

If your system speaks MLLP rather than HTTPS — most on-premise LIS and RIS do — a SkyScribe instance deployed on the hospital’s own network can listen on a TCP port. Frames are the standard 0x0B0x1C 0x0D.

A socket has no headers, so send the credential as the first line, terminated by a newline, before the first frame:

skc_live_a1b2c3d4e5f6a7b8.<secret>\n
<0x0B>MSH|^~\&|COBAS|CENTRALLAB|…<0x1C><0x0D>
<0x0B>MSH|^~\&|COBAS|CENTRALLAB|…<0x1C><0x0D>

One credential per connection; every message on it is re-checked, so revoking a connector takes effect on the next message rather than the next reconnect. ACKs come back MLLP-framed on the same socket.

MLLP is plain TCP with no transport encryption, so it is only enabled on a deployment that has been put on a private network on purpose. The managed cloud service does not run it — use HTTPS there.

FHIR R4 read

A patient’s full record as a FHIR R4 Bundle, looked up by the MRN your system uses — you do not need to learn our identifiers.

GET https://api.skyscribeai.com/api/v1/connectors/fhir/Patient?mrn=MRN-77219
Authorization: Bearer skc_live_….<secret>

→ 200 application/fhir+json   { "resourceType": "Bundle", … }
→ 404                          no patient with that MRN in this hospital

Read-only, and it will stay read-only. Writes come in as HL7, where the append-only timeline, the medication-safety guard, and the physician-approval rule all apply. A FHIR write endpoint would be a way around them.

DICOM modality worklist

Scheduled imaging, returned as DICOM tags so your broker or modality can copy them straight across.

GET https://api.skyscribeai.com/api/v1/connectors/worklist?modality=CT
Authorization: Bearer skc_live_….<secret>

[{
  "00100010": "Kumar^Ram",        // PatientName
  "00100020": "MRN-77219",        // PatientID
  "00100030": "19680411",         // PatientBirthDate
  "00100040": "M",                // PatientSex
  "00080050": "wi-8842-…",        // AccessionNumber  ← the join key
  "0020000D": "2.25.…",           // StudyInstanceUID
  "00321060": "CECT abdomen",     // RequestedProcedureDescription
  "00080060": "CT",               // Modality
  "00400002": "20260731",         // ScheduledProcedureStepStartDate
  "00400003": "140509"            // …StartTime
}]

Only PENDING and IN_PROGRESS studies appear — a completed study left on a worklist is how a patient gets scanned twice.

Omit ?modality= to get everything. Studies whose modality we could not infer from the request are returned on every query rather than hidden on the wrong one: an extra row is a smaller problem than a missing study.

Modalities speak DICOM C-FIND over a raw socket, which does not cross the public internet. Point a small on-site broker (dcm4che, Orthanc, or your vendor’s own) at this endpoint and let it answer the scanner.

Testing safely

Set MSH-11 to T or D. We acknowledge the message normally — so your engine’s queue behaves exactly as it will in production — but nothing is filed and no patient is created.

That is the whole test mode. There is no separate sandbox host to configure, no second credential to manage, and no risk of your test data reaching a real chart.

MSH|^~\&|HIS|MAINHOSP|SKYSCRIBE|SKYSCRIBE|20260731||ADT^A04|TEST01|T|2.5.1
                                                                          ↑ T = test

Ask the hospital’s administrator for a second connector named “Integration testing” if you want your test traffic separated in the message log. They can revoke it when you go live.

When something does not arrive

The hospital’s administrator can see every message you sent us, what we did with it, and why, under Settings → Integrations. It shows the message type, your control id (MSH-10), the outcome, the reason, and the raw message.

So “did it arrive?” is answerable without contacting us. Quote your MSH-10 control id and they can find the exact message in seconds.

The common ones:

  • 401 — credential missing, malformed, or wrong. It must be the whole skc_live_….<secret> string after Bearer.
  • 403 — the connector was revoked. Ask the administrator.
  • AE “No patient with MRN…” — the ADT feed has not been switched on, or ran behind. Send the ADT first.
  • AE “PID-3 carries no medical record number” — your PID-3 is empty or has no MR-typed identifier.
  • AR “does not accept…” — that message type is not supported. We refuse rather than pretending, so you find out on day one.

Rules we will not bend

Stated up front so they are not a surprise in week three:

  • The credential decides the hospital.Not MSH-4, not a body field. One hospital’s feed can never write into another’s records.
  • We match patients on MRN only. Never on name and date of birth.
  • We never return AA for data we did not file. If you got AA, it is in the record.
  • Clinical safety is computed here, not trusted from you. Panic values, drug interactions and clinical scores are recalculated in our own tested code. Send yours; we will not depend on them.
  • FHIR is read-only. Writes go through HL7, where the clinical rules apply.
  • Nothing is deleted.Revoking a connector keeps its message history, so “which system filed this?” stays answerable.

Still stuck?

Email skyscribe@skyscribeai.com with your MSH-10 control id and the hospital’s name. Please check the message log first — it answers most questions faster than we can.

What SkyScribe does →