Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card
Як імпортувати лабораторні результати до запису FHIR
Посібник: імпортуйте лабораторний звіт як CSV та як HL7 v2 ORU^R01 до FHIR R4 Observations з кодами LOINC та референтними діапазонами, обробляйте невідповідні маркери та повторні звіти, і відстежуйте кожен результат до його лабораторії.
Цей посібник розглядає лабораторний звіт у файлі CSV та як повідомлення HL7 v2 ORU^R01, імпортує його до запису HL7 FHIR R4 пацієнта одним запитом для кожного, і показує, що ви отримаєте у відповідь: лабораторні Observation ресурси з кодами LOINC, референтними діапазонами та походженням. Він також охоплює дві проблеми, з якими стикається кожна інтеграція лабораторії: маркери, які не можуть бути автоматично зіставлені, та звіти, які надсилаються двічі. Все працює на безкоштовному пісочниці з синтетичним пацієнтом.
Чому лабораторні результати важко зберігати
Лабораторний звіт виглядає просто: маркер, значення, одиниця вимірювання, референтний діапазон, дата. На практиці кожна лабораторія називає маркери по-своєму ("Глікозильований гемоглобін", "HbA1c", "Glycated haemoglobin"), використовує коми або крапки для десяткових знаків, пише діапазони як 4,0-5,6, <5 або >3.5, і повторно надсилає той самий звіт, коли щось йде не так. Збережені як вільний текст, ці результати неможливо порівняти з часом, відобразити на графіку, надати іншій програмі або впевнено передати моделі штучного інтелекту.
Запис FHIR зберігає кожен результат як Observation з кодом LOINC, одиницею UCUM, значенням, референтним діапазоном та датою, а також зберігає інформацію про відправника в ресурсі Provenance. Лабораторний конектор виконує це перетворення для вас.
lab report (CSV, HL7 v2, JSON)
│ POST /v1/patients/{id}/labs/import
▼
┌──────────────────────────────────────────────┐
│ parse rows → map marker to LOINC → parse │
│ value, unit, range → stable id per row │
└──────────────────────────────────────────────┘
│
▼
Observation (category laboratory) + Provenance (author_type import, source system, report id)
│
├─► the patient's app and every app they consented to
└─► webhooks: resource.created per Observation
Перед початком роботи
Вам потрібен ключ для пісочниці (sk_test_…) з platform.anpheros.com/dashboard (Отримати ключ для пісочниці). У прикладах використовується curl; SDK мають ті ж виклики (labs.importCsv, labs.importHl7, labs.importItems).
export BASE=https://platform.anpheros.com
export KEY=sk_test_…
# Elena Ionescu, a synthetic patient with type 2 diabetes
export PID=$(curl -s "$BASE/fhir/R4/Patient?identifier=https://anpheros.com/fhir/sid/sandbox-persona|p02" \
-H "Authorization: Bearer $KEY" | jq -r '.entry[0].resource.id')
Крок 1: імпорт CSV-звіту
Ось як румунська лабораторія може експортувати звіт: крапки з комою, десяткові коми, румунські назви стовпців та дати як DD.MM.YYYY. Конектор розпізнає румунські та англійські назви стовпців.
cat > report.csv <<'EOF'
Analiza;Rezultat;UM;Interval de referinta;Data
Hemoglobina glicozilata (HbA1c);6,9;%;4,0-5,6;01.10.2026
Glicemie;131;mg/dL;70-100;01.10.2026
TSH;2,1;mUI/L;0,4-4,0;01.10.2026
Marker foarte rar;12;U/L;0-20;01.10.2026
EOF
curl -X POST "$BASE/v1/patients/$PID/labs/import" -H "Authorization: Bearer $KEY" \
-H "Content-Type: text/csv" -H "X-Anpheros-Source-System: labx" \
-H "Idempotency-Key: report-2026-10-01-elena" --data-binary @report.csv
Відповідь (201):
{"created": 4, "skipped": 0, "unmapped": ["Marker foarte rar"], "warnings": [],
"observations": [
{"id": "ff0bbb44-…", "marker": "Hemoglobina glicozilata (HbA1c)", "code": "4548-4", "system": "http://loinc.org", "value": 6.9, "unit": "%", "date": "2026-10-01"},
{"id": "ebe5522f-…", "marker": "Glicemie", "code": "2345-7", "system": "http://loinc.org", "value": 131.0, "unit": "mg/dL", "date": "2026-10-01"},
{"id": "bace44a8-…", "marker": "TSH", "code": "3016-3", "system": "http://loinc.org", "value": 2.1, "unit": "mUI/L", "date": "2026-10-01"},
{"id": "26fd2270-…", "marker": "Marker foarte rar", "code": "marker_foarte_rar", "system": "urn:anpheros:lab-code", "value": 12.0, "unit": "U/L", "date": "2026-10-01"}]}
HbA1c, глюкоза та TSH були зіставлені з LOINC за їхніми назвами. Десяткові коми перетворилися на числа, а діапазони стали referenceRange. Один рядок повернувся в unmapped. Він все ще зберігається під власним кодом лабораторії (urn:anpheros:lab-code) з точним текстом зі звіту, тому нічого не втрачено.
Крок 2: обробка невідповідних маркерів
Деякі назви потребують рішення. "Glicemie" (рівень глюкози в крові) є гарним прикладом: LOINC має один код для глюкози в сироватці або плазмі (2345-7, венозний зразок, взятий у лабораторії) та інший для глюкози в цільній крові (2339-0, наприклад, при проколюванні пальця). У лабораторному звіті проста назва "Glicemie" зіставляється з сироваткою або плазмою. Назва, що містить "capilar", "capillary" або "sânge integral", зіставляється з цільною кров'ю:
{"created": 1, "skipped": 0, "unmapped": [], "warnings": [],
"observations": [{"id": "00480a6d-…", "marker": "Glicemie capilara", "code": "2339-0", "system": "http://loinc.org", "value": 140.0, "unit": "mg/dL", "date": "2026-10-02"}]}
Для маркерів, які конектор не розпізнає, знайдіть код:
curl "$BASE/v1/terminology/loinc?q=glucose" -H "Authorization: Bearer $KEY"
{"data": [
{"system": "http://loinc.org", "code": "2339-0", "display": "Glucose [Mass/volume] in Blood", "display_ro": "Glicemie (sânge)", "category": "laboratory", "unit": "mg/dL"},
{"system": "http://loinc.org", "code": "2345-7", "display": "Glucose [Mass/volume] in Serum or Plasma", "display_ro": "Glicemie (ser)", "category": "laboratory", "unit": "mg/dL"}],
"total": 2}
Потім надішліть код у стовпці LOINC. Код у звіті завжди має перевагу над назвою. Зберігайте це зіставлення для кожної лабораторії на своїй стороні та додавайте стовпець до кожного звіту з неї:
Analiza;Rezultat;UM;Interval de referinta;Data;LOINC
Glicemie;99;mg/dL;70-100;04.10.2026;2339-0
Маркери, які LOINC взагалі не охоплює, як-от вигаданий "Marker foarte rar", можуть залишатися під кодом лабораторії. Вони відображаються пацієнту та включаються до запису. Їх не можна порівнювати з результатами інших лабораторій.
Крок 3: надсилання одного й того ж звіту двічі
Лабораторії повторно надсилають звіти. Кожен рядок отримує стабільний ідентифікатор, створений з ідентифікатора звіту, коду, дати та значення, тому другий імпорт того самого звіту нічого не створює:
{"created": 0, "skipped": 4, "unmapped": ["Marker foarte rar"], "warnings": [], "observations": []}
Рядки, що змінилися, наприклад, виправлене значення, імпортуються як нові результати. Заголовок Idempotency-Key додає другу гарантію: повторна спроба мережі з тим самим ключем повертає першу відповідь без змін.
Крок 4: імпорт повідомлення HL7 v2 ORU^R01
Більшість лабораторних інформаційних систем використовують HL7 v2. Надішліть повідомлення як є (текст ER7, сегменти розділені CR або LF):
MSH|^~\&|LABX|LAB1|ANPHEROS|EHR|202610010930||ORU^R01|MSG00077|P|2.5.1
PID|1||12345||Ionescu^Elena||19850903|F
OBR|1||R-77|24331-1^Lipid panel^LN|||202610010800
OBX|1|NM|2093-3^Cholesterol [Mass/volume] in Serum or Plasma^LN||212|mg/dL|<200|H|||F|||202610010800
OBX|2|NM|2085-9^HDL Cholesterol^LN||52|mg/dL|>40|N|||F|||202610010800
curl -X POST "$BASE/v1/patients/$PID/labs/import" -H "Authorization: Bearer $KEY" \
-H "Content-Type: x-application/hl7-v2+er7" --data-binary @oru.hl7
{"created": 2, "skipped": 0, "unmapped": [], "warnings": [],
"observations": [
{"id": "b562045b-…", "marker": "Cholesterol [Mass/volume] in Serum or Plasma", "code": "2093-3", "system": "http://loinc.org", "value": 212.0, "unit": "mg/dL", "date": "2026-10-01T08:00:00Z"},
{"id": "9b3274e4-…", "marker": "HDL Cholesterol", "code": "2085-9", "system": "http://loinc.org", "value": 52.0, "unit": "mg/dL", "date": "2026-10-01T08:00:00Z"}]}
OBX-3 з кодовою системою LN використовується безпосередньо як LOINC. OBX-7 стає референсним діапазоном, а OBX-8 (H, N) — інтерпретацією. OBR-3 (R-77) зберігається як ідентифікатор звіту в provenance. Пацієнт — це той, що в URL: сегмент PID не використовується для пошуку пацієнта, тому неправильний PID не може прикріпити результати до іншої особи.
Вже маєте розпарсені результати? Надішліть JSON: {"date": "2026-10-01", "origin": "report-77", "items": [{"marker": "Ferritin", "value": 38, "unit": "ng/mL", "ref_low": 15, "ref_high": 150}]}. Ферритин відображається на LOINC 2276-4.
Крок 5: Читання результатів як FHIR
curl "$BASE/fhir/R4/Observation?patient=$PID&code=http://loinc.org|4548-4&_sort=-date&_count=1" \
-H "Authorization: Bearer $KEY"
Імпортований HbA1c, як збережено:
{
"resourceType": "Observation",
"id": "62b1b0c0-…",
"meta": {"versionId": "1", "lastUpdated": "2026-10-12T20:05:57.011Z"},
"identifier": [{"system": "urn:anpheros:lab-import", "value": "c52d3cd6449291d34f6bef1516d0ac05"}],
"status": "final",
"category": [{"coding": [{"system": "http://terminology.hl7.org/CodeSystem/observation-category", "code": "laboratory"}]}],
"code": {"coding": [{"system": "http://loinc.org", "code": "4548-4", "display": "Hemoglobin A1c/Hemoglobin.total in Blood"}],
"text": "Hemoglobina glicozilata (HbA1c)"},
"subject": {"reference": "Patient/…"},
"effectiveDateTime": "2026-10-01",
"valueQuantity": {"value": 6.9, "unit": "%"},
"referenceRange": [{"low": {"value": 4.0, "unit": "%"}, "high": {"value": 5.6, "unit": "%"}}]
}
LOINC display — це стандартна англійська назва. code.text зберігає власне формулювання лабораторії, тому пацієнт все ще бачить те, що було в паперовому звіті. Щоб дізнатися більше про ресурси та пошук, дивіться посібник FHIR platform та FHIR code systems.
Крок 6: перевірка відправника
curl "$BASE/v1/patients/$PID/provenance/Observation/62b1b0c0-…" -H "Authorization: Bearer $KEY"
{"data": [{"version": 1, "activity": "CREATE", "recorded": "2026-10-12T20:05:57.011000Z",
"author_type": "import", "author": "proj_…", "source_system": "labx", "origin_id": null,
"fhir": "Provenance/f15c4fee-…"}], "total": 1}
author_type: import та source_system: labx залишаються зі значенням. Коли ШІ-додаток пізніше читає цей результат через context API, він позначається як [import/labx], щоб модель могла відрізнити лабораторний результат від значення, введеного пацієнтом.
Що відбувається далі
- Пацієнт бачить результати у своєму додатку. Будь-який додаток, на доступ до якого він надав згоду, може їх прочитати в межах своїх областей дії (модель згоди та доступу).
- Для кожного Observation спрацьовує вебхук
resource.created, щоб інформаційна панель клініки або зведення ШІ могли оновитися без опитування. POST /fhir/R4/Observation/$validate?profile=eu-labзвітує, як результат співвідноситься з профілем лабораторного звіту HL7 Europe.- До 500 рядків на запит; обмеження перелічені в розділі Обмеження та ліміти швидкості.
Часті запитання
Які формати лабораторних звітів можна імпортувати у FHIR?
CSV з рядком заголовка (приймаються коми, крапки з комою або табуляція, десяткова кома), повідомлення HL7 v2 ORU^R01 та JSON. Звіти у форматі PDF можуть зберігатися як документи; витягнуті з них значення посилаються назад на документ.
Що відбувається з маркерами без коду LOINC?
Вони зберігаються під власним кодом лабораторії з точним текстом зі звіту та перелічені у unmapped. Додайте стовпець LOINC для цієї лабораторії, і вони будуть відображені. Код у звіті завжди має пріоритет над назвою.
Чи безпечно повторно надсилати звіт?
Так. Кожен рядок має стабільний ідентифікатор, створений зі звіту, коду, дати та значення, тому рядки, які вже були імпортовані, пропускаються; змінені рядки імпортуються як нові результати.
Чи може лабораторія імпортувати результати для будь-якого пацієнта?
Ні. Лабораторія імпортує дані для пацієнтів, для яких її проєкт був створений, або чиї записи особа надала їй через OAuth. Інші пацієнти для неї не існують (404).
Пов'язане
- API лабораторних результатів: HL7 v2 та FHIR поруч, і що повинен містити один результат
- Лабораторний конектор: кожна назва стовпця, поле HL7 та поле відповіді
- Інтероперабельність медичних даних: чому коди та походження роблять обмінені дані придатними для використання
- Медичні інтеграції: клініки, лабораторії, пристрої та сторонні додатки
- API медичних даних: запис окремих спостережень, станів та медикаментів
- Як створити медичний додаток зі штучним інтелектом з бекендом FHIR: використання цих результатів у відповіді ШІ
Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card