> ## Documentation Index
> Fetch the complete documentation index at: https://docs.expys.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Versioning

> How the /v1 API and the Expys SDKs evolve - SemVer, what counts as breaking, the spec-vs-SDK version relationship, and deprecation timelines.

This page governs how the public `/v1` API and the Expys SDKs (`@expys/sdk`,
`com.expys:sdk`, `expys-swift`) evolve, and what you can rely on as a consumer.

## Versioning model

* **The API is URL-versioned** (`/v1`). A new major API version (`/v2`) is
  introduced only for changes that cannot be made backward-compatibly.
* **SDKs use independent [SemVer](https://semver.org)**, decoupled from the API
  version and from each other. A change to one SDK does not force a release of the
  others.
* **Release tags are per-SDK**: `ts/vX.Y.Z`, `kotlin/vX.Y.Z`, `swift/vX.Y.Z`. The
  Swift mirror repo additionally carries the plain `X.Y.Z` tag SwiftPM resolves.

### Spec version vs SDK version

The **spec version** and **SDK version** are separate. Both are embedded in a
generated constant and in the `User-Agent` header of every request for server-side
attribution - for example `expys-sdk-ts/1.2.0 (spec/1.0.0; env=live)`. The
environment and an optional org id are folded into the comment consistently across
all three SDKs. See [Configuration](/guides/configuration) for the full
`User-Agent` format.

### SemVer rules for SDKs

| Bump      | When                                                                                   |
| --------- | -------------------------------------------------------------------------------------- |
| **MAJOR** | A breaking change (see below).                                                         |
| **MINOR** | Backward-compatible additions: a new method, a new optional parameter, or a new model. |
| **PATCH** | Backward-compatible bug fixes.                                                         |

## What is a breaking change

For the **API**:

* Removing or renaming an endpoint, response field, or enum value.
* Changing the type of an existing field.
* Adding a newly **required** request parameter or body field.
* Tightening validation or changing the semantics of an existing field.
* Changing authentication, scopes, or error `code` values consumers branch on.

For an **SDK**, additionally:

* Removing or renaming a public symbol, or changing a public method signature.
* Changing a public type in a source- or binary-incompatible way.

The following are **not** breaking - consumers must tolerate them: adding optional
response fields, new endpoints, new optional parameters, and **new error `code`
values**.

<Tip>
  Handle unknown error codes gracefully: match on the codes you know and fall back
  for the rest. A new `code` can ship in a minor release, so branching exhaustively
  will eventually surprise you. See [Errors](/guides/errors).
</Tip>

## Deprecation and sunset

We give a **minimum 30-day notice** before removing anything consumers depend on.

**API deprecations** are signalled on the affected responses:

| Header                               | Meaning                                                                                                                 |
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------- |
| `Deprecation: true` *(or a date)*    | The operation or field is deprecated.                                                                                   |
| `Sunset: <HTTP-date>`                | The date on or after which it stops working ([RFC 8594](https://www.rfc-editor.org/rfc/rfc8594)). At least 30 days out. |
| `Link: <...changelog>; rel="sunset"` | Pointer to the changelog entry with details.                                                                            |

Each deprecation is also recorded in the changelog and the developer portal.

**SDK deprecations** mark the symbol with the platform's native mechanism one
**MINOR** release before removal in the next **MAJOR**:

| SDK        | Mechanism                                                |
| ---------- | -------------------------------------------------------- |
| TypeScript | `@deprecated` JSDoc.                                     |
| Kotlin     | `@Deprecated(...)`, with a `ReplaceWith` where possible. |
| Swift      | `@available(*, deprecated, message: "...")`.             |

## Contract enforcement

* The committed snapshot `packages/api-spec/v1.json` is the single source of
  truth. `oasdiff` (in the API Spec workflow) **fails any PR that introduces a
  breaking change** to it; shipping one requires a new major plus migration notes.
* The SDK generation input `packages/api-spec/v1.sdk.json` and all generated
  types and models are drift-gated in CI - regenerate, fail on diff.
* Contract tests assert the SDK spec is a faithful projection of the API spec.

## Support window

The latest **MAJOR** of each SDK is fully supported. The previous major receives
security fixes for the duration of the 30-day notice window after its successor's
release. Older majors are unsupported.

## Changelog

* **TypeScript**: managed by [changesets](https://github.com/changesets/changesets);
  every consumer-facing change ships with a changeset.
* **Kotlin / Swift**: release notes are generated from the changelog at tag time.

## Related

<CardGroup cols={2}>
  <Card title="SDKs overview" icon="cubes" href="/sdks/overview">
    The three SDKs, install, and what they share.
  </Card>

  <Card title="SDK differences" icon="code-compare" href="/sdks/differences">
    Where idiomatic naming and types diverge per language.
  </Card>
</CardGroup>
