Docs/API Reference/Octet.start

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

public enum Octet {
    public static let sdkVersion: String  // "1.1.0"

    public static func start(
        config: OctetConfig,
        startPosition: Position? = nil
    ) async throws -> OctetSdk
}
object Octet {
    const val SDK_VERSION: String  // "1.1.0"

    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

  1. Loads (or generates) a per-install UUID from secure storage (Keychain on iOS, EncryptedSharedPreferences on Android).
  2. Auto-detects the app id from the bundle (Bundle.main.bundleIdentifier / context.packageName).
  3. Verifies the license key's PASETO signature locally against the SDK's embedded public keys.
  4. Validates the cached activation token if present. Otherwise calls POST /v1/activate to acquire one.
  5. Brings up the internal proof pipeline.
  6. Attaches the resulting LicenseStatus to the returned OctetSdk.

OctetConfig

public struct OctetConfig: Sendable {
    public let licenseKey: String
    public var proofUploadUrl: String?       // opt-in proof upload; nil disables (default)
    public var telemetryEnabled: Bool        // aggregate usage counters; default true
    public var advanced: AdvancedConfig

    public init(
        licenseKey: String,
        proofUploadUrl: String? = nil,
        telemetryEnabled: Bool = true,
        advanced: AdvancedConfig = AdvancedConfig()
    )

    public static let defaultActivationServerUrl: String  // "https://api.octetproof.com"
}
data class OctetConfig(
    val licenseKey: String,
    val proofUploadUrl: String? = null,      // opt-in proof upload; null disables (default)
    val telemetryEnabled: Boolean = true,    // aggregate usage counters; default true
    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

Still small. Battery profile, sensor tuning, and ML knobs stay internal. What is public: the activation server, log level, device-attestation cadence, and the per-platform attestation knobs.

public struct AdvancedConfig: Sendable {
    public var activationServerUrl: String        // default: production
    public var logLevel: LogLevel                 // default: .info
    public var enableCertPinning: Bool            // default: false
    public var attestationCadence: AttestationCadence  // default: .periodic(interval: 300)

    public init(
        activationServerUrl: String = OctetConfig.defaultActivationServerUrl,
        logLevel: LogLevel = .info,
        enableCertPinning: Bool = false,
        attestationCadence: AttestationCadence = .periodic(interval: 300)
    )
}

public enum LogLevel { case verbose, debug, info, warn, error }

public enum AttestationCadence: Sendable {
    case perSession
    case periodic(interval: TimeInterval)   // default; 5 minutes
    case perProof
}
data class AdvancedConfig(
    val activationServerUrl: String = OctetConfig.DEFAULT_ACTIVATION_SERVER_URL,
    val logLevel: LogLevel = LogLevel.INFO,
    // Google Cloud project NUMBER for Play Integrity; null uses the Play-Console-linked project.
    val playIntegrityCloudProjectNumber: Long? = null,
    val attestationCadence: AttestationCadence = AttestationCadence.Periodic(intervalSeconds = 300),
)

enum class LogLevel { VERBOSE, DEBUG, INFO, WARN, ERROR }

sealed class AttestationCadence {
    object PerSession : AttestationCadence()
    data class Periodic(val intervalSeconds: Int) : AttestationCadence()  // default; 5 minutes
    object PerProof : AttestationCadence()
}

Override activationServerUrl only when pointing at a staging or local backend. attestationCadence and the Android playIntegrityCloudProjectNumber are covered in Device Attestation. enableCertPinning opts into the bundled certificate pin set for api.octetproof.com. The Play Integrity cloud-project knob is Android-only: App Attest on iOS has no equivalent.

Example

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 Cached activation past the offline grace with the backend unreachable to refresh.
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