# API Versioning Last updated: 2025-11-25 (Docs Tasks Md.V) ## Principles - **Semantic versioning**: OpenAPI artifacts follow `MAJOR.MINOR.PATCH` where breaking changes bump MAJOR, additive changes bump MINOR, fixes/docs bump PATCH. - **Long-lived compatibility**: At least N-1 major versions remain runnable for 12 months; minor versions remain compatible for 6 months after release unless a security fix requires earlier removal. - **Explicit deprecations**: Every breaking removal/change is preceded by a deprecation window with headers and changelog entries. - **Deterministic specs**: Generated `out/api/*.yaml` are reproducible from a pinned manifest and committed checksums. ## How versions are expressed - **Base URL**: `/api/v{major}/...` (e.g., `/api/v1/policy`). Major only; minor/patch controlled via headers. - **Headers**: - `X-Stella-Api-Version: ` → client-requested minor/patch; server chooses the highest compatible available ≤ requested. If omitted, server serves the latest compatible minor/patch for that major. - `Deprecation: true` + `Sunset: ` returned when an endpoint or field is scheduled for removal. - `X-Stella-Api-Deprecated-Fields: field1,field2` lists soon-to-be-removed members for the response. - **Error codes**: - `error.code = API_VERSION_UNSUPPORTED` when requested major is not served. - `error.code = API_VERSION_TOO_OLD` when requested minor/patch is below the minimum supported for the major. ## Compatibility rules - Additive changes (new fields/enums/paths) are allowed within the same major; fields default to `null`/empty and must not change meaning. - Breaking changes require a new major: field removals/renames, required field additions, behavior changes that alter contracts. - Enum extensions: existing values remain; new values must be tolerated by clients. - Pagination/order: sort keys and determinism must be preserved across versions. ## Release & lifecycle 1) Draft OpenAPI in `src/Api/StellaOps.Api.OpenApi` and update `out/api/stella.yaml`. 2) Run `pnpm api:lint` + `pnpm api:compat --baseline stella-baseline.yaml` to ensure no unintended breaks. 3) Publish changelog entry under `out/api/changelog/-.md` with checksums/signature. 4) Announce deprecations via release notes; include `Deprecation`/`Sunset` headers in affected endpoints for at least 60 days before removal. 5) Sunset execution: remove endpoints/fields only after the sunset date and after the major bump ships. ## Client guidance - Always send `X-Stella-Api-Version` to lock to a tested minor/patch; pin SDK versions accordingly. - Handle `Deprecation`/`Sunset` headers by warning users and planning upgrades. - Prefer server-provided pagination tokens; avoid relying on incidental field order. ## Testing - Contract tests must cover the lowest and highest supported minor/patch for each major. - Deterministic fixtures for each version live under `tests/fixtures/api/versioning/`; CI runs `pnpm api:compat` against these fixtures. - Compatibility diff (`pnpm api:compat old.yaml new.yaml`) now flags: - Added/removed operations and responses - Parameter additions/removals/requiredness flips - Request body additions/removals/requiredness and content-type changes - Response content-type additions/removals Use `--fail-on-breaking` in CI to block removals/requiredness increases.