# Health Connect - JavaScript bridge API

> Reading and writing steps, distance, calories, heart rate, sleep, weight and exercise through Android’s Health Connect, for exactly the types the build ticked.

- **Applies to:** AppMint
- **Source:** extracted from the app runtime and its per-method example files; this page is generated from them.
- **HTML:** https://freewebtoapk.com/docs/api/health

### `AppMint.health`

```js
AppMint.health.isAvailable() / requestPermissions() / read() / write() / openHealthConnect()
```

**Example**

Reads and writes the user's health data through Health Connect: steps, distance, active calories, heart rate, sleep, weight and exercise sessions. Turn on **Health data (Health Connect)** in the wizard's Access step and tick the types and whether the app reads or writes each one - only those can be asked for.

**Returns:** every method returns a Promise. `isAvailable()` → `{ok: true, available, status, read, write}` (`status`: `available`, `not_installed`, `update_required`, `unsupported` = Android below 8.0, `disabled` = option off). The others → `{ok: true, …}` or `{ok: false, code, message}` with `code` `disabled`, `unsupported`, `not_installed`, `update_required`, `not_declared` (type not ticked in the wizard), `permission` (the user has not granted it), `bad-input`, `blocked` (a page from another site), `failed`. **Needs:** the wizard option, Android 8.0+, and Health Connect (built into Android 14+, an app from Play before that).

Types: `steps`, `distance`, `calories`, `heartRate`, `sleep`, `weight`, `exercise`. Times are milliseconds (`Date.now()`), `Date` objects or ISO strings; answers use ISO strings.

**Check, then ask:**

```js
async function connectHealth() {
  if (!(window.AppMint && AppMint.health)) return false;          // browser or option off
  var s = await AppMint.health.isAvailable();
  if (s.status === 'not_installed') { await AppMint.health.openHealthConnect(); return false; }
  if (!s.available) return false;
  var r = await AppMint.health.requestPermissions({ read: ['steps', 'heartRate'], write: ['weight'] });
  return r.ok && r.denied.read.length === 0;
}
```

**Today's steps** (totals with `aggregate: true`, the records themselves without it):

```js
async function stepsToday() {
  var start = new Date(); start.setHours(0, 0, 0, 0);
  var r = await AppMint.health.read('steps', { start: start, end: new Date(), aggregate: true });
  if (!r.ok) { console.warn(r.code, r.message); return 0; }
  return r.aggregate.count;
}

async function lastNightHeartRate() {
  var end = Date.now(), start = end - 12 * 3600 * 1000;
  var r = await AppMint.health.read('heartRate', { start: start, end: end });
  // r.records = [{start, end, id, samples: [{time, bpm}]}]
  return r.ok ? r.records.flatMap(function (x) { return x.samples; }) : [];
}
```

**Write** - one record or an array:

```js
await AppMint.health.write('weight', { time: Date.now(), kilograms: 72.4 });
await AppMint.health.write('exercise', [{
  start: Date.now() - 45 * 60000, end: Date.now(), exerciseType: 'running', title: 'Evening run'
}]);
await AppMint.health.write('steps', { start: Date.now() - 3600000, end: Date.now(), count: 4200 });
```

**Record fields:** steps `{start, end, count}` · distance `{start, end, meters}` · calories `{start, end, kilocalories}` · heartRate `{start, end, samples: [{time, bpm}]}` · sleep `{start, end, title?, stages?: [{start, end, stage}]}` (`awake`, `sleeping`, `out_of_bed`, `light`, `deep`, `rem`) · weight `{time, kilograms}` · exercise `{start, end, exerciseType, title?}` (Health Connect names such as `running`, `walking`, `biking`, `swimming_pool`, `yoga`, `strength_training`, `other_workout`). Aggregates: steps `{count}`, distance `{meters}`, calories `{kilocalories}`, heartRate `{avg, min, max}`, sleep / exercise `{minutes}`, weight `{avg, min, max}` (kg).

**Notes:** Health Connect shows your privacy policy from its permission screen - the address from the Finish step, or the generated policy. Before publishing on Google Play, fill in **App content → Health apps** in Play Console with the same data types and why the app needs each one; Play reviews health permissions. Health Connect gives an app the last 30 days of history from before its first grant. The raw bridge methods behind it (`healthIsAvailable`, `healthRequestPermissions`, `healthRead`, `healthWrite`, `healthOpen`) take JSON text and a callback id - use the helper.

