# Measurements

Canonical page: https://docs.ovok.com/java-sdk/measurements

`ovok.measurements().save(parameters)` builds FHIR Observations from a measurement and saves them in a transaction:

```java
ovok.measurements().save(Map.of(
        "patientId", "patient-id",
        "measurement", Map.of(
                "measurementTypeKey", "body-weight",
                "bodyWeight", 72.4)));
```

Without `patientId`, the measurement is saved for the signed-in patient.

## Measurement types [#measurement-types]

`measurementTypeKey` accepts `blood-glucose`, `body-temperature`, `body-weight`, `heart-rate-variability`, `heart-rate`, `respiratory-rate`, `resting-heart-rate`, `walking-heart-rate-average`, `blood-pressure`, `blood-oxygen-pulse-rate`, `ecg`, `step-count`, `urine-analysis`, `uric-acid`, `lipid-panel`, `respiratory-therapy`, and `baby-sleep`. Any other value throws `OvokValidationException`.

## Duplicates and large readings [#duplicates-and-large-readings]

Saves use conditional identifiers, so a repeated device reading does not create a duplicate. Large readings are split into bounded bundles.

`SaveObservationsOptions(requestOptions, identifierSystems, replace)` names the identifier systems that identify a device reading. With `replace` set to `true`, a reading that matches those identifiers overwrites the saved Observation instead of being skipped.

`build(parameters)` returns the Observations without saving them, and `saveObservations` saves Observations you built. Every method is in the [`MeasurementsResource` reference](/java-sdk/reference/measurements-resource).

Questionnaire answers can carry Observations too: `ovok.questionnaireResponses().submitWithObservations(response, observations)`. See [questionnaire responses](/java-sdk/questionnaire-responses).
