The phone↔watch protocol is defined inDocumentation 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-session/protos/session.proto, package synheart.session.v1.
Envelope
Every message on the wire is aSessionMessage with a oneof payload:
1–9 are reserved for phone→watch; 10+ for watch→phone.
Phone → watch
StartSession
The wire
ComputeProfile carries only window_sec and emit_interval_sec. The Dart-side ComputeProfile.rawEmitIntervalSec is phone-side only — it doesn’t cross the wire, because the watch derives raw cadence from enable_raw_stream + its own buffer policy.enable_raw_stream = true activates BiosignalBatch emission from watch to phone. Default is false — raw biosignals must not transmit unless explicitly enabled.
StopSession
SessionSummary and transitions to TERMINATED.
GetStatus
Empty message. Watch responds with SessionStatus.
Watch → phone
SessionStarted
ACTIVE (sensors hot, first sample admitted).
SessionFrame
SessionMetrics
Map<String, dynamic> on SessionFrame.metrics.
BehaviorSnapshot
BehaviorSnapshot field-for-field.
SessionSummary
SessionError
ErrorCode enum: ERROR_PERMISSION_DENIED, ERROR_SENSOR_UNAVAILABLE, ERROR_LOW_BATTERY, ERROR_OS_TERMINATED, ERROR_INVALID_STATE. See Errors.
SessionStatus
GetStatus. The Dart-side status returned by getStatus() carries only (sessionId, active, lastSeq); state is currently dropped at the SDK boundary.
BiosignalBatch
Transport mapping
The proto is transport-agnostic; the SDK uses each platform’s native companion channel:| Platform | Transport | Notes |
|---|---|---|
| iOS + watchOS | WatchConnectivity.WCSession | sendMessage for live, transferUserInfo for queued. |
| Android + Wear OS | Wearable.MessageClient / DataClient | Same pattern: MessageClient for live, DataClient for queued. |
MethodChannel("ai.synheart.session/methods") + EventChannel("ai.synheart.session/events") pair.
Channel surface
getWatchStatus() returns the connectivity snapshot:
Ordering guarantees
SessionStartedprecedes any frames or summary for a givensession_id.seqis monotonic non-decreasing within a single session id; gaps may exist if the transport drops frames.SessionSummaryandSessionErrorare mutually exclusive — the watch emits one or the other to terminate.BiosignalBatchevents are not ordered relative toSessionFrameevents; consumers must usetimestamp_msfor chronological alignment.
Privacy posture
- Default
enable_raw_stream = false. Opt-in only. - When raw streaming is enabled, the producing HSI block must include
raw_biosignals_allowed = true. - No PII fields cross the wire —
session_idis a host-supplied identifier (default UUID v4),window_labelis free-form but documented as no-PII.