Skip to main content
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, 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 for the full User-Agent format.

SemVer rules for SDKs

BumpWhen
MAJORA breaking change (see below).
MINORBackward-compatible additions: a new method, a new optional parameter, or a new model.
PATCHBackward-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.
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.

Deprecation and sunset

We give a minimum 30-day notice before removing anything consumers depend on. API deprecations are signalled on the affected responses:
HeaderMeaning
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). 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:
SDKMechanism
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; every consumer-facing change ships with a changeset.
  • Kotlin / Swift: release notes are generated from the changelog at tag time.

SDKs overview

The three SDKs, install, and what they share.

SDK differences

Where idiomatic naming and types diverge per language.