Skip to content
Get Started

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.

Both a document and a structured record enter the same pipeline:

  1. Read the source PDF / image → text (OCR); Excel → rows.
  2. Pull out readings Find each {indicator, value, unit, date}. Documents only — a /v1/data record is already structured and skips straight to coding.
  3. Code the indicator Match the name to a LOINC code. With no confident match, loinc_code stays null — never a wrong code.
  4. Normalize the unit Fold the unit spelling to one UCUM form and parse the value to a number: "mg/dl"mg/dL.
  5. Mirror to FHIR One FHIR R4 Observation per reading, addressable by fhir_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.

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)
Interopfree textFHIR R4 Observation (fhir_resource_id)
Originalkept: 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.

SurfaceWhat appears
POST /v1/dataResponse counts standardized alongside ingested.
GET /v1/dataEvery row carries parsed_value / parsed_unit / loinc_code / canonical_name / fhir_resource_id.
POST /v1/standardizeThe whole pipeline as a synchronous call — dry-run by default, so you can inspect standardization before committing a write.
The agentGrounded 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”
Terminal window
# 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 extraction
curl 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, …).