### `healthIsAvailable`

```js
window.WebToApk.healthIsAvailable(callbackId: String)
```

Health Connect's state for this app; resolves [callbackId] with `{available, status, read, write}`.

**Example**

Documented together with `AppMint.health` - the example there shows this one too.

Reads and writes the user's health data through Health Connect: steps, distance, active calories, heart rate, sleep, weight and exercise sessions. Turn on **Health data (Health Connect)** in the wizard's Access step and tick the types and whether the app reads or writes each one - only those can be asked for.

**Returns:** every method returns a Promise. `isAvailable()` → `{ok: true, available, status, read, write}` (`status`: `available`, `not_installed`, `update_required`, `unsupported` = Android below 8.0, `disabled` = option off). The others → `{ok: true, …}` or `{ok: false, code, message}` with `code` `disabled`, `unsupported`, `not_installed`, `update_required`, `not_declared` (type not ticked in the wizard), `permission` (the user has not granted it), `bad-input`, `blocked` (a page from another site), `failed`. **Needs:** the wizard option, Android 8.0+, and Health Connect (built into Android 14+, an app from Play before that).

Types: `steps`, `distance`, `calories`, `heartRate`, `sleep`, `weight`, `exercise`. Times are milliseconds (`Date.now()`), `Date` objects or ISO strings; answers use ISO strings.

**Check, then ask:**

```js
async function connectHealth() {
  if (!(window.AppMint && AppMint.health)) return false;          // browser or option off
  var s = await AppMint.health.isAvailable();
  if (s.status === 'not_installed') { await AppMint.health.openHealthConnect(); return false; }
  if (!s.available) return false;
  var r = await AppMint.health.requestPermissions({ read: ['steps', 'heartRate'], write: ['weight'] });
  return r.ok && r.denied.read.length === 0;
}
```

**Today's steps** (totals with `aggregate: true`, the records themselves without it):

```js
async function stepsToday() {
  var start = new Date(); start.setHours(0, 0, 0, 0);
  var r = await AppMint.health.read('steps', { start: start, end: new Date(), aggregate: true });
  if (!r.ok) { console.warn(r.code, r.message); return 0; }
  return r.aggregate.count;
}

async function lastNightHeartRate() {
  var end = Date.now(), start = end - 12 * 3600 * 1000;
  var r = await AppMint.health.read('heartRate', { start: start, end: end });
  // r.records = [{start, end, id, samples: [{time, bpm}]}]
  return r.ok ? r.records.flatMap(function (x) { return x.samples; }) : [];
}
```

**Write** - one record or an array:

```js
await AppMint.health.write('weight', { time: Date.now(), kilograms: 72.4 });
await AppMint.health.write('exercise', [{
  start: Date.now() - 45 * 60000, end: Date.now(), exerciseType: 'running', title: 'Evening run'
}]);
await AppMint.health.write('steps', { start: Date.now() - 3600000, end: Date.now(), count: 4200 });
```

**Record fields:** steps `{start, end, count}` · distance `{start, end, meters}` · calories `{start, end, kilocalories}` · heartRate `{start, end, samples: [{time, bpm}]}` · sleep `{start, end, title?, stages?: [{start, end, stage}]}` (`awake`, `sleeping`, `out_of_bed`, `light`, `deep`, `rem`) · weight `{time, kilograms}` · exercise `{start, end, exerciseType, title?}` (Health Connect names such as `running`, `walking`, `biking`, `swimming_pool`, `yoga`, `strength_training`, `other_workout`). Aggregates: steps `{count}`, distance `{meters}`, calories `{kilocalories}`, heartRate `{avg, min, max}`, sleep / exercise `{minutes}`, weight `{avg, min, max}` (kg).

**Notes:** Health Connect shows your privacy policy from its permission screen - the address from the Finish step, or the generated policy. Before publishing on Google Play, fill in **App content → Health apps** in Play Console with the same data types and why the app needs each one; Play reviews health permissions. Health Connect gives an app the last 30 days of history from before its first grant. The raw bridge methods behind it (`healthIsAvailable`, `healthRequestPermissions`, `healthRead`, `healthWrite`, `healthOpen`) take JSON text and a callback id - use the helper.

