Skip to main content
The Synheart SDKs (Dart, Swift, Kotlin) are thin shells over a native runtime binary. They communicate across a stable C ABI that is loaded at startup via dlsym (Apple platforms / Linux) or JNI (Android). This page documents the symbols your SDK actually calls.
Most apps never touch this layer directly — the SDK wraps it. This page is for: build-error diagnosis, custom integrations (CLIs, embedded hosts), or auditing what the SDK does on your behalf.

When you’d care

You see one of these:
  • A linker error mentioning libsynheart_core_runtime or undefined synheart_core_* symbols.
  • A dlsym / JNI error at runtime.
  • You’re embedding the runtime directly without using the SDK shells.
  • You’re writing platform glue code that calls the runtime from a non-mainstream language.
If none of these apply, Architecture is the page you want.

ABI rules

  1. C calling convention — extern "C", no name mangling, no exceptions across the boundary.
  2. Handle ownership — synheart_core_new returns an opaque *const SynheartCore handle that the SDK owns and must free with synheart_core_free.
  3. Strings out of the runtime are heap-allocated *char (UTF-8, null-terminated). Caller must release with synheart_core_free_string. Returning NULL means “no value” (not an error — check last_error_code).
  4. Strings into the runtime are borrowed for the duration of the call. The runtime copies what it needs.
  5. Structured returns are JSON strings. Lenient JSON parsing on both sides — unknown fields are tolerated.
  6. Error codes are negative integers; success is 0 or a positive value (e.g. queue length).
  7. Thread safety — the runtime is internally synchronised. Any thread can call any function on a handle. Callbacks (HSI, log, stream) fire on a runtime-owned thread; the SDK shell is responsible for re-dispatching to the host’s UI/main thread.
  8. ABI version — synheart_core_build_info reports the C ABI as MAJOR.MINOR. A new MINOR only adds symbols; a new MAJOR removes or re-signs some, so an SDK built for one MAJOR refuses the others. Runtime 0.42 is ABI 4.0, 0.43 is 4.1 (HSM Schema consent) and 0.45 is 4.2 (the daily score inputs changed shape). Flutter synheart_core 0.22 and later and Kotlin and Swift 0.6 and later require ABI 4.2 (runtime 0.45.0 or later).

1. Handle and lifecycle

2. Session lifecycle

3. HSI streaming

The runtime emits HSI 1.3 windows on a configurable cadence (default: 60s window, 5s step). Hosts subscribe via callback; the SDK exposes the stream as Stream<HSIState> / AnyPublisher<...> / Flow<...>.

4. Sample ingest

Signatures below were introduced in ABI 4.0 (runtime 0.42) and are unchanged through ABI 4.2. ts_ms is Unix epoch milliseconds. provider names the source ("ble_hrm", "sdk_wear", …; NULL uses the default). utc_offset_min is the person’s offset from UTC at the sample, in minutes (±840), so samples land on the right local day across a daylight-saving change or a flight.

5. Cloud upload

The runtime owns a persistent SQLite upload queue. The SDK observes it; the runtime drains it. See Cloud Protocol for the wire shape. See Consent System and Capability System for the model.

7. Sessions and local storage

The runtime owns local persistence (SQLite plus encrypted preference storage on Apple/Android).

8. SRM and baselines

The Self-Reference Model maintains longitudinal baselines per subject.

9. Sync

Every function except set_sync_enabled returns a JSON envelope: {"ok": true, "data": {...}} on success, or {"ok": false, "error": {code, message, retryable, owner, recovery, ...}} on failure. Free the string with synheart_core_free_string. See Cross-device sync for the flow and error codes.

10. Account deletion

11. Multi-source priority resolver

When multiple wearables / vendors push the same metric, the runtime de-duplicates via a priority resolver. SDKs configure it so the SDK consumer’s source preferences flow into the runtime gate.

12. Stateless score computation

These are stateless utility calls — they don’t read or mutate the handle’s state, just compute a result from the input JSON. The _handle parameter is unused; pass NULL.

13. Apple Health backfill

When a user exports export.zip from the iOS Health app, the SDK feeds it back into the runtime via this batch path. Idempotency keys ensure repeated imports don’t duplicate samples.

14. Diagnostics

15. Memory management

Forgetting to call this on returned strings leaks memory. SDK shells handle it automatically; custom integrations must call it themselves.

Symbols this page does not document

The runtime exports more than what’s listed here. Those undocumented symbols are either:
  • Tracing variants (*_traced with a correlation id parameter) — useful for runtime debugging only.
  • Vendor event ingestion (*_vendor_*) — internal to the cloud connector seam.
  • Internal counters (frame_count, last_features, last_quality) — diagnostic-only, may change.
Treat anything not on this page as unstable. If you find yourself needing one of these, file an issue against the relevant SDK repo at github.com/synheart-ai.