Data Plane
How Standardization Works
How structured readings become coded, unit-normalized, FHIR-mirrored data.
Health data arrives messy — “血糖(空腹)”, “FBG”, “Glucose, fasting” all name the same indicator, and the units vary just as much. Mirobody standardizes every structured reading written through POST /v1/data or stored by POST /v1/standardize, so the agent and your queries see one coherent, coded dataset.
POST /v1/files is a separate storage and text-extraction surface; uploading a file standardizes its report values into structured readings automatically. /v1/standardize is the explicit path for that same extraction — use it to inspect the result (dry-run), or to standardize text / file_key sources on demand.
The pipeline
Section titled “The pipeline”Both a document and a structured record enter the same pipeline:
- Read the source PDF / image → text (OCR); Excel → rows.
- Pull out readings Find each
{indicator, value, unit, date}. Documents only — a/v1/datarecord is already structured and skips straight to coding. - Code the indicator Match the name to a LOINC code. With no confident match,
loinc_codestaysnull— never a wrong code. - Normalize the unit Fold the unit spelling to one UCUM form and parse the value to a number:
"mg/dl"→mg/dL. - Mirror to FHIR One FHIR R4
Observationper reading, addressable byfhir_resource_id.
The important part is step 3: codes are matched, never invented. A model is great at reading a document but shouldn’t be trusted to recite a code system — a wrong LOINC code is worse than none. So when the match isn’t confident, Mirobody keeps the raw name and leaves loinc_code null rather than guess.
Before / after
Section titled “Before / after”What you send to /v1/data (or what /v1/standardize reads from a report) vs. what the structured store holds:
| Before (as written) | After (standardized) | |
|---|---|---|
| Indicator | "血糖(空腹)" / "FBG" / "Glucose, fasting" | loinc_code: "1558-6", canonical_name: "Fasting glucose [Mass/volume] in Serum or Plasma" |
| Value | "97 mg/dL" (one string) | value: "97" (raw value, no unit), parsed_value: "97", parsed_unit: "mg/dL" (UCUM) |
| Unit spelling | "mg/dl", "MG/DL", "mg/dL" | "mg/dL" (one UCUM form) |
| Interop | free text | FHIR R4 Observation (fhir_resource_id) |
| Original | — | kept: value holds the raw value as written (e.g. 97, no unit appended — the unit rides in parsed_unit); raw names/units preserved |
Three spellings of the same test become one series — trend queries, the agent’s data tools, and your own analytics all see it as one indicator.
Where you see it
Section titled “Where you see it”| Surface | What appears |
|---|---|
POST /v1/data | Response counts standardized alongside ingested. |
GET /v1/data | Every row carries parsed_value / parsed_unit / loinc_code / canonical_name / fhir_resource_id. |
POST /v1/standardize | The whole pipeline as a synchronous call — dry-run by default, so you can inspect standardization before committing a write. |
| The agent | Grounded answers query the standardized series — which is why “how’s my glucose?” finds records written as “FBG”. |
Cookbook: one call, report → structured data
Section titled “Cookbook: one call, report → structured data”# Inspect first (nothing persisted) …curl https://api.mirobody.ai/v1/standardize \ -H "Authorization: Bearer $MIROBODY_API_KEY" \ -F "user=alice" -F "file=@lab_report.pdf"
# … then commit the same extractioncurl https://api.mirobody.ai/v1/standardize \ -H "Authorization: Bearer $MIROBODY_API_KEY" \ -F "user=alice" -F "file=@lab_report.pdf" \ -F "store=true" -F "retention=permanent"See Standardize a report for the full row shape (indicator_raw, loinc_code, confidence, …).