### `healthOpen`

```js
window.WebToApk.healthOpen(callbackId: String)
```

Opens Health Connect, or its Play Store page when it is not installed.

**Example**

Documented together with `AppMint.health` - the example there shows this one too.

Reads and writes the user's health data through Health Connect: steps, distance, active calories, heart rate, sleep, weight and exercise sessions. Turn on **Health data (Health Connect)** in the wizard's Access step and tick the types and whether the app reads or writes each one - only those can be asked for.

**Returns:** every method returns a Promise. `isAvailable()` → `{ok: true, available, status, read, write}` (`status`: `available`, `not_installed`, `update_required`, `unsupported` = Android below 8.0, `disabled` = option off). The others → `{ok: true, …}` or `{ok: false, code, message}` with `code` `disabled`, `unsupported`, `not_installed`, `update_required`, `not_declared` (type not ticked in the wizard), `permission` (the user has not granted it), `bad-input`, `blocked` (a page from another site), `failed`. **Needs:** the wizard option, Android 8.0+, and Health Connect (built into Android 14+, an app from Play before that).

Types: `steps`, `distance`, `calories`, `heartRate`, `sleep`, `weight`, `exercise`. Times are milliseconds (`Date.now()`), `Date` objects or ISO strings; answers use ISO strings.

**Check, then ask:**

```js
async function connectHealth() {
  if (!(window.AppMint && AppMint.health)) return false;          // browser or option off
  var s = await AppMint.health.isAvailable();
  if (s.status === 'not_installed') { await AppMint.health.openHealthConnect(); return false; }
  if (!s.available) return false;
  var r = await AppMint.health.requestPermissions({ read: ['steps', 'heartRate'], write: ['weight'] });
  return r.ok && r.denied.read.length === 0;
}
```

**Today's steps** (totals with `aggregate: true`, the records themselves without it):

```js
async function stepsToday() {
  var start = new Date(); start.setHours(0, 0, 0, 0);
  var r = await AppMint.health.read('steps', { start: start, end: new Date(), aggregate: true });
  if (!r.ok) { console.warn(r.code, r.message); return 0; }
  return r.aggregate.count;
}

async function lastNightHeartRate() {
  var end = Date.now(), start = end - 12 * 3600 * 1000;
  var r = await AppMint.health.read('heartRate', { start: start, end: end });
  // r.records = [{start, end, id, samples: [{time, bpm}]}]
  return r.ok ? r.records.flatMap(function (x) { return x.samples; }) : [];
}
```

**Write** - one record or an array:

```js
await AppMint.health.write('weight', { time: Date.now(), kilograms: 72.4 });
await AppMint.health.write('exercise', [{
  start: Date.now() - 45 * 60000, end: Date.now(), exerciseType: 'running', title: 'Evening run'
}]);
await AppMint.health.write('steps', { start: Date.now() - 3600000, end: Date.now(), count: 4200 });
```

**Record fields:** steps `{start, end, count}` · distance `{start, end, meters}` · calories `{start, end, kilocalories}` · heartRate `{start, end, samples: [{time, bpm}]}` · sleep `{start, end, title?, stages?: [{start, end, stage}]}` (`awake`, `sleeping`, `out_of_bed`, `light`, `deep`, `rem`) · weight `{time, kilograms}` · exercise `{start, end, exerciseType, title?}` (Health Connect names such as `running`, `walking`, `biking`, `swimming_pool`, `yoga`, `strength_training`, `other_workout`). Aggregates: steps `{count}`, distance `{meters}`, calories `{kilocalories}`, heartRate `{avg, min, max}`, sleep / exercise `{minutes}`, weight `{avg, min, max}` (kg).

**Notes:** Health Connect shows your privacy policy from its permission screen - the address from the Finish step, or the generated policy. Before publishing on Google Play, fill in **App content → Health apps** in Play Console with the same data types and why the app needs each one; Play reviews health permissions. Health Connect gives an app the last 30 days of history from before its first grant. The raw bridge methods behind it (`healthIsAvailable`, `healthRequestPermissions`, `healthRead`, `healthWrite`, `healthOpen`) take JSON text and a callback id - use the helper.

