Octet.start(...)
The single bring-up call. Verifies the license key locally, activates against the Octet backend if needed, brings up the proof pipeline, and returns a fully-usable OctetSdk handle.
Signature
- Swift (iOS)
- Kotlin (Android)
public enum Octet {
public static let sdkVersion: String // "1.0.0-alpha"
public static func start(
config: OctetConfig,
startPosition: Position? = nil
) async throws -> OctetSdk
}
object Octet {
const val SDK_VERSION: String // "1.0.0-alpha"
suspend fun start(
context: Context,
config: OctetConfig,
startPosition: Position? = null,
): OctetSdk
}
startPosition is an optional hint used internally during pipeline bring-up. Most integrators omit it.
What it does, in order
- Loads (or generates) a per-install UUID from secure storage (Keychain on iOS,
EncryptedSharedPreferenceson Android). - Auto-detects the app id from the bundle (
Bundle.main.bundleIdentifier/context.packageName). - Verifies the license key's PASETO signature locally against the SDK's embedded public keys.
- Validates the cached activation token if present. Otherwise calls
POST /v1/activateto acquire one. - Brings up the internal proof pipeline.
- Attaches the resulting
LicenseStatusto the returnedOctetSdk.
OctetConfig
- Swift (iOS)
- Kotlin (Android)
public struct OctetConfig: Sendable {
public let licenseKey: String
public var advanced: AdvancedConfig
public init(
licenseKey: String,
advanced: AdvancedConfig = AdvancedConfig()
)
public static let defaultActivationServerUrl: String // "https://api.octetproof.com"
}
data class OctetConfig(
val licenseKey: String,
val advanced: AdvancedConfig = AdvancedConfig(),
) {
companion object {
const val DEFAULT_ACTIVATION_SERVER_URL: String // "https://api.octetproof.com"
}
}
licenseKey is the only required field. It is a PASETO v4.public token in the wire form octet_live_v4.public.… (prod) or octet_test_… (staging).
AdvancedConfig
Deliberately minimal at v1. Battery profile, sensor tuning, ML knobs, and attestation flags stay internal.
- Swift (iOS)
- Kotlin (Android)
public struct AdvancedConfig: Sendable {
public var activationServerUrl: String // default: production
public var logLevel: LogLevel // default: .info
public init(
activationServerUrl: String = OctetConfig.defaultActivationServerUrl,
logLevel: LogLevel = .info
)
}
public enum LogLevel { case verbose, debug, info, warn, error }
data class AdvancedConfig(
val activationServerUrl: String = OctetConfig.DEFAULT_ACTIVATION_SERVER_URL,
val logLevel: LogLevel = LogLevel.INFO,
)
enum class LogLevel { VERBOSE, DEBUG, INFO, WARN, ERROR }
Override activationServerUrl only when pointing at a staging or local backend.
Example
- Swift (iOS)
- Kotlin (Android)
let config = OctetConfig(
licenseKey: "octet_live_v4.public.…"
// advanced left to defaults
)
let sdk = try await Octet.start(config: config)
lifecycleScope.launch {
val sdk = Octet.start(
context = applicationContext,
config = OctetConfig(licenseKey = "octet_live_v4.public.…")
)
}
Failure modes
Octet.start(...) throws a typed LicenseError for every license-related failure. Other failures propagate as their native error types. The SDK does not throw a raw Error / Exception for license reasons.
LicenseError case | Meaning |
|---|---|
MalformedKey | The key isn't a valid signed token. |
NoActivation | No cached activation, offline. |
Expired | License past day 105, OR cached activation past 7-day offline grace. |
ActivationWindowClosed | Fresh device trying to activate after day 90. |
Revoked | Admin revoke. |
Network(message) / Network(cause) | Transient network failure during activation. |
ServerRejected(httpStatus, reason) | Backend rejected for another reason (e.g., app_blocked). |
See also
- License & Activation for the timeline model and activation flow.
OctetSdkfor whatstartreturns.- License Types for the full
LicenseErrorreference.