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

# Synheart Core - Flutter SDK

> Unified SDK for human-state intelligence in Flutter applications

## Overview

The Synheart Core Flutter SDK provides a unified API for collecting HSI-compatible data, processing human state on-device, and generating focus/emotion signals in Flutter applications.

**Key Features:**

* Cross-platform support (iOS + Android)
* On-device HSI Runtime
* Real-time state updates
* Modular design (enable only what you need)
* Privacy-first architecture

## Installation

Add to your `pubspec.yaml`:

```yaml theme={null}
dependencies:
  synheart_core: ^0.0.4
```

Install dependencies:

```bash theme={null}
flutter pub get
```

## Platform Configuration

### iOS Configuration

Add to `ios/Runner/Info.plist`:

```xml theme={null}
<!-- Health data access (if using Wear module) -->
<key>NSHealthShareUsageDescription</key>
<string>This app needs access to your health data to provide insights.</string>

<!-- Motion & Fitness (if using Phone module) -->
<key>NSMotionUsageDescription</key>
<string>This app uses motion data to understand your activity patterns.</string>
```

### Android Configuration

Add to `android/app/src/main/AndroidManifest.xml`:

```xml theme={null}
<!-- Required permissions -->
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />

<!-- Health Connect Permissions (if using Wear module) -->
<uses-permission android:name="android.permission.health.READ_HEART_RATE"/>
<uses-permission android:name="android.permission.health.READ_HEART_RATE_VARIABILITY"/>
```

## Basic Usage

### Initialize the SDK

```dart theme={null}
import 'package:synheart_core/synheart_core.dart';

// Initialize with basic modules
await Synheart.initialize(
  userId: 'anon_user_123',
  config: SynheartConfig(
    allowUnsignedCapabilities: true,  // Use capabilityToken in production
  ),
);
```

### Subscribe to HSI Updates

The HSI (Human State Intelligence) stream emits raw JSON from the on-device runtime:

```dart theme={null}
// onHSIUpdate emits raw HSI JSON from the Synheart Runtime
Synheart.onHSIUpdate.listen((hsiJson) {
  print('HSI JSON: $hsiJson');
});
```

### Activate optional modules

The `SynheartFeature` enum gates collection by feature. Activation is one
of four conditions a feature needs (the others are consent, capability
tier, and an active session — see [Capability System](/synheart-core/capability-system)).

```dart theme={null}
// Available features:
//   SynheartFeature.wear         — biosignals from wearables
//   SynheartFeature.behavior     — interaction telemetry
//   SynheartFeature.phoneContext — motion / screen / app context
//   SynheartFeature.cloud        — HSI upload connector

Synheart.activate(SynheartFeature.wear);
Synheart.activate(SynheartFeature.cloud);

// Stop a feature without uninitializing the SDK.
Synheart.deactivate(SynheartFeature.cloud);
```

State signals (focus, emotion, recovery, etc.) are not separate features
— they're axes inside the HSI JSON emitted by `Synheart.onHSIUpdate`.
Parse the JSON or use the typed `Synheart.onStateUpdate` stream to read
them.

### Enable the cloud connector

Upload HSI 1.3 snapshots when the host has been granted `cloudUpload`
consent:

```dart theme={null}
await Synheart.initialize(
  userId: 'anon_user_123',
  config: SynheartConfig(
    allowUnsignedCapabilities: true,  // use capabilityToken in production
    cloudConfig: CloudConfig(
      appId: 'your_app_id',
      subjectId: 'user_123',
      instanceId: 'device_abc',
      baseUrl: 'https://api.synheart.ai',
      maxQueueSize: 100,
    ),
  ),
);

// Uploads happen automatically when consent is granted, the queue has
// pending snapshots, and the network is reachable. Inspect upload state
// via the diagnostics getters:
final pending = Synheart.uploadQueueLength;
final lastMs = Synheart.lastIngestSuccessAtMs;

Synheart.deactivate(SynheartFeature.cloud);   // pause uploads
```

## Complete example