### `healthRead`

```js
window.WebToApk.healthRead(type: String, optionsJson: String, callbackId: String)
```

Reads [type] records (or totals with `aggregate:true`) between [optionsJson] `start` and `end`.

**Example**

Documented together with `AppMint.health` - the example there shows this one too.

Reads and writes the user's health data through Health Connect: steps, distance, active calories, heart rate, sleep, weight and exercise sessions. Turn on **Health data (Health Connect)** in the wizard's Access step and tick the types and whether the app reads or writes each one - only those can be asked for.

**Returns:** every method returns a Promise. `isAvailable()` → `{ok: true, available, status, read, write}` (`status`: `available`, `not_installed`, `update_required`, `unsupported` = Android below 8.0, `disabled` = option off). The others → `{ok: true, …}` or `{ok: false, code, message}` with `code` `disabled`, `unsupported`, `not_installed`, `update_required`, `not_declared` (type not ticked in the wizard), `permission` (the user has not granted it), `bad-input`, `blocked` (a page from another site), `failed`. **Needs:** the wizard option, Android 8.0+, and Health Connect (built into Android 14+, an app from Play before that).

Types: `steps`, `distance`, `calories`, `heartRate`, `sleep`, `weight`, `exercise`. Times are milliseconds (`Date.now()`), `Date` objects or ISO strings; answers use ISO strings.

**Check, then ask:**

```js
async function connectHealth() {
  if (!(window.AppMint && AppMint.health)) return false;          // browser or option off
  var s = await AppMint.health.isAvailable();
  if (s.status === 'not_installed') { await AppMint.health.openHealthConnect(); return false; }
  if (!s.available) return false;
  var r = await AppMint.health.requestPermissions({ read: ['steps', 'heartRate'], write: ['weight'] });
  return r.ok && r.denied.read.length === 0;
}
```

**Today's steps** (totals with `aggregate: true`, the records themselves without it):

```js
async function stepsToday() {
  var start = new Date(); start.setHours(0, 0, 0, 0);
  var r = await AppMint.health.read('steps', { start: start, end: new Date(), aggregate: true });
  if (!r.ok) { console.warn(r.code, r.message); return 0; }
  return r.aggregate.count;
}

async function lastNightHeartRate() {
  var end = Date.now(), start = end - 12 * 3600 * 1000;
  var r = await AppMint.health.read('heartRate', { start: start, end: end });
  // r.records = [{start, end, id, samples: [{time, bpm}]}]
  return r.ok ? r.records.flatMap(function (x) { return x.samples; }) : [];
}
```

**Write** - one record or an array:

```js
await AppMint.health.write('weight', { time: Date.now(), kilograms: 72.4 });
await AppMint.health.write('exercise', [{
  start: Date.now() - 45 * 60000, end: Date.now(), exerciseType: 'running', title: 'Evening run'
}]);
await AppMint.health.write('steps', { start: Date.now() - 3600000, end: Date.now(), count: 4200 });
```

**Record fields:** steps `{start, end, count}` · distance `{start, end, meters}` · calories `{start, end, kilocalories}` · heartRate `{start, end, samples: [{time, bpm}]}` · sleep `{start, end, title?, stages?: [{start, end, stage}]}` (`awake`, `sleeping`, `out_of_bed`, `light`, `deep`, `rem`) · weight `{time, kilograms}` · exercise `{start, end, exerciseType, title?}` (Health Connect names such as `running`, `walking`, `biking`, `swimming_pool`, `yoga`, `strength_training`, `other_workout`). Aggregates: steps `{count}`, distance `{meters}`, calories `{kilocalories}`, heartRate `{avg, min, max}`, sleep / exercise `{minutes}`, weight `{avg, min, max}` (kg).

**Notes:** Health Connect shows your privacy policy from its permission screen - the address from the Finish step, or the generated policy. Before publishing on Google Play, fill in **App content → Health apps** in Play Console with the same data types and why the app needs each one; Play reviews health permissions. Health Connect gives an app the last 30 days of history from before its first grant. The raw bridge methods behind it (`healthIsAvailable`, `healthRequestPermissions`, `healthRead`, `healthWrite`, `healthOpen`) take JSON text and a callback id - use the helper.

