The SDK follows semantic versioning. This page describes how to pin safely, what compatibility is guaranteed between the CDN bundle and the embed capture frame, and the non-breaking evolution contract that governs what can change without a major version bump.

## Pinning

**npm:** pin to an exact version in `package.json`:

```json
{
  "dependencies": {
    "@checktiv/sdk-web": "1.2.3"
  }
}
```

Do not use `^` or `~` in production. A patch release may change behavior in ways you have not tested.

**CDN:** always pin the version in the URL and supply the Subresource Integrity hash from the [release notes](/developers/sdks/release-notes):

```html
<script
  src="https://sdk.us.checktiv.com/sdk/1.2.3/sdk.js"
  integrity="sha384-<hash-from-release-notes>"
  crossorigin="anonymous"
></script>
```

Loading `sdk.js` without an SRI hash or from an un-pinned URL exposes you to CDN compromise; a tampered bundle would run with full page access.

## SDK-to-embed compatibility window

The SDK (the JavaScript you install) communicates with the capture frame (served by the platform) over a versioned postMessage protocol. The platform guarantees backwards compatibility for at least two prior SDK major versions. You will not be stranded by a platform update.

When the protocol advances (a `v2` prefix), the platform serves both `v1` and `v2` simultaneously during a transition window. SDK releases that ship during the window accept either. You will be notified in the [release notes](/developers/sdks/release-notes) when a version is scheduled for retirement.

## The non-breaking evolution contract

The following changes may be made without a major version bump:

### 1. Additive `bt_*` scopes

New optional scopes may be added to `bt_*` tokens. An old token that was minted without a new scope continues to work for the routes it was originally valid for. Your mint endpoint does not need changes until you adopt a feature that requires the new scope.

### 2. Additive event namespaces

New event types may be added at any time. The event stream is forward-open: `checktiv.${string}` is the tail, so any string beginning with `checktiv.` is a valid event type. Event literals are never reused with a different meaning.

**Do not exhaustively switch on `event.type`.** Unknown event types may arrive without a major version bump. Always include a `default` case or an `else` branch:

```js
onEvent: (event) => {
  if (event.type === 'checktiv.idv.submitted') {
    // handle
  } else if (event.type === 'checktiv.idv.error') {
    // handle
  }
  // Unknown events: ignore silently.
};
```

### 3. `checktiv.idv.submitted` is frozen

The `checktiv.idv.submitted` event will never gain a decision or verdict field. It signals that capture is complete, nothing more. The verdict arrives via `kyc.session.*` webhook. See [Verdict and webhooks](/developers/sdks/verdict-and-webhooks).

### 4. Managed-to-headless migration path

A customer can move from the server-driven `mountProvisioned` path to the explicit `mount('idv', opts)` override, or to the headless `createCaptureController` kernel, without a contract break. The session, token, and event contracts are identical across all three mount paths.

## Pre-GA features (betas)

Some features are available before general availability via opt-in flags:

```js
Checktiv.init({
  publishableKey: 'ah_pk_us_test_...',
  getSessionToken: async (ctx) => {
    /* ... */
  },
  betas: ['idv_enhanced_coaching_v1'],
});
```

Unknown entries in `betas` are silently ignored; a future beta name is forward-compatible. Pre-GA surfaces are exempt from the additive-only guarantee until they reach GA. Breaking changes to a pre-GA feature are announced in the [release notes](/developers/sdks/release-notes) with at least one release of notice.

## Related pages

- [Release notes](/developers/sdks/release-notes) - changelog, SRI hashes, and retirement notices
- [Secret key rotation](/developers/sdks/sk-key-rotation) - rotate your `ah_sk_*` key independently of SDK versions
- [Error reference](/developers/sdks/error-reference) - `protocol_mismatch` and what it means in practice