```dart theme={null}
import 'package:flutter/material.dart';
import 'package:synheart_core/synheart_core.dart';

class HumanStateMonitor extends StatefulWidget {
  @override
  State<HumanStateMonitor> createState() => _HumanStateMonitorState();
}

class _HumanStateMonitorState extends State<HumanStateMonitor> {
  HSIState? _state;
  String? _rawHsi;
  bool _ready = false;

  @override
  void initState() {
    super.initState();
    _bootstrap();
  }

  Future<void> _bootstrap() async {
    await Synheart.initialize(
      userId: 'user_123',
      config: SynheartConfig(allowUnsignedCapabilities: true),
    );
    Synheart.activate(SynheartFeature.wear);
    Synheart.activate(SynheartFeature.behavior);

    Synheart.onHSIUpdate.listen((json) => setState(() => _rawHsi = json));
    Synheart.onStateUpdate.listen((s) => setState(() => _state = s));

    setState(() => _ready = true);
  }

  @override
  void dispose() {
    Synheart.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    if (!_ready) return const Center(child: CircularProgressIndicator());
    final axes = _state?.hsi;
    return Scaffold(
      appBar: AppBar(title: const Text('Human State')),
      body: ListView(padding: const EdgeInsets.all(16), children: [
        Text('Focus: ${axes?.focus?.value.toStringAsFixed(2) ?? '—'}'),
        Text('Arousal: ${axes?.arousal?.value.toStringAsFixed(2) ?? '—'}'),
        Text('Capacity: ${axes?.capacity?.value.toStringAsFixed(2) ?? '—'}'),
        const SizedBox(height: 16),
        if (_rawHsi != null)
          Text('Raw HSI: ${_rawHsi!.substring(0, 100)}…'),
      ]),
    );
  }
}
```

## HSI state reference

`Synheart.onHSIUpdate` emits raw HSI 1.3 JSON strings. The typed
projection of that JSON is `HSIState`, surfaced via
`Synheart.onStateUpdate`. Most apps use the typed stream; reach for the
raw JSON only when you need fields the typed projection doesn't expose
(for example, the 64D embedding vector).

```dart theme={null}
class HSIState {
  final String subjectId;
  final int timestampMs;
  final HSIAxes hsi;
  final Modalities modalities;
  final Tiers tiers;
  final String rawJson;
}

class HSIAxes {
  final HSIAxisValue? focus;
  final HSIAxisValue? arousal;
  final HSIAxisValue? capacity;
  final HSIAxisValue? sleep;
}

class HSIAxisValue {
  final double value;       // 0.0–1.0
  final double confidence;  // 0.0–1.0
}
```

`modalities` and `tiers` carry per-axis source attribution and capability gating. The exact shape can drift between HSI versions; treat the typed fields as best-effort and the `rawJson` as authoritative. See the [HSI specification](/hsi/overview) and [Synheart Core HSI mapping](/synheart-core/hsi-specification).

## Cloud connector

The cloud connector uploads HSI 1.3 snapshots to the Synheart Platform
when the host has been granted `cloudUpload` consent.

```dart theme={null}
await Synheart.initialize(
  userId: 'anon_user_123',
  config: SynheartConfig(
    allowUnsignedCapabilities: true,  // use capabilityToken in production
    cloudConfig: CloudConfig(
      appId: 'your_app_id',
      subjectId: 'user_123',
      instanceId: 'device_abc',
      baseUrl: 'https://api.synheart.ai',
      maxQueueSize: 100,
    ),
  ),
);

// Once activated, the connector handles uploads automatically:
//   - flushes when HSI windows close and consent is granted
//   - queues during offline windows (FIFO, capped by maxQueueSize)
//   - retries failed uploads with exponential backoff
//
// Inspect state through diagnostic getters:
final pending = Synheart.uploadQueueLength;
final lastMs = Synheart.lastIngestSuccessAtMs;

// Pause / resume:
Synheart.deactivate(SynheartFeature.cloud);
Synheart.activate(SynheartFeature.cloud);
```

Authentication is hardware-backed device ECDSA per
RFC-AUTH-MOBILE-0001.
The runtime owns request signing via the host's `synheart-auth`
integration — `CloudConfig` does **not** carry shared secrets or
HMAC keys. See [Synheart Auth overview](/synheart-auth/overview) for
the device-identity flow.

**Upload Payload (HSI 1.3 format)**:

```dart theme={null}
{
  "subject": {
    "subject_type": "pseudonymous_user",
    "subject_id": "user_123"
  },
  "snapshots": [
    {
      "hsi_version": "1.3",
      "observed_at_utc": "2026-01-15T10:30:00Z",
      "computed_at_utc": "2026-01-15T10:30:10Z",
      "producer": {
        "name": "Synheart Core SDK",
        "version": "1.0.0",
        "instance_id": "device_abc"
      },
      "windows": {
        "micro": {
          "start_utc": "2026-01-15T10:29:30Z",
          "end_utc": "2026-01-15T10:30:00Z",
          "duration_seconds": 30
        }
      },
      "axes": {
        "affect": {
          "arousal_index": 0.72,
          "valence_stability": 0.65
        },
        "engagement": {
          "engagement_stability": 0.81,
          "interaction_cadence": 0.55
        },
        "behavior": {
          "motion_index": 0.45,
          "posture_stability": 0.78,
          "screen_active_ratio": 0.90,
          "session_fragmentation": 0.22
        }
      },
      "embeddings": [
        {
          "dimension": 64,
          "model": "synheart-jl-64",
          "vector": [0.12, 0.34, ...]
        }
      ],
      "privacy": {
        "contains_pii": false
      }
    }
  ]
}
```

