/api/v1is frozen: a route that ships in/api/v1keeps its request and response shapes until its removal is announced through at least one minor deprecation window. No silent breaking changes.- Additive changes (new optional fields, new routes, new permissions) are not breaking and may land any time.
- The OpenAPI spec per service is the source of truth. If the spec says it, clients may rely on it; if the code does something the spec doesn't say, the code is wrong.
- Mark responses with the RFC-9745 headers using
platform.Deprecation(w, at, sunset)(internal/platform/security.go). - Announce in release notes +
docs/CONTRACTS.md. - Keep the old shape for ≥90 days after the deprecation announcement.
- Removal lands only in a major wave boundary, never mid-wave.
- New services may start at
/api/v2directly; existing services add/api/v2routes alongside v1 during the overlap window. - The gateway registry handles both: specs annotate their own paths, prefixes are mechanical. Consumers migrate per-route, not big-bang.
- Per-consumer version negotiation headers — overkill while all consumers are first-party frontends.
- Long-lived public SDKs —
packages/contractsregenerates from the aggregate spec on every build, so clients are always in sync.