# Migrating from 1.x

2.0 is a major release. This page lists what changed for an app moving from 1.x, breaking changes first. The 1.x docs stay available at [/docs/v1.2/](/docs/v1.2/).

## Licensing moves to attested bootstrap

In 1.x the SDK activated with a pasted `licenseKey`. In 2.0 it proves the app's identity with a platform attestation (Apple App Attest, Android key attestation) and the backend mints the license. You register your app once instead of embedding a key. See [Attested bootstrap](/docs/concepts/attested-bootstrap/) for the model and [Prerequisites](/docs/getting-started/prerequisites/) for setup.

New `LicenseError` cases accompany this: `bootstrapFailed(reason:)` carries a `BootstrapReason` naming the cause. See [License Types](/docs/api-reference/license-types/).

## Breaking changes

- **iOS: `confidence.flags` JSON values are now `UPPER_SNAKE`.** `toJson()` / `toJsonl()` on iOS previously emitted Swift case names (`vpnActive`); they now emit `VPN_ACTIVE`, matching Android. This affects only code that parses the JSON on iOS. The typed `ConfidenceSummary.flags` and `toStr()` are unchanged. See [Serialization](/docs/api-reference/serialization/).
- **Region resolution can now return `regionUnresolved`.** A country or subdivision predicate that cannot resolve the device's region at the required confidence returns `INDETERMINATE / REGION_UNRESOLVED` instead of silently coarsening to an `earth()` claim. Code that treated every `INDETERMINATE` the same should read the reason. See [Verdicts](/docs/concepts/verdicts/).
## Behavior changes to know

- **Proof emission is semantic-binding v2.** Proofs now bind city and earth geometry and a `location_verdict`. Verify 2.0 proofs with `octet-verify` 2.0+ or on-device [`Octet.verify`](/docs/api-reference/octet-verify/), which are v2-first and still accept 1.x proofs.
- **New adversarial reason codes.** A detected spoof now carries `spoofingDetected` or `tampering`, distinct from the benign "couldn't measure" reasons. See the [reason-code taxonomy](/docs/concepts/verdicts/).

## New in 2.0 you can adopt

- **`OctetSdk.close()`** ends the session and stops the Android location foreground service. Call it when your proof flow finishes. See [Session Lifecycle](/docs/concepts/lifecycle/).
- **On-device verification** with [`Octet.verify`](/docs/api-reference/octet-verify/).
- **Decision binding and force-fresh** on the predicates: `decisionRef` and `forceFresh`. See [Proof Binding](/docs/concepts/proof-binding/).

## Version coordinates

Pin `2.0.0` or later. iOS Swift Package Manager `exact: "2.0.0"`; Android Gradle `com.octetproof:sdk:2.0.0`. See the [iOS](/docs/getting-started/ios-quickstart/) and [Android](/docs/getting-started/android-quickstart/) quick starts.
