# API wyników laboratoryjnych: HL7 v2, FHIR i LOINC

> Jak wyniki laboratoryjne są przesyłane jako dane HL7 v2 i FHIR, co musi zawierać pojedynczy wynik i jak odbierać raporty laboratoryjne do rekordu FHIR, wraz z rzeczywistym przykładem.

Source: https://developers.anpheros.com/pl/guides/lab-results-api

**API wyników laboratoryjnych dostarcza wyniki laboratoryjne jako ustrukturyzowane dane — kod testu, wartość, jednostkę, zakres referencyjny, status i czas — zamiast pliku PDF, dzięki czemu oprogramowanie może je przechowywać, porównywać, wizualizować i udostępniać.** Obecnie dane te są przesyłane w trzech formach: wiadomości HL7 v2 ORU^R01 (nadal stanowiące kręgosłup komunikacji między laboratoriami a szpitalami), zasoby HL7 FHIR R4 `Observation` i `DiagnosticReport` (format nowoczesnych API) oraz specyficzne dla laboratorium eksporty CSV, JSON lub PDF. Ta strona wyjaśnia, jak poszczególne elementy pasują do siebie, co musi zawierać dobre API wyników laboratoryjnych i jak odbierać dane laboratoryjne do rekordu FHIR pacjenta za pomocą Anpheros.

## Kto wymienia wyniki badań laboratoryjnych i w jakim formacie

| Od → do | Zwykły format dzisiaj | Uwagi |
|---|---|---|
| Laboratorium → system szpitalny lub przychodni | HL7 v2 ORU^R01 (w USA często zgodnie z przewodnikiem HL7 v2.5.1 Laboratory Results Interface) | Zlecenia idą w przeciwnym kierunku jako komunikaty ORM/OML |
| Laboratorium → agencja zdrowia publicznego | Elektroniczne raportowanie wyników laboratoryjnych HL7 v2, coraz częściej FHIR | Tylko zgłaszalne schorzenia |
| System przychodni → aplikacja pacjenta | FHIR R4 poprzez API dostępu dla pacjenta | W USA certyfikowane EHR udostępniają wyniki laboratoryjne jako FHIR (US Core); w UE Europejska Przestrzeń Danych Zdrowotnych wymienia wyniki laboratoryjne wśród swoich priorytetowych kategorii danych |
| Laboratorium → pacjent | Raport PDF, portal, czasami CSV | Format, który większość pacjentów faktycznie otrzymuje |
| Aplikacja → model AI | Strukturalny kontekst zbudowany z Observations | Wymaga kodów i jednostek, aby był wiarygodny |

Kierunek ma znaczenie: laboratoryjny system informatyczny (LIS) jest źródłem prawdy dla wyniku, a każdy system poniżej przechowuje jego kopię. To, co sprawia, że kopie są godne zaufania, to fakt, że każdy z nich przechowuje kod, jednostkę, zakres i pochodzenie wartości.

## Co powinien zawierać jeden wynik laboratoryjny

Wynik mówiący jedynie „Glukoza 126” nie może być bezpiecznie zinterpretowany. Kompletny wynik zawiera:

- **Standardowy kod.** LOINC identyfikuje analit, próbkę i metodę: `2345-7` to glukoza w surowicy lub osoczu, `2339-0` to glukoza w pełnej krwi. Własny kod laboratorium może mu towarzyszyć.
- **Wartość z jednostką.** Najlepiej jednostkę UCUM (`mg/dL`, `mmol/L`, `10*3/uL`), aby wartości z dwóch laboratoriów można było przeliczyć i porównać.
- **Zakres referencyjny**, którego użyło laboratorium, oraz **flaga interpretacji** (H, L, N…), jeśli laboratorium ją podaje.
- **Status:** wstępny, ostateczny, poprawiony lub uzupełniony. Korekty się zdarzają; API musi pozwalać na przeglądanie nowej wersji bez utraty starej.
- **Czasy:** kiedy pobrano próbkę (`effectiveDateTime`) i kiedy opublikowano wynik (`issued`).
- **Pochodzenie:** które laboratorium je wyprodukowało i do którego raportu lub zlecenia należą.