### `healthRequestPermissions`

```js
window.WebToApk.healthRequestPermissions(requestJson: String, callbackId: String)
```

Opens Health Connect's permission screen for [requestJson] `{read:[…], write:[…]}`; resolves with `{granted, denied}`.

**Example**

Documented together with `AppMint.health` - the example there shows this one too.

Reads and writes the user's health data through Health Connect: steps, distance, active calories, heart rate, sleep, weight and exercise sessions. Turn on **Health data (Health Connect)** in the wizard's Access step and tick the types and whether the app reads or writes each one - only those can be asked for.

**Returns:** every method returns a Promise. `isAvailable()` → `{ok: true, available, status, read, write}` (`status`: `available`, `not_installed`, `update_required`, `unsupported` = Android below 8.0, `disabled` = option off). The others → `{ok: true, …}` or `{ok: false, code, message}` with `code` `disabled`, `unsupported`, `not_installed`, `update_required`, `not_declared` (type not ticked in the wizard), `permission` (the user has not granted it), `bad-input`, `blocked` (a page from another site), `failed`. **Needs:** the wizard option, Android 8.0+, and Health Connect (built into Android 14+, an app from Play before that).

Types: `steps`, `distance`, `calories`, `heartRate`, `sleep`, `weight`, `exercise`. Times are milliseconds (`Date.now()`), `Date` objects or ISO strings; answers use ISO strings.

**Check, then ask:**

```js
async function connectHealth() {
  if (!(window.AppMint && AppMint.health)) return false;          // browser or option off
  var s = await AppMint.health.isAvailable();
  if (s.status === 'not_installed') { await AppMint.health.openHealthConnect(); return false; }
  if (!s.available) return false;
  var r = await AppMint.health.requestPermissions({ read: ['steps', 'heartRate'], write: ['weight'] });
  return r.ok && r.denied.read.length === 0;
}
```

**Today's steps** (totals with `aggregate: true`, the records themselves without it):

```js
async function stepsToday() {
  var start = new Date(); start.setHours(0, 0, 0, 0);
  var r = await AppMint.health.read('steps', { start: start, end: new Date(), aggregate: true });
  if (!r.ok) { console.warn(r.code, r.message); return 0; }
  return r.aggregate.count;
}

async function lastNightHeartRate() {
  var end = Date.now(), start = end - 12 * 3600 * 1000;
  var r = await AppMint.health.read('heartRate', { start: start, end: end });
  // r.records = [{start, end, id, samples: [{time, bpm}]}]
  return r.ok ? r.records.flatMap(function (x) { return x.samples; }) : [];
}
```

**Write** - one record or an array:

```js
await AppMint.health.write('weight', { time: Date.now(), kilograms: 72.4 });
await AppMint.health.write('exercise', [{
  start: Date.now() - 45 * 60000, end: Date.now(), exerciseType: 'running', title: 'Evening run'
}]);
await AppMint.health.write('steps', { start: Date.now() - 3600000, end: Date.now(), count: 4200 });
```

**Record fields:** steps `{start, end, count}` · distance `{start, end, meters}` · calories `{start, end, kilocalories}` · heartRate `{start, end, samples: [{time, bpm}]}` · sleep `{start, end, title?, stages?: [{start, end, stage}]}` (`awake`, `sleeping`, `out_of_bed`, `light`, `deep`, `rem`) · weight `{time, kilograms}` · exercise `{start, end, exerciseType, title?}` (Health Connect names such as `running`, `walking`, `biking`, `swimming_pool`, `yoga`, `strength_training`, `other_workout`). Aggregates: steps `{count}`, distance `{meters}`, calories `{kilocalories}`, heartRate `{avg, min, max}`, sleep / exercise `{minutes}`, weight `{avg, min, max}` (kg).

**Notes:** Health Connect shows your privacy policy from its permission screen - the address from the Finish step, or the generated policy. Before publishing on Google Play, fill in **App content → Health apps** in Play Console with the same data types and why the app needs each one; Play reviews health permissions. Health Connect gives an app the last 30 days of history from before its first grant. The raw bridge methods behind it (`healthIsAvailable`, `healthRequestPermissions`, `healthRead`, `healthWrite`, `healthOpen`) take JSON text and a callback id - use the helper.

