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

# Passive data

> Device-derived readings: heart rate, sleep, activity, glucose, and vitals. 6 log types with payload schemas and examples.

Device-derived readings: heart rate, sleep, activity, glucose, and vitals. Submit these via `POST /v1/logs/batch` or the [Python SDK](/reference/sdk); see [How logs work](/send-data/how-logs-work) for submission fields and the difference between **lifecycle-tracked** and point-in-time log types.

## Heart rate data

**Type:** `heart_rate_data` · **Source:** Python SDK / REST, App SDK (coming soon) · **Extensible**

Reserved for heart rate or HRV from a device or integration: resting\_bpm, avg/min/max\_bpm, avg\_hrv\_sdnn\_ms, period, device\_provider.

**Payload**

<ResponseField name="resting_bpm" type="number">
  Resting heart rate in beats per minute.
</ResponseField>

<ResponseField name="avg_bpm" type="number">
  Average heart rate in bpm over the measurement period.
</ResponseField>

<ResponseField name="min_bpm" type="number">
  Minimum heart rate in bpm over the measurement period.
</ResponseField>

<ResponseField name="max_bpm" type="number">
  Maximum heart rate in bpm over the measurement period.
</ResponseField>

<ResponseField name="avg_hrv_sdnn_ms" type="number">
  Heart rate variability (SDNN) in milliseconds.
</ResponseField>

<ResponseField name="irregular_events_count" type="integer">
  Count of irregular rhythm events detected by the device.
</ResponseField>

<ResponseField name="period" type="object">
  <Expandable title="fields">
    <ResponseField name="start_datetime" type="string">
      ISO 8601 UTC. Start of the measurement period.
    </ResponseField>

    <ResponseField name="end_datetime" type="string">
      ISO 8601 UTC. End of the measurement period.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="device_provider" type="string">
  Device or integration provider.. Example: `garmin`, `fitbit`, `apple_health`
</ResponseField>

<ResponseField name="extensions" type="object">
  Open key/value bag for client/source-specific fields that lack a typed slot; merged into the entry's extensions (leaf-level, last-writer-wins by event timestamp).
</ResponseField>

**Example**

<CodeGroup>
  ```python Python theme={null}
  import olira
  from olira import OliraLogType

  olira.log(
      log_type=OliraLogType.HEART_RATE_DATA,
      patient_id="your-patient-id",
      payload={},
  )
  ```

  ```http HTTP theme={null}
  POST /v1/logs/batch
  Authorization: Bearer YOUR_API_KEY
  Content-Type: application/json

  {
    "logs": [
      {
        "log_type": "heart_rate_data",
        "patient_id": "8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82",
        "timestamp": "2026-03-18T09:00:00Z",
        "payload": {}
      }
    ]
  }
  ```
</CodeGroup>

