# Flutter

## Connections

| Value                      | Platform | Description                                                  |
| -------------------------- | -------- | ------------------------------------------------------------ |
| `Connection.appleHealth`   | iOS      | Apple Health (HealthKit)                                     |
| `Connection.samsung`       | Android  | Samsung Health (direct SDK access)                           |
| `Connection.healthConnect` | Android  | Health Connect (reads all data sources)                      |
| `Connection.googleFit`     | Android  | Google Fit (via Health Connect, filtered to Google Fit data) |

{% hint style="warning" %}
Passing an iOS-only connection on Android (or vice versa) will result in a `PlatformException`. The SDK does not guard against this at the Dart level.
{% endhint %}

## CustomPermission

Use these to request a subset of permissions. When not specified, all permissions from your developer scopes are requested. 41 values available — see `lib/models/enums.dart` for the full list.

Notable platform gaps: `menstruation` and `electrocardiogram` are recognized on iOS but **silently ignored** on Android. `mindfulness` is recognized on both native platforms but has **no Dart enum value**.

## Types

### SuccessMessage

```dart
class SuccessMessage {
  final bool? success;
  final String? error;
}
```

### DataMessage

```dart
class DataMessage {
  final bool? success;
  final Map<String, dynamic>? data;
  final String? error;
}
```

When `toWebhook` is `true`, the `data` field contains `{ "reference": "..." }` — a reference ID for the webhook payload. When `false`, `data` contains the full normalized health data map.

### UserId

```dart
class UserId {
  final bool? success;
  final String? userId;
}
```

## **Initialization**

### **initTerra**

Creates and authenticates a Terra SDK instance. This **makes a network call** to Terra's servers to validate your developer ID and reconnect existing users.

```dart
static Future<SuccessMessage?> initTerra(
      String devID,
      String referenceID) async
```

