# Lab connector

> Send a whole laboratory report as CSV, HL7 v2 ORU^R01 or JSON and get laboratory Observations with LOINC codes and reference ranges.

Source: https://developers.anpheros.com/guides/lab-connector

A laboratory (or anyone holding a lab report) sends the whole report in one request and the
platform turns every result into a laboratory `Observation` of the patient:

```
POST /v1/patients/{patient_id}/labs/import
Authorization: Bearer <project key>
Content-Type: text/csv | x-application/hl7-v2+er7 | application/json
X-Anpheros-Source-System: labx        (optional; recorded in Provenance)
Idempotency-Key: <report id>          (optional; a retry returns the same answer)
```

## Formats

**CSV** with a header row; separators `,` `;` or tab, decimal comma accepted, dates ISO,
`DD.MM.YYYY` or `DD/MM/YYYY`. Recognised columns (Romanian or English): marker
(`analiza`, `test`, `marker`), value (`rezultat`, `valoare`, `value`), unit (`um`, `unitate`),
reference range (`interval`, `referinta`: `70-100`, `<5`, `>3.5`) or `ref_low`/`ref_high`,
date (`data`, `recoltare`), optional LOINC (`loinc`, `code`), note.

```
Analiza;Rezultat;UM;Interval de referinta;Data
Hemoglobina glicozilata (HbA1c);6,4;%;4,0-5,6;01.09.2026
TSH;2,1;mUI/L;0,4-4,0;01.09.2026
```

**HL7 v2 ORU^R01** (ER7 text, segments separated by CR or LF): `OBX-3` identifier (`code^text^LN`
is LOINC; other coding systems are kept as the lab's code), `OBX-5` value (`NM`, `SN`, or text),
`OBX-6` unit, `OBX-7` reference range, `OBX-8` abnormal flag → `interpretation`, `OBX-11` status,
`OBX-14` or `OBR-7` date; `OBR-3`/`MSH-10` become the report id in Provenance.

**JSON**: `{"date": "2026-09-01", "origin": "report-77", "items": [{"marker": "TSH", "value": 2.1, "unit": "mUI/L", "ref_low": 0.4, "ref_high": 4.0, "date": "2026-09-01", "code": "3016-3"}]}`.

## What you get back

```json
{"created": 3, "skipped": 0, "unmapped": ["Marker foarte rar"], "warnings": [],
 "observations": [{"id": "…", "marker": "TSH", "code": "3016-3", "system": "http://loinc.org", "value": 2.1, "unit": "mUI/L", "date": "2026-09-01"}]}
```

- Markers are mapped to **LOINC** when the report gives a LOINC code or the name matches the
  platform's terminology (Romanian and English names and common aliases). Others keep the lab's
  code under `urn:anpheros:lab-code` with the exact text from the report, and are listed in `unmapped`
  so you can improve the mapping on your side.
- Each row gets a stable identifier (`urn:anpheros:lab-import`) built from the report id, code, date
  and value: **re-sending the same report skips rows already imported** (`skipped`).
- Every Observation carries Provenance with `author_type = import`, your source system and the report id;
  webhooks fire `resource.created` per Observation; the patient sees the results in their app and any
  app they consented to can read them.
- Up to 500 rows per request.

Both SDKs: `labs.importCsv`, `labs.importHl7`, `labs.importItems`.