### `healthWrite`

```js
window.WebToApk.healthWrite(type: String, recordsJson: String, callbackId: String)
```

Writes the records in [recordsJson] (an array) as [type]; resolves with their ids.

**Example**

Documented together with `AppMint.health` - the example there shows this one too.

Reads and writes the user's health data through Health Connect: steps, distance, active calories, heart rate, sleep, weight and exercise sessions. Turn on **Health data (Health Connect)** in the wizard's Access step and tick the types and whether the app reads or writes each one - only those can be asked for.

**Returns:** every method returns a Promise. `isAvailable()` → `{ok: true, available, status, read, write}` (`status`: `available`, `not_installed`, `update_required`, `unsupported` = Android below 8.0, `disabled` = option off). The others → `{ok: true, …}` or `{ok: false, code, message}` with `code` `disabled`, `unsupported`, `not_installed`, `update_required`, `not_declared` (type not ticked in the wizard), `permission` (the user has not granted it), `bad-input`, `blocked` (a page from another site), `failed`. **Needs:** the wizard option, Android 8.0+, and Health Connect (built into Android 14+, an app from Play before that).

Types: `steps`, `distance`, `calories`, `heartRate`, `sleep`, `weight`, `exercise`. Times are milliseconds (`Date.now()`), `Date` objects or ISO strings; answers use ISO strings.

**Check, then ask:**

```js
async function connectHealth() {
  if (!(window.AppMint && AppMint.health)) return false;          // browser or option off
  var s = await AppMint.health.isAvailable();
  if (s.status === 'not_installed') { await AppMint.health.openHealthConnect(); return false; }
  if (!s.available) return false;
  var r = await AppMint.health.requestPermissions({ read: ['steps', 'heartRate'], write: ['weight'] });
  return r.ok && r.denied.read.length === 0;
}
```

**Today's steps** (totals with `aggregate: true`, the records themselves without it):

```js
async function stepsToday() {
  var start = new Date(); start.setHours(0, 0, 0, 0);
  var r = await AppMint.health.read('steps', { start: start, end: new Date(), aggregate: true });
  if (!r.ok) { console.warn(r.code, r.message); return 0; }
  return r.aggregate.count;
}

async function lastNightHeartRate() {
  var end = Date.now(), start = end - 12 * 3600 * 1000;
  var r = await AppMint.health.read('heartRate', { start: start, end: end });
  // r.records = [{start, end, id, samples: [{time, bpm}]}]
  return r.ok ? r.records.flatMap(function (x) { return x.samples; }) : [];
}
```

**Write** - one record or an array:

```js
await AppMint.health.write('weight', { time: Date.now(), kilograms: 72.4 });
await AppMint.health.write('exercise', [{
  start: Date.now() - 45 * 60000, end: Date.now(), exerciseType: 'running', title: 'Evening run'
}]);
await AppMint.health.write('steps', { start: Date.now() - 3600000, end: Date.now(), count: 4200 });
```

**Record fields:** steps `{start, end, count}` · distance `{start, end, meters}` · calories `{start, end, kilocalories}` · heartRate `{start, end, samples: [{time, bpm}]}` · sleep `{start, end, title?, stages?: [{start, end, stage}]}` (`awake`, `sleeping`, `out_of_bed`, `light`, `deep`, `rem`) · weight `{time, kilograms}` · exercise `{start, end, exerciseType, title?}` (Health Connect names such as `running`, `walking`, `biking`, `swimming_pool`, `yoga`, `strength_training`, `other_workout`). Aggregates: steps `{count}`, distance `{meters}`, calories `{kilocalories}`, heartRate `{avg, min, max}`, sleep / exercise `{minutes}`, weight `{avg, min, max}` (kg).

**Notes:** Health Connect shows your privacy policy from its permission screen - the address from the Finish step, or the generated policy. Before publishing on Google Play, fill in **App content → Health apps** in Play Console with the same data types and why the app needs each one; Play reviews health permissions. Health Connect gives an app the last 30 days of history from before its first grant. The raw bridge methods behind it (`healthIsAvailable`, `healthRequestPermissions`, `healthRead`, `healthWrite`, `healthOpen`) take JSON text and a callback id - use the helper.

