Versioning and compatibility

How the Voult API and the @voult/* packages are versioned, which versions work together, and how things are deprecated and removed.

The API

The API has one version, semver, shown in three places that always agree:

Change Bump Examples
Breaking major Removing or renaming a route, field or error code; changing a field's type or meaning; making an optional parameter required; rejecting input that used to be accepted; changing a status code or what a route needs to authenticate
Compatible addition minor A new route, optional parameter, response field, header or error code (for a new failure case); a compatible behaviour change, such as a shorter token lifetime that clients already handle by refreshing
Fix patch A bug fix that changes no documented contract

To stay compatible with minor releases, clients must ignore response fields they don't know and treat an unknown error code as a generic failure for its HTTP status.

Every API change is recorded in the root CHANGELOG.md. CI fails a change to controllers/, routes/, services/ or models/ that has no entry.

The packages

@voult/sdk, @voult/core, @voult/express, @voult/react, @voult/cli (and later @voult/next, create-voult-app) each have their own version and CHANGELOG in voult-sdk, and are released from CI with provenance (RELEASING.md).

They are 0.x until launch:

From 1.0 (at launch) the packages follow plain semver: breaking changes only in a major.

Compatibility

Voult API @voult/sdk @voult/express @voult/core @voult/react @voult/cli
1.0 – 1.2 (current) 0.2.x (0.1.3+ still works for password, MFA, magic link and passkeys; hosted OAuth and linking need 0.2.0) 0.2.x, 0.3.x 0.1.x, 0.2.x 0.1.x, 0.2.x 0.2.x

Security fixes

A security fix can change behaviour in a minor or patch release, even when that rejects requests a previous version accepted. Waiting for a major (or a 90-day deprecation) would leave the hole open. Such changes are marked Security in the CHANGELOG, with what to do if they affect you.

Deprecation

Nothing a client can rely on disappears without warning. A deprecated route, field, parameter, header, env variable or package export:

  1. keeps working for at least 2 minor releases of the package that carries it (for an API change: of @voult/sdk) and at least 90 days, whichever is later, after it is announced;
  2. is announced in both CHANGELOGs: the root CHANGELOG.md for the API and the affected package's CHANGELOG, with the replacement and the earliest removal date;
  3. is listed below until it is removed;
  4. tells the caller at runtime where it can: API routes send a Deprecation header (with a Sunset date once removal is scheduled), packages log a one-time warning, and voult doctor flags what it can see.

Removing it afterwards is a breaking change: an API major, or a package minor while in 0.x (marked Breaking).

Currently deprecated

What Replacement Deprecated since Removed no earlier than
redirectUrl in linkOAuthProvider()'s result (@voult/sdk) authUrl @voult/sdk 0.2.0 (2026-09-26) @voult/sdk 0.4.0 and 2026-12-25
Env names CLIENT_ID, CLIENT_SECRET, BASE_URL, SESSION_SECRET, APP_URL (@voult/express, warns once at startup) VOULT_CLIENT_ID, VOULT_CLIENT_SECRET, VOULT_BASE_URL, VOULT_SESSION_SECRET, VOULT_APP_URL @voult/express 0.1.0 (2026-09-22) @voult/express 0.4.0 and 2026-12-21

Error codes

Error codes are part of the API contract:

How the docs track versions