Skip to main content
The binary SDK is gated by a license key that NEUROFIT issues for your app identifiers. Verification happens entirely on the device: the SDK checks the key’s signature against a public key compiled into the SDK. There is no network call, no persistence and no telemetry. Source licensees receive a key of type source and use the same call.

Installing the key

Call activate once, early in your app’s life and before creating a session. The key is a single string.
Keep the key out of source control the same way you would any configuration value: an xcconfig that is not committed, a BuildConfig field fed from local.properties or CI secrets, or your existing config system. The key is bound to your app identifiers and cannot be used by another app, so a leaked key does not let anyone else ship the SDK, but it is still licensed material. activate is synchronous and fast, and safe from any thread. After it succeeds, VitalsSDK.licenseStatus returns the parsed status; before that it is nil / null, and creating a session (or calling start()) throws notActivated. The app identifier it checks is Bundle.main.bundleIdentifier on iOS and the application id (context.packageName) on Android. The key is held in memory only; activate again on every launch.

Key format

The payload is JSON with these fields: LicenseStatus exposes licensee, apps, features, updatesUntil, type (iOS LicenseType.binary / .source, Android LicenseType.BINARY / SOURCE) and warnings.

What updatesUntil means

Your license is perpetual. updatesUntil is the end of your maintenance period, and it works like this:
  • Every SDK build carries a build date (VitalsSDK.buildDate, for example 2026-09-30).
  • A key accepts any SDK build whose build date is on or before updatesUntil.
  • An SDK build released after updatesUntil refuses the key with licenseUpdatesExpired(updatesUntil:).
  • Builds you already ship keep working forever. Nothing expires inside your users’ installed apps.
So when maintenance lapses you keep using the last SDK version released during your maintenance period; when you renew, NEUROFIT issues a key with a later updatesUntil and newer builds accept it. The check compares dates inside the key and the SDK only; it never reads the device clock, so a wrong system time cannot break a reading.

Verification order and errors

The checks run in this order and stop at the first failure: Swift throws VitalsError; Kotlin throws the matching VitalsException subclass (LicenseInvalid, LicenseUpdatesExpired, LicenseNotValidForApp); the wrappers reject with the same case name in code.

Debug builds

The app-identifier check can be relaxed for development: instead of throwing licenseNotValidForApp, activate succeeds and adds a message to LicenseStatus.warnings naming the licensed apps. This lets you run the sample apps and your own debug flavours under identifiers that are not on the key. The two platforms decide differently:
  • Android decides at runtime: the relaxation applies when the host app is debuggable (ApplicationInfo.FLAG_DEBUGGABLE). A debug build of your app gets the warning; a release build is rejected.
  • iOS decides at compile time of the SDK module (#if DEBUG inside NeurofitVitals). With the SwiftPM source integration that follows your build configuration, so Debug builds get the warning. The binary xcframework is built Release and never relaxes the check, whatever your app’s configuration: use a key that lists every bundle identifier you run under, including development ones.
Release builds enforce the check on both platforms.

Several app identifiers

One key can list several identifiers (production, staging, a white-label variant). Ask NEUROFIT to include every identifier you ship under. Adding an identifier later means a new key; the old key keeps working.

Rotation and re-issue

Keys are signed by NEUROFIT’s production signing key and carry its kid. If NEUROFIT ever rotates the signing key, the SDK build that carries the new public key ships together with re-issued keys for every licensee under maintenance, and the release notes say so. Builds you already ship are unaffected. Lost keys are re-issued on request; there is nothing to revoke on the device.

Source licenses

A source license ships the engine and SDK sources. Your build still calls activate with a key of type source, which verifies the same way. Because you build from source, you can also replace the compiled-in public key or the check itself; the license agreement, not the key, is what governs your use.

Questions

Licensing questions go to contact@neurofit.app. Include your licensee name and the kid from your key.