W FHIR R4 każdy wynik to jedno `Observation` z `category = laboratory`, a raport grupujący je to `DiagnosticReport`, który wymienia Obserwacje w `result`. Prawidłowe przykłady obu, z błędami najczęściej zgłaszanymi przez walidatory, znajdują się w [przykładach FHIR R4 JSON](https://developers.anpheros.com/tools/fhir-examples/observation-lab-result) — zobacz także [przykład DiagnosticReport](https://developers.anpheros.com/tools/fhir-examples/diagnostic-report).

## HL7 v2 i FHIR obok siebie

Ten sam wynik panelu lipidowego, tak jak większość laboratoriów wysyła go dzisiaj i tak jak API powinno go przechowywać:

```
OBX|1|NM|2093-3^Cholesterol^LN||212|mg/dL|<200|H|||F|||20261002074500
```

| Pole HL7 v2 | Znaczenie | Element FHIR R4 Observation |
|---|---|---|
| OBX-3 `2093-3^Cholesterol^LN` | Test, zakodowany w LOINC | `code.coding` (system `http://loinc.org`) |
| OBX-5 `212`, OBX-2 `NM` | Wartość numeryczna | `valueQuantity.value` |
| OBX-6 `mg/dL` | Jednostka | `valueQuantity.unit` |
| OBX-7 `<200` | Zakres referencyjny | `referenceRange.high` |
| OBX-8 `H` | Flaga nieprawidłowości | `interpretation` |
| OBX-11 `F` | Wynik końcowy | `status = final` |
| OBX-14 | Czas obserwacji | `effectiveDateTime` |

Konwersja między nimi to głównie mapowanie pól. Trudniejsze aspekty leżą gdzie indziej: laboratoria, które wysyłają własne kody zamiast LOINC, liczby zapisane jako tekst (`"6,4"`, `"<5"`), zakresy w różnych notacjach oraz raporty wysyłane ponownie po upływie czasu. [Jak normalizować dane medyczne](https://developers.anpheros.com/pl/guides/normalize-medical-data) omawia te kwestie szczegółowo.

## Odbieranie wyników badań laboratoryjnych do rekordu FHIR z Anpheros

Anpheros przechowuje rekord każdego pacjenta jako HL7 FHIR R4 i posiada [łącznik laboratoryjny](https://developers.anpheros.com/pl/guides/lab-connector): jedno żądanie przyjmuje cały raport w formacie HL7 v2, CSV lub JSON i zwraca obserwacje laboratoryjne z kodami LOINC, zakresami referencyjnymi, interpretacją i pochodzeniem danych.

```bash
curl -s -X POST "https://platform.anpheros.com/v1/patients/$PID/labs/import" \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: x-application/hl7-v2+er7" \
  -H "X-Anpheros-Source-System: springfield-lis" \
  --data-binary @lipid-panel.hl7
```

Dla trójliniowego panelu lipidowego (cholesterol, HDL, trójglicerydy) odpowiedź, z lokalnego uruchomienia platformy, wygląda następująco:

```json
{
  "created": 3, "skipped": 0, "unmapped": [], "warnings": [],
  "observations": [
    {"id": "26ed9219-…", "marker": "Cholesterol", "code": "2093-3", "system": "http://loinc.org",
     "value": 212.0, "unit": "mg/dL", "date": "2026-10-02T07:45:00Z"},
    {"id": "2633d1d4-…", "marker": "HDL cholesterol", "code": "2085-9", "system": "http://loinc.org",
     "value": 48.0, "unit": "mg/dL", "date": "2026-10-02T07:45:00Z"},
    {"id": "a02520bb-…", "marker": "Triglyceride", "code": "2571-8", "system": "http://loinc.org",
     "value": 165.0, "unit": "mg/dL", "date": "2026-10-02T07:45:00Z"}
  ]
}
```

Każdy zapisany wynik to standardowa obserwacja FHIR R4, którą można odczytać za pomocą dowolnego klienta FHIR:

```json
{
  "resourceType": "Observation",
  "status": "final",
  "category": [{"coding": [{"system": "http://terminology.hl7.org/CodeSystem/observation-category", "code": "laboratory"}]}],
  "code": {"coding": [{"system": "http://loinc.org", "code": "2093-3",
                        "display": "Cholesterol [Mass/volume] in Serum or Plasma"}], "text": "Cholesterol"},
  "subject": {"reference": "Patient/4c3062d9-…"},
  "effectiveDateTime": "2026-10-02T07:45:00Z",
  "valueQuantity": {"value": 212.0, "unit": "mg/dL"},
  "interpretation": [{"coding": [{"system": "http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation", "code": "H"}]}],
  "referenceRange": [{"high": {"value": 200.0, "unit": "mg/dL"}}]
}
```

Ponowne wysłanie tej samej wiadomości niczego nowego nie tworzy (`"created": 0, "skipped": 3`): każdy wiersz otrzymuje stabilny identyfikator na podstawie identyfikatora raportu, kodu, daty i wartości. Znaczniki, których platforma nie może zmapować na LOINC, zachowują kod laboratorium i wracają w `unmapped`, dzięki czemu można poprawić mapowanie u źródła.

Odczytywanie wyników z powrotem to standardowe wyszukiwanie FHIR:

```bash
curl -s "https://platform.anpheros.com/fhir/R4/Observation?patient=$PID&category=laboratory&code=http://loinc.org|2093-3" \
  -H "Authorization: Bearer $KEY"
```

Inne sposoby wprowadzania i wyprowadzania tych samych danych:

- **Bezpośrednio FHIR:** `POST /fhir/R4/Observation` lub transakcyjny Bundle zawierający `DiagnosticReport` i jego Obserwacje razem.
- **Zdarzenia:** [webhook](https://developers.anpheros.com/pl/guides/webhooks) `resource.created` dla każdej Obserwacji, dzięki czemu klinika lub aplikacja może zareagować po otrzymaniu wyników.
- **Dla ludzi i AI:** pacjent widzi wyniki w swojej aplikacji; aplikacje, na których odczyt wyrazi zgodę; `POST /v1/context` dostarcza modelowi AI podsumowanie z oznaczeniem źródła, które zawiera ostatnie wartości laboratoryjne.
- **Pochodzenie danych:** każdy zaimportowany wynik rejestruje `author_type = import`, system źródłowy i identyfikator raportu ([pochodzenie danych medycznych](https://developers.anpheros.com/pl/guides/medical-data-provenance)).

Pełny opis krok po kroku, z raportem CSV, wiadomością HL7 v2, niezmapowanymi znacznikami i ponowionymi raportami dla syntetycznego pacjenta, znajduje się w tutorialu [Jak zaimportować wyniki badań laboratoryjnych do rekordu FHIR](https://developers.anpheros.com/pl/guides/import-lab-results-fhir).

## Sprawdź wyniki przed wysłaniem

Bezpłatny [walidator FHIR R4](https://developers.anpheros.com/tools/fhir-validator) sprawdza strukturę Obserwacji i wymagane zestawy wartości, a dzięki profilowi `eu-lab` sprawdza również, co powinien zawierać wynik laboratoryjny: kategorię `laboratory`, kod LOINC, temat, status typu końcowego, czas, wartość, jednostkę UCUM i zakres referencyjny. Te same kontrole są przeprowadzane na platformie za pośrednictwem `POST /fhir/R4/Observation/$validate?profile=eu-lab`.

## Wybór API wyników laboratoryjnych: lista kontrolna

- Czy wyniki są przechowywane jako obserwacje FHIR R4 z kodami LOINC, czy jako wiersze we własnym schemacie?
- Czy może przyjmować formaty, które faktycznie wysyłają laboratoria (HL7 v2 w większości szpitali, CSV lub PDF z mniejszych laboratoriów)?
- Co dzieje się z markerem, którego nie można zmapować: czy jest odrzucany, pomijany, czy zachowywany z kodem laboratorium?
- Czy ponawianie prób jest bezpieczne, czy ponowne wysłanie raportu tworzy duplikaty?
- Czy poprawione wyniki są wersjonowane, a wcześniejsza wartość jest nadal czytelna?
- Czy pochodzenie każdej wartości jest rejestrowane i widoczne dla pacjenta?
- Kto może odczytać wyniki i czy jest to decydowane przez zgodę pacjenta?

## Czego Anpheros nie robi

Anpheros nie jest systemem informatycznym laboratorium i nie jest połączony z komercyjnymi sieciami laboratoryjnymi: raport wysyła laboratorium, klinika lub aplikacja pacjenta. Nie obsługuje zleceń laboratoryjnych, nie odczytuje raportów PDF za pośrednictwem tego API (aplikacja Anpheros Daily wyodrębnia wyniki ze zdjęć i plików PDF po stronie pacjenta) i nie interpretuje wyników klinicznie. Jednostki są przechowywane w takiej postaci, w jakiej wysyła je laboratorium; konwersja do kodów UCUM leży po stronie nadawcy, zgodnie z opisem w [Jak normalizować dane medyczne](https://developers.anpheros.com/pl/guides/normalize-medical-data).

## Często zadawane pytania

### Czym jest API wyników laboratoryjnych?
Interfejs, który pozwala oprogramowaniu wysyłać lub odbierać wyniki laboratoryjne jako ustrukturyzowane dane — zakodowany test, wartość z jednostką, zakres referencyjny, status i czas — zamiast jako dokument. Nowoczesne API wyników laboratoryjnych wykorzystują zasoby HL7 FHIR R4 Observation i DiagnosticReport; większość laboratoriów nadal emituje komunikaty HL7 v2 ORU^R01.

### Który system kodowania identyfikuje testy laboratoryjne?
LOINC. Każdy kod LOINC nazywa analit, próbkę i często metodę, dlatego `2345-7` (glukoza w surowicy lub osoczu) i `2339-0` (glukoza w pełnej krwi) to różne wyniki. Jednostki najlepiej wyrażać w UCUM.

### Jaka jest różnica między Observation a DiagnosticReport?
Observation to pojedynczy wynik, na przykład cholesterol 212 mg/dL. DiagnosticReport to raport jako całość — zlecony panel, kto go wydał i kiedy — i zawiera listę swoich Observation w `result`.

### Czy mogę zaimportować komunikaty HL7 v2 dotyczące badań laboratoryjnych na serwer FHIR?
Tak. Każdy segment OBX jest mapowany na jedną Observation (OBX-3 do `code`, OBX-5 i OBX-6 do `valueQuantity`, OBX-7 do `referenceRange`, OBX-8 do `interpretation`). Łącznik laboratoryjny Anpheros wykonuje to w jednym żądaniu i przechowuje identyfikator raportu laboratorium w Provenance.

### Jak uniknąć duplikatów wyników laboratoryjnych, gdy raport jest wysyłany ponownie?
Nadaj każdemu wynikowi stabilny identyfikator pochodzący z raportu, testu, czasu i wartości, a następnie pomiń wiersze, których identyfikator już istnieje. Łącznik laboratoryjny Anpheros robi to automatycznie i raportuje liczbę jako `skipped`.

## Powiązane

- [Mapowanie HL7 v2 na FHIR](https://developers.anpheros.com/pl/guides/hl7-v2-to-fhir-mapping): każdy segment i pole OBX
- [Jak zaimportować wyniki laboratoryjne do rekordu FHIR](https://developers.anpheros.com/pl/guides/import-lab-results-fhir): samouczek krok po kroku
- [Łącznik laboratoryjny](https://developers.anpheros.com/pl/guides/lab-connector): dokumentacja punktu końcowego
- [Jak normalizować dane medyczne](https://developers.anpheros.com/pl/guides/normalize-medical-data): LOINC, UCUM, daty, zakresy i duplikaty
- [Wyjaśnienie pochodzenia danych medycznych](https://developers.anpheros.com/pl/guides/medical-data-provenance)
- [Systemy kodowania FHIR](https://developers.anpheros.com/pl/guides/fhir-code-systems)
- [Jak zintegrować systemy kliniczne z backendem FHIR](https://developers.anpheros.com/pl/guides/integrate-clinic-systems-fhir)
- [FHIR vs HL7 v2: praktyczne różnice](https://developers.anpheros.com/pl/guides/fhir-vs-hl7-v2)
- [HL7 v2 i FHIR dla pulpitów nawigacyjnych klinicznych](https://developers.anpheros.com/pl/guides/clinical-dashboard-hl7-fhir): od wiadomości laboratoryjnej do kafelka pulpitu nawigacyjnego
