> ## Documentation Index
> Fetch the complete documentation index at: https://docs.corti.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Observation resource group

> Learn how vital signs, lab results, exam findings, social history, imaging, and survey scores become FHIR R4 Observation resources

An Observation resource records one measurement or one finding about the patient. Observations hold what the clinician measured or saw. The interpretation, such as a diagnosis, goes into a [Condition](https://docs.corti.ai/fhir/resource-groups/condition.md). The resource follows the [FHIR R4 Observation](https://hl7.org/fhir/R4/observation.html) specification, and each field name below links to its R4 definition.

> [!WARNING]
>
> If you already receive lab results or vital signs as structured data, use that source and turn off the `laboratory` and `vital-signs` categories. A value copied into a note can be wrong or out of date. See [Reduce extraction errors](https://docs.corti.ai/fhir/reduce-errors.md#skip-data-you-already-have-in-structured-form).

## One Observation per value

Each number or finding gets its own Observation. A blood pressure of "150/90" becomes two Observations, one systolic and one diastolic. A panel such as "Na 139, K 4.1" becomes one Observation per analyte. The endpoint does not use the FHIR [`component`](https://hl7.org/fhir/R4/observation-definitions.html#Observation.component) field.

## Measurements and findings

Every Observation is one of two kinds. The kind decides which coding system `code` uses, and where the result goes.

| | Measurement | Finding |
| - | - | - |
| What it is | A value that someone measured or scored | Something that someone saw, heard, or felt |
| Note says | "HbA1c 7.2 %", "Heart rate 88", "PHQ-9 score 14" | "No murmurs", "Abdominal tenderness", "Never smoked" |
| `code` | **What the clinician measured**, in LOINC: `4548-4` Hemoglobin A1c | **The finding itself**, in SNOMED CT: `88610006` Heart murmur |
| Result | A number in `valueQuantity` (with a unit), `valueInteger`, or `valueRatio` | A SNOMED CT qualifier in `valueCodeableConcept`, such as Present or Absent |

Read it as a question and an answer. For a measurement, `code` asks "what is the HbA1c?" and the value answers "7.2 %". For a finding, `code` names the finding, "heart murmur", and the value says whether the clinician found it: "absent".

### Same topic, different kinds

A single topic can produce both kinds. The wording in the note decides:

| Note says | Kind | `code` | Result |
| - | - | - | - |
| "20 pack-years" | Measurement | LOINC term for tobacco pack-years | `valueQuantity`: 20 |
| "Never smoked" | Finding | SNOMED CT finding for tobacco smoking | `valueCodeableConcept`: Absent |
| "Ejection fraction 55 % on echo" | Measurement | LOINC term for left ventricular ejection fraction | `valueQuantity`: 55 % |
| "No pericardial effusion on echo" | Finding | `373945007` Pericardial effusion | `valueCodeableConcept`: `2667000` Absent |
| "Severe stenosis at L4-L5 on MRI" | Finding | SNOMED CT finding for spinal stenosis | `valueCodeableConcept`: Severe, with `bodySite` L4-L5 |

> [!TIP]
>
> When you read an Observation, check the value field before you use `code`. A finding Observation with the value Absent means the patient does **not** have that finding. Code `88610006` Heart murmur on its own does not mean the patient has a murmur.

A finding names the finding in positive form, with presence or absence in the value. "No acute hemorrhage" becomes the code for intracranial hemorrhage, with the value Absent, not a code meaning "no hemorrhage".

### Normal and absent findings

Findings let you record what the clinician did *not* find. A list of codes has no way to say "no murmur". An Observation does:

| Note says | `code` | `valueCodeableConcept` |
| - | - | - |
| "Murmur heard at apex" | `88610006` Heart murmur | `52101004` Present |
| "No murmurs" | `88610006` Heart murmur | `2667000` Absent |

## Categories

The endpoint sorts every Observation into one of seven categories. Some categories only hold measurements, one only holds findings, and three hold both:

| Category | Example from a note | Kind | `code` |
| - | - | - | - |
| `vital-signs` | "BP 150/90", "HR 88", "Temp 38.2" | Measurement | LOINC |
| `laboratory` | "HbA1c 7.2 %", "Potassium 4.1 mmol/L" | Measurement | LOINC |
| `survey` | "PHQ-9 score 14", "GCS 15" | Measurement | LOINC |
| `exam` | "No murmurs", "Abdominal tenderness" | Finding | SNOMED CT |
| `social-history` | "20 pack-years", "Never smoked" | Both | LOINC for measurements, SNOMED CT for findings |
| `imaging` | "Ejection fraction 55 %", "Chest X-ray shows consolidation" | Both | LOINC for measurements, SNOMED CT for findings |
| `procedure` | "QTc 450 ms", "ECG shows sinus rhythm" | Both | LOINC for measurements, SNOMED CT for findings |

This matters for [filtering](https://docs.corti.ai/fhir/filter-reference.md#filterable-fields). A LOINC filter on `social-history` only affects the measurements in that category. To restrict the findings, add a SNOMED CT filter.

## Fields

| Field | Type | What it holds | Example from a note |
| - | - | - | - |
| [`status`](https://hl7.org/fhir/R4/observation-definitions.html#Observation.status) | [code](https://docs.corti.ai/fhir/datatypes.md#primitive-types) | `final` by default. Also `registered`, `preliminary`, `amended`, `corrected`, `cancelled`, `entered-in-error`, or `unknown`. See the [R4 value set](https://hl7.org/fhir/R4/valueset-observation-status.html). | "preliminary result" → `preliminary` |
| [`category`](https://hl7.org/fhir/R4/observation-definitions.html#Observation.category) | [CodeableConcept](https://docs.corti.ai/fhir/datatypes.md#codeableconcept) list | One of the seven categories above. See the [R4 value set](https://hl7.org/fhir/R4/valueset-observation-category.html). | |
| [`code`](https://hl7.org/fhir/R4/observation-definitions.html#Observation.code) | [CodeableConcept](https://docs.corti.ai/fhir/datatypes.md#codeableconcept) | What the clinician measured or found, in LOINC or SNOMED CT | "HbA1c" → `4548-4` |
| [`valueQuantity`](https://hl7.org/fhir/R4/observation-definitions.html#Observation.value_x_) | [Quantity](https://docs.corti.ai/fhir/datatypes.md#quantity) | A number with a unit (`value`, `unit`, `comparator`, `system`) | "HbA1c 7.2 %" → `7.2`, `%` |
| [`valueInteger`](https://hl7.org/fhir/R4/observation-definitions.html#Observation.value_x_) | [integer](https://docs.corti.ai/fhir/datatypes.md#primitive-types) | A whole-number score | "GCS 15" → `15` |
| [`valueRatio`](https://hl7.org/fhir/R4/observation-definitions.html#Observation.value_x_) | [Ratio](https://docs.corti.ai/fhir/datatypes.md#ratio) | A ratio (`numerator`, `denominator`) | "titer 1:64" |
| [`valueCodeableConcept`](https://hl7.org/fhir/R4/observation-definitions.html#Observation.value_x_) | [CodeableConcept](https://docs.corti.ai/fhir/datatypes.md#codeableconcept) | The result of a finding, as a SNOMED CT qualifier such as Present, Absent, or Severe | "no murmurs" → Absent |
| [`interpretation`](https://hl7.org/fhir/R4/observation-definitions.html#Observation.interpretation) | [CodeableConcept](https://docs.corti.ai/fhir/datatypes.md#codeableconcept) list | One of nine HL7 interpretation codes: `N` Normal, `A` Abnormal, `H` High, `L` Low, `HH` Critical high, `LL` Critical low, `POS` Positive, `NEG` Negative, or `ND` Not detected. `laboratory` uses all nine, `vital-signs` only `N`, `H`, and `L`, `imaging` and `procedure` only `N`, `A`, `H`, and `L`, and `survey` only `N` and `A`. `exam` and `social-history` Observations have no interpretation. See the [R4 value set](https://hl7.org/fhir/R4/valueset-observation-interpretation.html). | "potassium low at 3.1" → `L` |
| [`bodySite`](https://hl7.org/fhir/R4/observation-definitions.html#Observation.bodySite) | [CodeableConcept](https://docs.corti.ai/fhir/datatypes.md#codeableconcept) | Where on the body, in SNOMED CT | "BP right arm" → right upper arm structure |
| [`effectiveDateTime`](https://hl7.org/fhir/R4/observation-definitions.html#Observation.effective_x_) | [dateTime](https://docs.corti.ai/fhir/datatypes.md#primitive-types) | When the measurement was taken. Only when the note states a date. A time of day without a timezone is cut back to the date, because R4 accepts a time only with a timezone offset. | "HbA1c 7.2 % on 2026-10-12" → `2026-10-12` |
| [`note`](https://hl7.org/fhir/R4/observation-definitions.html#Observation.note) | list of [Annotation](https://docs.corti.ai/fhir/datatypes.md#annotation) | Extra context | |
| [`subject`](https://hl7.org/fhir/R4/observation-definitions.html#Observation.subject) | [Reference](https://docs.corti.ai/fhir/datatypes.md#reference) | The Patient of the Bundle | |
| [`encounter`](https://hl7.org/fhir/R4/observation-definitions.html#Observation.encounter) | [Reference](https://docs.corti.ai/fhir/datatypes.md#reference) | The Encounter of the note | |
| [`extension`](https://hl7.org/fhir/R4/extensibility.html#Extension) | list of [Extension](https://docs.corti.ai/fhir/datatypes.md#extension) | [Mentions and alternatives](https://docs.corti.ai/fhir/how-it-works.md#every-value-points-back-to-the-note) | |

### Units

A unit comes from the note, or from a fixed default for a few common measurements. For example, a heart rate written without a unit gets `beats/min`, and a temperature of 37.2 gets `°C`. The endpoint does not guess an ambiguous unit: "weight 180" keeps no unit. Every unit uses `system: "http://unitsofmeasure.org"` (UCUM). The `unit` is the text as the note writes it, and the Quantity carries no UCUM `code`.

## Codes the endpoint can assign

The endpoint only searches a fixed part of each coding system for each field. A code outside that part never appears, and a [filter](https://docs.corti.ai/fhir/filter-reference.md#how-filters-combine) can only narrow the part further, never widen it. [Codes come from a fixed scope](https://docs.corti.ai/fhir/how-it-works.md#codes-come-from-a-fixed-scope) explains why.

The allowed codes depend on the category, and on whether the Observation is a [measurement or a finding](#measurements-and-findings):

| Category | `code` for measurements | `code` for findings | `valueCodeableConcept` | `bodySite` |
| - | - | - | - | - |
| `laboratory` | LOINC, status `ACTIVE` | | | none |
| `vital-signs` | LOINC, status `ACTIVE` | | | Body structure |
| `survey` | LOINC, status `ACTIVE` | | | Body structure |
| `exam` | | Clinical finding | Present or Absent | Body structure |
| `social-history` | LOINC, status `ACTIVE` | Clinical finding | Present or Absent | Body structure |
| `procedure` | LOINC, status `ACTIVE` | Clinical finding | Present or Absent | Body structure |
| `imaging` | LOINC, status `ACTIVE` | Clinical finding | Semantic tag `qualifier value` | Body structure |

What the short names mean:

| Name | Allowed codes |
| - | - |
| LOINC, status `ACTIVE` | Any LOINC term with status `ACTIVE`. The endpoint never returns `TRIAL`, `DISCOURAGED`, or `DEPRECATED` terms. |
| Clinical finding | SNOMED CT `404684003` Clinical finding, and its descendants. This includes disorders, such as `373945007` Pericardial effusion. |
| Present or Absent | A fixed pair: SNOMED CT `52101004` Present and `2667000` Absent |
| Semantic tag `qualifier value` | Any SNOMED CT qualifier value, such as `52101004` Present, `24484000` Severe, or a word that describes size or shape |
| Body structure | SNOMED CT `442083009` Anatomical or acquired body structure, and its descendants |

`category`, `status`, and `interpretation` use the fixed HL7 value sets listed under [Fields](#fields).

## Examples

### Lab result

```text theme={null}
HbA1c 7.2 % on 2026-10-12, up from 6.8 %.
```

> [tab] Simplified
>
> | Field | Value |
> | - | - |
> | `category` | `laboratory` |
> | `code` | `4548-4` Hemoglobin A1c/Hemoglobin.total in Blood (LOINC) |
> | `valueQuantity` | 7.2 % |
> | `effectiveDateTime` | `2026-10-12` |

> [tab] JSON
>
> ```json theme={null}
> {
>   "resourceType": "Observation",
>   "id": "8f0c6b8e-3d5a-5b7e-9a41-2c6d0e7f1a93",
>   "status": "final",
>   "category": [
>     {
>       "coding": [
>         {
>           "system": "http://terminology.hl7.org/CodeSystem/observation-category",
>           "code": "laboratory",
>           "display": "Laboratory"
>         }
>       ],
>       "text": "Laboratory"
>     }
>   ],
>   "code": {
>     "coding": [
>       {
>         "system": "http://loinc.org",
>         "code": "4548-4",
>         "display": "Hemoglobin A1c/Hemoglobin.total in Blood"
>       }
>     ],
>     "text": "Hemoglobin A1c/Hemoglobin.total in Blood"
>   },
>   "subject": { "reference": "urn:uuid:b49ecda5-92db-5325-a7a9-f82c71500bad", "type": "Patient" },
>   "encounter": {
>     "reference": "urn:uuid:29543af8-9ec2-528e-8a3b-1e891822d99d",
>     "type": "Encounter",
>     "identifier": {
>       "system": "http://corti.app/fhir/identifier/encounter",
>       "value": "enc-88213"
>     }
>   },
>   "effectiveDateTime": "2026-10-12",
>   "valueQuantity": {
>     "value": 7.2,
>     "unit": "%",
>     "system": "http://unitsofmeasure.org"
>   }
> }
> ```

The earlier value of 6.8 % gets its own laboratory Observation. It has no `effectiveDateTime`, because the note does not say when the lab measured it.

### Exam finding

```text theme={null}
Heart: regular rhythm, no murmurs.
```

> [tab] Simplified
>
> | Field | Value |
> | - | - |
> | `category` | `exam` |
> | `code` | `88610006` Heart murmur |
> | `valueCodeableConcept` | `2667000` Absent |

> [tab] JSON
>
> ```json theme={null}
> {
>   "resourceType": "Observation",
>   "id": "c47e2a19-6b0d-5f83-8e25-9d1a3b4c5e60",
>   "status": "final",
>   "category": [
>     {
>       "coding": [
>         {
>           "system": "http://terminology.hl7.org/CodeSystem/observation-category",
>           "code": "exam",
>           "display": "Exam"
>         }
>       ],
>       "text": "Exam"
>     }
>   ],
>   "code": {
>     "coding": [
>       {
>         "system": "http://snomed.info/sct",
>         "code": "88610006",
>         "display": "Heart murmur"
>       }
>     ],
>     "text": "Heart murmur"
>   },
>   "subject": { "reference": "urn:uuid:b49ecda5-92db-5325-a7a9-f82c71500bad", "type": "Patient" },
>   "encounter": {
>     "reference": "urn:uuid:29543af8-9ec2-528e-8a3b-1e891822d99d",
>     "type": "Encounter",
>     "identifier": {
>       "system": "http://corti.app/fhir/identifier/encounter",
>       "value": "enc-88213"
>     }
>   },
>   "valueCodeableConcept": {
>     "coding": [
>       {
>         "system": "http://snomed.info/sct",
>         "code": "2667000",
>         "display": "Absent"
>       }
>     ],
>     "text": "Absent"
>   }
> }
> ```

"Regular rhythm" is a separate finding, so it gets its own exam Observation.

For a vital-sign example with two Observations for one blood pressure, see the full response in [Extract FHIR resources](https://docs.corti.ai/fhir/quickstart.md#read-the-response).

## Next steps

> [card] [Procedure resource group](https://docs.corti.ai/fhir/resource-groups/procedure.md)
>
> Learn how surgery, therapy, and other interventions look in FHIR.

> [card] [Filter FHIR resources](https://docs.corti.ai/fhir/filtering.md)
>
> Turn off the Observation categories you already have.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.