<Note>
  **Related types:** Use [`vitals_measurement`](/reference/log-types/lab-clinical#vitals-measurement) for vital signs from exam or flowsheet. Not intended for single spot HR in a vitals set (vitals\_measurement with heart\_rate\_bpm). Always include period to anchor the measurement window; include device\_provider when multiple simultaneous sources are possible.
</Note>

## Sleep data

**Type:** `sleep_data` · **Source:** Python SDK / REST, App SDK (coming soon) · **Extensible**

Reserved for one sleep session from a device or integration. Each event represents a single session; include period (full sleep window, UTC start to end) and device\_provider: total\_sleep\_minutes, stages, period, device\_provider.

**Payload**

<ResponseField name="total_sleep_minutes" type="number">
  Total sleep duration in minutes.
</ResponseField>

<ResponseField name="deep_sleep_minutes" type="number">
  Duration in deep/slow-wave sleep stage (minutes).
</ResponseField>

<ResponseField name="rem_sleep_minutes" type="number">
  Duration in REM sleep stage (minutes).
</ResponseField>

<ResponseField name="light_sleep_minutes" type="number">
  Duration in light sleep stage (minutes).
</ResponseField>

<ResponseField name="awake_minutes" type="number">
  Wake after sleep onset (WASO) in minutes.
</ResponseField>

<ResponseField name="period" type="object">
  <Expandable title="fields">
    <ResponseField name="start_datetime" type="string">
      ISO 8601 UTC. Start of the sleep period.
    </ResponseField>

    <ResponseField name="end_datetime" type="string">
      ISO 8601 UTC. End of the sleep period.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="device_provider" type="string">
  Device or integration provider.. Example: `garmin`, `fitbit`, `apple_health`
</ResponseField>

<ResponseField name="extensions" type="object">
  Open key/value bag for client/source-specific fields that lack a typed slot; merged into the entry's extensions (leaf-level, last-writer-wins by event timestamp).
</ResponseField>

**Example**

<CodeGroup>
  ```python Python theme={null}
  import olira
  from olira import OliraLogType

  olira.log(
      log_type=OliraLogType.SLEEP_DATA,
      patient_id="your-patient-id",
      payload={},
  )
  ```

  ```http HTTP theme={null}
  POST /v1/logs/batch
  Authorization: Bearer YOUR_API_KEY
  Content-Type: application/json

  {
    "logs": [
      {
        "log_type": "sleep_data",
        "patient_id": "8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82",
        "timestamp": "2026-03-18T09:00:00Z",
        "payload": {}
      }
    ]
  }
  ```
</CodeGroup>

<Note>
  **Related types:** Use [`activity_data`](/reference/log-types/passive-data#activity-data) for activity or steps, [`vitals_measurement`](/reference/log-types/lab-clinical#vitals-measurement) for vitals.
</Note>

## Activity data

**Type:** `activity_data` · **Source:** Python SDK / REST, App SDK (coming soon), signal\_feature\_pipeline · **Extensible**

Reserved for activity measurements from wearables, device integrations, or the signal feature pipeline. Each event covers one measurement period (a daily summary or a single detected walking bout); always set period to define the window: steps, walks, active\_minutes, sedentary\_minutes, calories, floors\_climbed, exercise\_sessions, period, device\_provider, local\_date.

**Payload**

<ResponseField name="steps" type="integer">
  Step count within the measurement period.
</ResponseField>

<ResponseField name="walks" type="integer">
  Number of discrete walking bouts.
</ResponseField>

<ResponseField name="walking_minutes" type="number">
  Total minutes spent walking.
</ResponseField>

<ResponseField name="time_at_home_percent" type="number">
  Percentage of time spent at home location (0–100).. Minimum: 0. Maximum: 100
</ResponseField>

<ResponseField name="distance_travelled" type="object">
  Distance with explicit unit. Server normalises to metres.

  <Expandable title="fields">
    <ResponseField name="value" type="number">
      Numeric distance value.
    </ResponseField>

    <ResponseField name="unit" type="string">
      Unit of measurement.. Example: `meters`, `feet`, `km`
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="active_minutes" type="integer">
  Minutes of moderate-to-vigorous activity.
</ResponseField>

<ResponseField name="sedentary_minutes" type="integer">
  Sedentary minutes within the measurement period.
</ResponseField>

<ResponseField name="calories_total" type="number">
  Total calories burned.
</ResponseField>

<ResponseField name="calories_active" type="number">
  Active calories burned.
</ResponseField>

<ResponseField name="floors_climbed" type="integer">
  Number of floors climbed.
</ResponseField>

<ResponseField name="exercise_sessions" type="object[]" />

<ResponseField name="period" type="object">
  <Expandable title="fields">
    <ResponseField name="start_datetime" type="string">
      ISO 8601 UTC. Start of the activity period.
    </ResponseField>

    <ResponseField name="end_datetime" type="string">
      ISO 8601 UTC. End of the activity period.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="device_provider" type="string">
  Device or integration provider.. Example: `garmin`, `fitbit`, `apple_health`
</ResponseField>

<ResponseField name="local_date" type="string">
  ISO 8601 date (YYYY-MM-DD) in the patient's local timezone, derived from utc\_offset\_seconds. Preferred anchor for per-day grouping when period spans midnight in UTC.
</ResponseField>

<ResponseField name="utc_offset_seconds" type="integer">
  UTC offset of the sensor at the time of the measurement, in seconds (e.g. -18000 for UTC-5).
</ResponseField>

<ResponseField name="extensions" type="object">
  Open key/value bag for client/source-specific fields that lack a typed slot; merged into the entry's extensions (leaf-level, last-writer-wins by event timestamp).
</ResponseField>

**Example**

<CodeGroup>
  ```python Python theme={null}
  import olira
  from olira import OliraLogType

  olira.log(
      log_type=OliraLogType.ACTIVITY_DATA,
      patient_id="your-patient-id",
      payload={},
  )
  ```

  ```http HTTP theme={null}
  POST /v1/logs/batch
  Authorization: Bearer YOUR_API_KEY
  Content-Type: application/json

  {
    "logs": [
      {
        "log_type": "activity_data",
        "patient_id": "8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82",
        "timestamp": "2026-03-18T09:00:00Z",
        "payload": {}
      }
    ]
  }
  ```
</CodeGroup>

<Note>
  **Related types:** Use [`vitals_measurement`](/reference/log-types/lab-clinical#vitals-measurement) for vital signs, [`sleep_data`](/reference/log-types/passive-data#sleep-data) for sleep, [`heart_rate_data`](/reference/log-types/passive-data#heart-rate-data) for heart rate.
</Note>

## CGM reading

**Type:** `cgm_reading` · **Source:** Python SDK / REST, App SDK (coming soon) · **Extensible**

Reserved for a single CGM reading from a continuous glucose device: glucose\_mg\_dl + sensor\_timestamp; trend\_arrow, glucose\_flag, device\_provider optional.

**Payload**

<ResponseField name="glucose_mg_dl" type="number" required>
  Blood glucose in mg/dL. To convert to mmol/L divide by 18.018.
</ResponseField>

<ResponseField name="trend_arrow" type="string">
  e.g. rising, falling, steady.. Example: `rising`, `falling`, `stable`
</ResponseField>

<ResponseField name="glucose_flag" type="string">
  Whether glucose is above, below, or within range.. One of: `high`, `low`, `normal`
</ResponseField>

<ResponseField name="sensor_timestamp" type="string" required>
  ISO 8601 UTC timestamp from the CGM sensor.
</ResponseField>

<ResponseField name="device_provider" type="string">
  Device or integration provider.. Example: `dexcom`, `freestyle_libre`, `eversense`
</ResponseField>

<ResponseField name="extensions" type="object">
  Open key/value bag for client/source-specific fields that lack a typed slot; merged into the entry's extensions (leaf-level, last-writer-wins by event timestamp).
</ResponseField>

**Example**

<CodeGroup>
  ```python Python theme={null}
  import olira
  from olira import OliraLogType

  olira.log(
      log_type=OliraLogType.CGM_READING,
      patient_id="your-patient-id",
      payload={
          "glucose_mg_dl": 0,
          "sensor_timestamp": "..."
      },
  )
  ```

  ```http HTTP theme={null}
  POST /v1/logs/batch
  Authorization: Bearer YOUR_API_KEY
  Content-Type: application/json

  {
    "logs": [
      {
        "log_type": "cgm_reading",
        "patient_id": "8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82",
        "timestamp": "2026-03-18T09:00:00Z",
        "payload": {
          "glucose_mg_dl": 0,
          "sensor_timestamp": "..."
      }
      }
    ]
  }
  ```
</CodeGroup>

<Note>
  **Related types:** Use [`lab_results`](/reference/log-types/lab-clinical#lab-results) for lab glucose or other lab results. Not intended for fingerstick or other non-CGM glucose (lab\_results if from lab).
</Note>

## SpO2 reading

**Type:** `spo2_reading` · **Source:** Python SDK / REST, App SDK (coming soon) · **Extensible**

Reserved for SpO2 from pulse oximeter or wearable: spo2\_percent (+ pulse\_bpm, measurement\_context, sensor\_timestamp, device\_provider). Always include sensor\_timestamp and device\_provider.

**Payload**

<ResponseField name="spo2_percent" type="number" required>
  Oxygen saturation percentage (0–100).. Minimum: 0. Maximum: 100
</ResponseField>

<ResponseField name="pulse_bpm" type="number">
  Simultaneous pulse rate in beats per minute.
</ResponseField>

<ResponseField name="measurement_context" type="string">
  Conditions under which SpO2 was measured.. One of: `resting`, `during_sleep`, `activity`
</ResponseField>

<ResponseField name="sensor_timestamp" type="string">
  ISO 8601 UTC datetime of the reading.
</ResponseField>

<ResponseField name="device_provider" type="string">
  Device or integration provider.. Example: `withings`, `garmin`, `fitbit`
</ResponseField>

<ResponseField name="extensions" type="object">
  Open key/value bag for client/source-specific fields that lack a typed slot; merged into the entry's extensions (leaf-level, last-writer-wins by event timestamp).
</ResponseField>

**Example**

<CodeGroup>
  ```python Python theme={null}
  import olira
  from olira import OliraLogType

  olira.log(
      log_type=OliraLogType.SPO2_READING,
      patient_id="your-patient-id",
      payload={
          "spo2_percent": 0
      },
  )
  ```

  ```http HTTP theme={null}
  POST /v1/logs/batch
  Authorization: Bearer YOUR_API_KEY
  Content-Type: application/json

  {
    "logs": [
      {
        "log_type": "spo2_reading",
        "patient_id": "8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82",
        "timestamp": "2026-03-18T09:00:00Z",
        "payload": {
          "spo2_percent": 0
      }
      }
    ]
  }
  ```
</CodeGroup>

<Note>
  **Related types:** Use [`lab_results`](/reference/log-types/lab-clinical#lab-results) for lab results. Not intended for vitals from exam/flowsheet (vitals\_measurement when SpO2 is part of a broader vitals set).
</Note>

## Weight measurement

**Type:** `weight_measurement` · **Source:** Python SDK / REST, App SDK (coming soon) · **Extensible**

Reserved for weight from a connected scale device: weight\_kg (+ body\_fat\_percent, bmi, sensor\_timestamp, device\_provider).

**Payload**

<ResponseField name="weight_kg" type="number" required>
  Body weight in kilograms.
</ResponseField>

<ResponseField name="body_fat_percent" type="number">
  Body fat percentage (0–100).. Minimum: 0. Maximum: 100
</ResponseField>

<ResponseField name="bmi" type="number">
  Body mass index (calculated). Provide if returned by the device.
</ResponseField>

<ResponseField name="sensor_timestamp" type="string">
  ISO 8601 UTC datetime of the measurement.
</ResponseField>

<ResponseField name="device_provider" type="string">
  Device or integration provider.. Example: `withings`, `omron`, `fitbit`
</ResponseField>

<ResponseField name="extensions" type="object">
  Open key/value bag for client/source-specific fields that lack a typed slot; merged into the entry's extensions (leaf-level, last-writer-wins by event timestamp).
</ResponseField>

**Example**

<CodeGroup>
  ```python Python theme={null}
  import olira
  from olira import OliraLogType

  olira.log(
      log_type=OliraLogType.WEIGHT_MEASUREMENT,
      patient_id="your-patient-id",
      payload={
          "weight_kg": 0
      },
  )
  ```

  ```http HTTP theme={null}
  POST /v1/logs/batch
  Authorization: Bearer YOUR_API_KEY
  Content-Type: application/json

  {
    "logs": [
      {
        "log_type": "weight_measurement",
        "patient_id": "8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82",
        "timestamp": "2026-03-18T09:00:00Z",
        "payload": {
          "weight_kg": 0
      }
      }
    ]
  }
  ```
</CodeGroup>

<Note>
  **Related types:** Use [`vitals_measurement`](/reference/log-types/lab-clinical#vitals-measurement) for weight from vitals/flowsheet, [`lab_results`](/reference/log-types/lab-clinical#lab-results) for lab or other.
</Note>
