---
title: Stats
---


## Overview

Sahha provides your app with daily stats directly from Apple Health and Google Health Connect.

Stats are daily summaries of user activity.

For example:

- the total number of steps taken in a day
- the average heart rate for a day
- the total minutes slept at night

{% image src="connect/sdk/sdk-stats.png" alt="Sahha Stats" width=512 / %}

{% callout title="Stats are calculated in realtime for a 24 hour period" %}

Using the `getStats` method will give you the most up-to-date calculation for a [`SahhaSensor`](/docs/connect/sdk/collection#sahha-sensor) for the current day.

For example, if you'd like to monitor a user's daily steps, you can call `getStats(.steps)` multiple times during the day - we suggest using it everytime the user opens your app.

**_The total number of steps for the current day will continue to increase until midnight in the user's local timezone._**

This is very useful for monitoring daily changes in user activity.

After midnight, a new day will begin and a new stat will start to be calculated.

**_Using `getStats` for previous days will always return the total value that was calculated at midnight for that day._**

{% /callout %}

---

## Get stats for today

Get the most recent stats for the current day in the user's local timezone.

{% tabs %}

{% tab label="iOS" %}

```swift title=MyApp.swift
// Get stats for today

Sahha.getStats(
    sensor: .steps,
    startDateTime: .now,
    endDateTime: .now)
{ error, stats in
    if let error = error {
        print(error)
    } else if stats.isEmpty == false {
        print(stats)
    }
}
```

{% /tab %}

{% tab label="Android" %}

```kotlin title=MainActivity.kt
// Get stats for today
// Leave date range empty

Sahha.getStats(
    SahhaSensor.steps,
    Pair(LocalDateTime.now(), LocalDateTime.now())
	) { error, stats ->
    error?.also {
        println(error)
    }
    stats?.also {
        println(stats)
    }
}
```

{% /tab %}

{% tab label="Flutter" %}

```typescript title=MyApp.dart
// Get stats for today
// Leave date range empty

SahhaFlutter.getStats(
  sensor: SahhaSensor.steps,
  startDateTime: DateTime.now(),
  endDateTime: DateTime.now())
.then((value) {
    List<dynamic> data = jsonDecode(value);
    debugPrint(data.toString());
}).catchError((error, stackTrace) => {debugPrint(error.toString())});
```

{% /tab %}

{% tab label="React Native" %}

```typescript title=MyApp.tsx
// Get stats for today
// Leave date range empty

let date = new Date();

Sahha.getStats(
	SahhaSensor.steps,
	date.getTime(),
	date.getTime(),
	(error: string, value: string) => {
		if (error) {
			console.error(`Error: ${error}`);
		} else if (value) {
			const jsonArray = JSON.parse(value);
			const jsonString = JSON.stringify(jsonArray);
			console.log(value);
		}
	}
);
```

{% /tab %}

{% tab label="Ionic Capacitor" %}

```javascript title=MyApp.js
// Get stats for today
// Leave date range empty

let date: Date = new Date();

Sahha.getStats({
	sensor: SahhaSensor.steps,
	startDateTime: date.getTime(),
	endDateTime: date.getTime() })
.then(
    function (response) {
        const array = JSON.parse(response.value);
        const jsonString = JSON.stringify(array);
        console.log(jsonString);
    },
    function (error) {
        console.log(error);
    }
)
```

{% /tab %}

{% /tabs %}

---

## Get stats for the last week

You can provide a data range if you would like to receive multiple stats over a specific time period. The response will include an array of stats for each 24 hour segment in that time period.

{% tabs %}

{% tab label="iOS" %}

```swift title=MyApp.swift
// Get stats for last 7 days
// Add a date range

let today = Date()
let sevenDaysAgo = Calendar.current.date(byAdding: .day, value: -7, to: today) ?? Date()

Sahha.getStats(
    sensor: .steps,
    startDateTime: sevenDaysAgo,
    endDateTime: today)
{ error, stats in
    if let error = error {
        print(error)
    } else if stats.isEmpty == false {
        print(stats)
    }
}
```

{% /tab %}

{% tab label="Android" %}

```kotlin title=MainActivity.kt
// Get stats for last 7 days
// Add a date range

Sahha.getStats(
	sensor = SahhaSensor.steps,
    dates = Pair(LocalDateTime.now().minusDays(7), LocalDateTime.now())
    ) { error, stats ->
    error?.also {
        println(error)
    }
    stats?.also {
        println(stats)
    }
}
```

{% /tab %}

{% tab label="Flutter" %}

```typescript title=MyApp.dart
// Get stats for last 7 days
// Add a date range

SahhaFlutter.getStats(
  sensor: SahhaSensor.steps,
  startDateTime: DateTime.now().subtract(const Duration(days: 7)),
  endDateTime: DateTime.now())
.then((value) {
    List<dynamic> data = jsonDecode(value);
    debugPrint(data.toString());
}).catchError((error, stackTrace) => {debugPrint(error.toString())});
```

{% /tab %}

{% tab label="React Native" %}

```typescript title=MyApp.tsx
// Get stats for last 7 days
// Add date range as milliseconds since epoch time

let endDate: Date = new Date();
let days = endDate.getDate() - 7;
var startDate = new Date();
startDate.setDate(days);

Sahha.getStats(
	SahhaSensor.steps,
	startDate.getTime(),
	endDate.getTime(),
	(error: string, value: string) => {
		if (error) {
			console.error(`Error: ${error}`);
		} else if (value) {
			const jsonArray = JSON.parse(value);
			const jsonString = JSON.stringify(jsonArray);
			console.log(value);
		}
	}
);
```

{% /tab %}

{% tab label="Ionic Capacitor" %}

```javascript title=MyApp.js
// Get stats for last 7 days
// Add date range as milliseconds since epoch time

let endDate: Date = new Date();
let days = endDate.getDate() - 7;
var startDate = new Date();
startDate.setDate(days);

Sahha.getStats({
	sensor: SahhaSensor.steps,
	startDateTime: startDate.getTime(),
	endDateTime: endDate.getTime() })
.then(
    function (response) {
        const array = JSON.parse(response.value);
        const jsonString = JSON.stringify(array);
        console.log(jsonString);
    },
    function (error) {
        console.log(error);
    }
)
```

{% /tab %}

{% /tabs %}

---

## Stat response

Stats are returned as an array of objects in JSON format.

- **Parameters**:
  - `id`: UUID for the stat
  - `type`: The type of the stat (`steps`, `sleep`, etc.)
  - `startDateTime`: Start date-time in `"yyyy-MM-dd'T'HH:mm:ss.SSZZZZZ"` format (`"2021-10-27T16:34:06-06:00"`)
  - `endDateTime`: End date-time in `"yyyy-MM-dd'T'HH:mm:ss.SSZZZZZ"` format (`"2021-10-27T16:44:06-06:00"`)
  - `value`: Numerical value of the stat (`100`, `200`, etc.)
  - `unit`: The unit for measuring the value (`count`, `minute`, `kg`, `bpm`, etc.)
  - `sources`: An array of sources which recorded the stat in `com.company.app` format (`["com.apple.health"]`)

**_For iOS and Android, stats are returned as an array of objects in `SahhaStat` format._**

{% tabs %}

{% tab label="iOS" %}

```swift title=SahhaStat.swift
public struct SahhaStat: Comparable, Codable {
    public var id: String
    public var type: String
    public var value: Double
    public var unit: String
    public var startDateTime: Date
    public var endDateTime: Date
    public var sources: [String]
}
```

{% /tab %}

{% tab label="Android" %}

```kotlin title=SahhaStat.kt
data class SahhaStat(
    val id: String,
    val type: String,
    val value: Double,
    val unit: String,
    val startDateTime: ZonedDateTime,
    val endDateTime: ZonedDateTime,
    val sources: List<String> = emptyList(),
)
```

{% /tab %}

{% /tabs %}

### Array response

Stats are returned as an array of objects in JSON format.

Older stats will be at the start of the array.

Newer stats will be at the end of the array.

An example response includes these fields:

```json title=RESPONSE
[
	{
		"value": 5616,
		"id": "464A029C-D2B6-4A49-A94F-01BFEC642CBA",
		"sources": ["com.apple.health.0C1972B1-DBA3-4B25-9FE7-E9C00DF1DCE6"],
		"unit": "count",
		"startDateTime": "2024-12-13T00:00:00.00+09:00",
		"endDateTime": "2024-12-14T00:00:00.00+09:00",
		"type": "steps"
	},
	{
		"value": 7576,
		"sources": ["com.apple.health.0C1972B1-DBA3-4B25-9FE7-E9C00DF1DCE6"],
		"endDateTime": "2024-12-15T00:00:00.00+09:00",
		"unit": "count",
		"id": "A3313BE9-AD16-4C1B-B8DE-0D1916A517F1",
		"type": "steps",
		"startDateTime": "2024-12-14T00:00:00.00+09:00"
	},
	{
		"startDateTime": "2024-12-15T00:00:00.00+09:00",
		"type": "steps",
		"sources": ["com.apple.health.0C1972B1-DBA3-4B25-9FE7-E9C00DF1DCE6"],
		"unit": "count",
		"id": "24CB1DE7-7B3B-40CE-BF51-1584364991C3",
		"value": 227,
		"endDateTime": "2024-12-16T00:00:00.00+09:00"
	}
]
```

### Empty response

If no stats are found for the `SahhaSensor` and time period you specify, you will receive an error message.

```json title=RESPONSE
"No stats found"
```

---

## Using SahhaSensor

Stats are grouped by `SahhaSensor` type.

For example, use `getStats(.heartRate)` to get stats of a user's heart rate.

{% callout title="Choose a SahhaSensor" %}

You must specify which `SahhaSensor` to use for `getStats`.

{% /callout %}

|         SahhaSensor          |        Android         |          iOS           |
| :--------------------------: | :--------------------: | :--------------------: |
|            gender            | _Sensor Not Available_ | _Sensor Not Available_ |
|        date_of_birth         | _Sensor Not Available_ | _Sensor Not Available_ |
|            sleep             |           ✔           |           ✔           |
|            steps             |           ✔           |           ✔           |
|        floors_climbed        |           ✔           |           ✔           |
|          heart_rate          |           ✔           |           ✔           |
|      resting_heart_rate      |           ✔           |           ✔           |
|  walking_heart_rate_average  | _Sensor Not Available_ |           ✔           |
| heart_rate_variability_rmssd |           ✔           | _Sensor Not Available_ |
| heart_rate_variability_sdnn  | _Sensor Not Available_ |           ✔           |
|   blood_pressure_systolic    | _Sensor Not Available_ |           ✔           |
|   blood_pressure_diastolic   | _Sensor Not Available_ |           ✔           |
|        blood_glucose         | _Sensor Not Available_ |           ✔           |
|           vo2_max            | _Sensor Not Available_ |           ✔           |
|      oxygen_saturation       | _Sensor Not Available_ |           ✔           |
|       respiratory_rate       | _Sensor Not Available_ |           ✔           |
|     active_energy_burned     |           ✔           |           ✔           |
|     basal_energy_burned      | _Sensor Not Available_ |           ✔           |
|     total_energy_burned      |           ✔           | _Sensor Not Available_ |
|     basal_metabolic_rate     |           ✔           | _Sensor Not Available_ |
|       time_in_daylight       | _Sensor Not Available_ |           ✔           |
|       body_temperature       | _Sensor Not Available_ |           ✔           |
|    basal_body_temperature    | _Sensor Not Available_ |           ✔           |
|  sleeping_wrist_temperature  | _Sensor Not Available_ |           ✔           |
|            height            |           ✔           |           ✔           |
|            weight            |           ✔           |           ✔           |
|        lean_body_mass        | _Sensor Not Available_ |           ✔           |
|       body_mass_index        | _Sensor Not Available_ |           ✔           |
|           body_fat           | _Sensor Not Available_ |           ✔           |
|       body_water_mass        | _Sensor Not Available_ | _Sensor Not Available_ |
|          bone_mass           | _Sensor Not Available_ | _Sensor Not Available_ |
|     waist_circumference      | _Sensor Not Available_ |           ✔           |
|          stand_time          | _Sensor Not Available_ |           ✔           |
|          move_time           | _Sensor Not Available_ |           ✔           |
|        exercise_time         | _Sensor Not Available_ |           ✔           |
|       activity_summary       | _Sensor Not Available_ | _Sensor Not Available_ |
|         device_lock          | _Sensor Not Available_ | _Sensor Not Available_ |
|           exercise           |           ✔           | _Sensor Not Available_ |
