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 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