## Configuration Options

```dart theme={null}
final config = SynheartConfig(
  // Update interval for HSV processing
  updateInterval: Duration(seconds: 30),

  // Cloud configuration (optional).
  cloudConfig: CloudConfig(
    appId: 'your_app_id',
    subjectId: 'user_123',
    instanceId: 'device_abc',
    baseUrl: 'https://api.synheart.ai',
  ),

  // Capability JWT (optional, for extended/research access).
  capabilityToken: null,

  // Log level
  logLevel: LogLevel.info,
);

await Synheart.initialize(
  userId: 'user_123',
  config: config,
);
```

## Error Handling

```dart theme={null}
try {
  await Synheart.initialize(
    userId: userId,
    config: config,
  );
} on PermissionDeniedError catch (e) {
  print('Permission denied: ${e.message}');
} on InitializationError catch (e) {
  print('Initialization failed: ${e.message}');
} on SynheartError catch (e) {
  print('SDK error: ${e.message}');
}
```

## Privacy & Consent

The SDK enforces consent at multiple levels:

```dart theme={null}
// Coarse status — granted | pending | expired | denied
final status = await Synheart.consentStatus();

// Per-type check (wire strings: biosignals, phoneContext, behavior,
// cloudUpload, vendorSync, research)
final canUpload = await Synheart.hasConsent('cloudUpload');
final canRead   = await Synheart.hasConsent('biosignals');

// Request consent — opens the cloud consent flow when configured.
final token = await Synheart.requestConsent();

if (await Synheart.hasConsent('cloudUpload')) {
  Synheart.activate(SynheartFeature.cloud);
}

// Revoke a single type or everything
await Synheart.revokeConsentType('cloudUpload');
await Synheart.revokeConsent();
```

For the full consent model (granular channels, tiers, JWT lifecycle), see [Consent System](/synheart-core/consent-system).

## Performance Considerations

These are **design targets**, not measured runtime numbers — profile
your own app for ground truth on the current build. Use the
diagnostic getters to inspect what the SDK is actually doing.

### Diagnostics & upload inspection

```dart theme={null}
// Live counters and last-error strings.
final diag = Synheart.runtimeDiagnostics();
print(diag);

// Synchronous getters — safe to read from UI code.
final depth = Synheart.uploadQueueLength;
final lastMs = Synheart.lastIngestSuccessAtMs;

// Manually flush queued snapshots when consent + network are eligible.
final result = await Synheart.ingestion.flushIfEligible();
```

## API reference

### `Synheart`

Main SDK class.

**Static methods:**

| Method                 | Description                             | Returns                |
| ---------------------- | --------------------------------------- | ---------------------- |
| `initialize(...)`      | Initialize the SDK                      | `Future<void>`         |
| `activate(feature)`    | Activate a feature                      | `void`                 |
| `deactivate(feature)`  | Deactivate a feature                    | `void`                 |
| `dispose()`            | Tear down the SDK and release resources | `Future<void>`         |
| `runtimeDiagnostics()` | Live counters / last-error strings      | `Map<String, dynamic>` |

**Streams:**

| Stream          | Type               | Description                                |
| --------------- | ------------------ | ------------------------------------------ |
| `onHSIUpdate`   | `Stream<String>`   | Raw HSI 1.3 JSON, emitted per window close |
| `onStateUpdate` | `Stream<HSIState>` | Typed projection of `onHSIUpdate`          |

## Resources

* **Repository**: [synheart-core-flutter](https://github.com/synheart-ai/synheart-core-flutter)
* **pub.dev**: [synheart\_core](https://pub.dev/packages/synheart_core)
* **API Docs**: [API Reference](https://pub.dev/documentation/synheart_core/latest/)
* **Issues**: [GitHub Issues](https://github.com/synheart-ai/synheart-core-flutter/issues)

## Related Documentation

* [HSV Specification](/synheart-core/hsv-specification) - Understand Synheart Core’s internal state model
* [Architecture](/synheart-core/architecture) - Deep dive into the system
* [Capability System](/synheart-core/capability-system) - Access levels and permissions
