Neolung

Connecting the laboratory system to Neolung

For your integration team. Your engine calls Neolung over HTTPS, in HL7 v2 or FHIR R4 (UK Core); Neolung never calls it. An admin in your organisation creates its key in Neolung, in Settings, Integration, and sees there whether the engine is connected.

What it does

From your laboratory system

  • Each new specimen, as a draft case of its report type
  • The lab number, the specimen types and the requester's and site's codes, never the patient's details

Back to it, once signed

  • Every signed report, amendment, supplementary report and second opinion, part by part
  • SNOMED CT codes, in Lung resection (primary carcinoma) and Lung biopsy (small) reports
  • Structured data for your COSD submission

HL7 v2

1. Address and key

The engine calls Neolung over HTTPS, outbound from the trust: no port or VPN to open. Each request carries the organisation's key, which an admin creates in Neolung, in its Authorization header.

Address and header

https://app.neolung.io/api/integration/v1/hl7v2
Authorization: Bearer <key>

2. Test the connection

Neolung answers 200 when the key works. The admin sees the check in Neolung, in Settings, Integration.

Request

curl -H "Authorization: Bearer <key>" 'https://app.neolung.io/api/integration/v1/check'

3. Send each new specimen

One OML^O21 (2.5 and later) or ORM^O01 (2.3, 2.4) per lab number, in the body of a POST, segments separated by carriage returns or line feeds. Neolung answers with an ACK: AA, or AE or AR with the reason in words.

Request

curl -X POST -H "Authorization: Bearer <key>" -H "Content-Type: x-application/hl7-v2+er7" --data-binary @specimen.hl7 'https://app.neolung.io/api/integration/v1/hl7v2'

specimen.hl7

MSH|^~\&|LIMS|LAB|NEOLUNG|NEOLUNG|20261026090000||OML^O21^OML_O21|MSG00001|T|2.5.1
ORC|NW|PLACER1|ZZ26-00001
OBR|1|PLACER1|ZZ26-00001|HISTO^Histology^L
SPM|1|^ZZ26-00001||LOBE^Right upper lobectomy^L

4. Collect each signed report

Every minute, GET the oldest report waiting: an ORU^R01 (2.5.1, or 2.4 with ?version=2.4), or 204 when none waits. File it, then POST its ACK (AA filed, AE couldn't file), MSA-2 the report's MSH-10. The same report comes until it is acknowledged.

Request

curl -H "Authorization: Bearer <key>" 'https://app.neolung.io/api/integration/v1/hl7v2'

Acknowledgement

curl -X POST -H "Authorization: Bearer <key>" -H "Content-Type: x-application/hl7-v2+er7" --data-binary @ack.hl7 'https://app.neolung.io/api/integration/v1/hl7v2'

ack.hl7

MSH|^~\&|LIMS|LAB|NEOLUNG|NEOLUNG|20261026091000||ACK^R01^ACK|ACK00001|T|2.5.1
MSA|AA|<MSH-10 of the report>

5. Test messages first

Until the organisation is approved for patient data in Neolung, send messages marked as test (MSH-11 T): Neolung refuses production ones.

6. What Neolung reads

Only the lab number, the specimen types and the requester's and site's codes. Neolung never reads the patient, clinical details or notes, and never keeps them.

FHIR R4 (UK Core)

1. Address and key

The engine calls Neolung over HTTPS, outbound from the trust: no port or VPN to open. Each request carries the organisation's key, which an admin creates in Neolung, in its Authorization header.

Address and header

https://app.neolung.io/api/integration/v1/fhir
Authorization: Bearer <key>

2. Test the connection

Neolung answers 200 when the key works. The admin sees the check in Neolung, in Settings, Integration.

Request

curl -H "Authorization: Bearer <key>" 'https://app.neolung.io/api/integration/v1/check'

3. Send each new specimen

A ServiceRequest with its Specimens, as application/fhir+json: in a transaction or batch Bundle POSTed to the base, answered 200 with a response for each entry; or alone to /ServiceRequest, answered 201 with an OperationOutcome. The lab number is the Specimen's accessionIdentifier. A refusal says why in words.

Request

curl -X POST -H "Authorization: Bearer <key>" -H "Content-Type: application/fhir+json" --data-binary @specimen.json 'https://app.neolung.io/api/integration/v1/fhir'

specimen.json

{
  "resourceType": "Bundle",
  "type": "transaction",
  "meta": {
    "security": [
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-ActReason",
        "code": "HTEST"
      }
    ]
  },
  "entry": [
    {
      "fullUrl": "urn:uuid:5f0d1f1e-0000-4000-8000-000000000001",
      "resource": {
        "resourceType": "Specimen",
        "accessionIdentifier": {
          "value": "ZZ26-00001"
        },
        "type": {
          "text": "Right upper lobectomy"
        }
      },
      "request": {
        "method": "POST",
        "url": "Specimen"
      }
    },
    {
      "resource": {
        "resourceType": "ServiceRequest",
        "status": "active",
        "intent": "order",
        "specimen": [
          {
            "reference": "urn:uuid:5f0d1f1e-0000-4000-8000-000000000001"
          }
        ]
      },
      "request": {
        "method": "POST",
        "url": "ServiceRequest"
      }
    }
  ]
}

4. Collect each signed report

Every minute, GET the DiagnosticReports waiting (UK Core, oldest first). File each, then acknowledge it: outcome filed, or refused when the laboratory system couldn't file it. The same reports come until acknowledged.

Request

curl -H "Authorization: Bearer <key>" 'https://app.neolung.io/api/integration/v1/fhir/DiagnosticReport?_count=20'

Acknowledgement

curl -X POST -H "Authorization: Bearer <key>" -H "Content-Type: application/fhir+json" \
  -d '{"resourceType":"Parameters","parameter":[{"name":"outcome","valueCode":"filed"}]}' \
  'https://app.neolung.io/api/integration/v1/fhir/DiagnosticReport/<id>/$acknowledge'

5. Test messages first

Until the organisation is approved for patient data in Neolung, mark each request as test (the HTEST security label): Neolung refuses production ones.

6. What Neolung reads

Only the lab number, the specimen types and the requester's and site's codes. Neolung never reads the patient, clinical details or notes, and never keeps them.