* `String devID` ➡ Your developer ID from the [Terra Dashboard](https://dashboard.tryterra.co).
* `String referenceID` ➡ An identifier for your app's user. This value appears as `reference_id` in webhook payloads and API responses, allowing you to map Terra users back to your own user system.

**returns** `Future<SuccessMessage?>`

{% hint style="warning" %}
You must `await` this call and verify `success` is `true` before calling any other SDK function.

**Android note:** On Android, the native `Terra.instance` call always reports `success: true` even if an error occurred — check the `error` field for the actual status.
{% endhint %}

## **Connection setup/management**

### initConnection

Authenticates a new user connection with Terra's servers and triggers the platform permission dialog (HealthKit on iOS, Health Connect on Android). This **makes a network call**.

This function should only be called **once** per user/connection type. On subsequent app launches, `initTerra` will automatically reconnect existing users.

```dart
static Future<SuccessMessage?> initConnection(
      Connection connection,
      String token,
      bool schedulerOn,
      List<CustomPermission> customPermissions) async
```

* `Connection connection` ➡ The connection type (e.g. `Connection.appleHealth`, `Connection.samsung`). Must match the platform.
* `String token` ➡ A **single-use** authentication token from the [Generate Authentication Token](https://docs.tryterra.co/reference/generate-authentication-token) endpoint.
* `bool schedulerOn` ➡ Enables automatic data delivery. On **iOS**, enables HealthKit background delivery (also requires `setUpBackgroundDelivery` in AppDelegate). On **Android**, enables periodic WorkManager-based data fetches.
* `List<CustomPermission> customPermissions` ➡ Request specific permissions. Empty list defaults to all scopes.

**returns** `Future<SuccessMessage?>` — check `error` field for specific failure reasons.

### getUserId

Returns the Terra user ID for a connection, or `null` if no connection exists. This is a local read with no network call.

```dart
static Future<UserId?> getUserId(Connection connection) async
```

* `Connection connection` ➡ The connection to get the user ID for.

**returns** `Future<UserId?>` — `userId` is `null` if no connection exists.

## Data retrieval

All data retrieval functions **make network calls** — even with `toWebhook = false`, the SDK sends data to Terra's normalization servers and returns the normalized result.

{% hint style="info" %}
**`toWebhook` behavior:**
{% endhint %}

| `toWebhook`      | What happens                                      | `DataMessage.data` contains                    |
| ---------------- | ------------------------------------------------- | ---------------------------------------------- |
| `true` (default) | Data is fetched and sent to your webhook          | `{ "reference": "..." }` — a reference ID only |
| `false`          | Data is fetched, normalized, and returned locally | The full normalized health data map            |

{% hint style="info" %}
Both paths require network connectivity.
{% endhint %}

### **getActivity**

Retrieves workout and exercise session data.

```dart
static Future<DataMessage?> getActivity(
      Connection connection, DateTime startDate, DateTime endDate,
      {bool toWebhook = true}) async
```

### **getDaily**

Retrieves daily summary data (steps, calories, distance, heart rate, etc.).

```dart
static Future<DataMessage?> getDaily(
      Connection connection, DateTime startDate, DateTime endDate,
      {bool toWebhook = true}) async
```

### getBody

Retrieves body measurement data (weight, height, BMI, heart rate, blood pressure, etc.).

```dart
static Future<DataMessage?> getBody(
      Connection connection, DateTime startDate, DateTime endDate,
      {bool toWebhook = true}) async
```

{% hint style="info" %}
Unlike iOS and React Native, the Flutter SDK does not have a `latestReading` parameter on `getBody`.
{% endhint %}

### getSleep

Retrieves sleep session data (stages, duration, heart rate during sleep, etc.).

```dart
static Future<DataMessage?> getSleep(
      Connection connection, DateTime startDate, DateTime endDate,
      {bool toWebhook = true}) async
```

### **getNutrition**

Retrieves nutrition and meal data.

```dart
static Future<DataMessage?> getNutrition(
      Connection connection, DateTime startDate, DateTime endDate,
      {bool toWebhook = true}) async
```

### getMenstruation

Retrieves menstrual cycle data. **iOS only** — throws `MissingPluginException` on Android.

```dart
static Future<DataMessage?> getMenstruation(
      Connection connection, DateTime startDate, DateTime endDate,
      {bool toWebhook = true}) async
```

### getAthlete

Retrieves the user's athlete profile (biographical data, no date range needed). **iOS only** — throws `MissingPluginException` on Android.

```dart
static Future<DataMessage?> getAthlete(
      Connection connection, {bool toWebhook = true}) async
```

**Common parameters for all data getters:**

* `Connection connection` ➡ The connection to get data from.
* `DateTime startDate` ➡ Start of the date range. Converted to UTC before sending to native.
* `DateTime endDate` ➡ End of the date range. Converted to UTC before sending to native.
* (Optional) `bool toWebhook` ➡ Whether to send data to your webhook. Defaults to `true`.

## Android-only methods

These functions are **only available on Android**. They will throw `MissingPluginException` on iOS.

### isHealthConnectAvailable

Checks if Health Connect is available on the device. Local check, no network call.

```dart
static Future<bool> isHealthConnectAvailable() async
```

### getGivenPermissions

Returns the Health Connect permissions currently granted to your app. Returns permission name strings like `"READ_HEART_RATE"`, `"READ_STEPS"`, etc.

```dart
static Future<Set<String>> getGivenPermissions() async
```

{% hint style="warning" %}
Requires a Health Connect-based connection to be initialized first. If no connection exists, the underlying callback may never fire, causing the Future to hang.
{% endhint %}

## iOS-only methods

### setIgnoredSources

Filters out health data from specific apps when reading from Apple Health. Use this to prevent double-counting when a user connects a data source both through Terra's API (e.g. WHOOP, Garmin) and has that same app syncing into Apple Health.

```dart
static Future<void> setIgnoredSources(List<String> sources) async
```

* `List<String> sources` ➡ App bundle identifiers to exclude (e.g. `["com.whoop.app", "com.garmin.connect.mobile"]`).

{% hint style="info" %}

* Takes effect on the next data fetch (including background delivery).
* **Not persisted across app launches** — call this on every app start if needed.
* **Android: this function is a no-op.** It is accepted but does nothing.
  {% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.tryterra.co/reference/health-and-fitness-api/sdk-references/flutter.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
