Requirements & goals:
- Backward compatibility for existing consumers (internal & external)
- Clear discoverability, easy testing, and safe migration paths
- Auditability and automation for enforcement and deprecation
Versioning approach
- Default: URL-based major versioning for public data API (e.g., /v1/events). Rationale: explicit, cache-friendly, easy for partners to pin, simpler for proxies/CDNs and documentation. Major versions indicate breaking changes.
- Complementary: Header-based for minor/patch feature flags and opt-ins (e.g., Accept: application/json; version=1.2). Rationale: avoids URL churn for non-breaking or experimental features, allows clients to opt into new fields without changing endpoints.
Semantic versioning practices
- Follow MAJOR.MINOR.PATCH semantics:
- MAJOR: breaking schema changes (rename/remove field, change types)
- MINOR: additive, backwards-compatible (new optional fields, new endpoints)
- PATCH: bug fixes, performance tweaks, non-consumer-visible fixes
- Publish machine-readable version metadata at /.well-known/api-version and via OpenAPI.
Deprecation windows & policies
- Policy: Minimum 90-day deprecation for internal teams, 180-day for external partners; longer for enterprise SLAs.
- Steps:
- Announce: release notes + email + status page + partner portal (day 0)
- Dual support: continue old major version for window
- Telemetry: track client usage per version (user-agent, API key)
- Reminders: 60/30/7 days before removal
- Hard cutoff + archive docs; keep data export available for historical access
Tooling & docs to smooth migrations
- Automated version compatibility tests in CI: contract tests (PACT or schema validation) run against consumer mocks.
- Provide migration guides per release: diffs of schemas, sample queries, mapping scripts, SQL snippets for downstream ETL adjustments.
- SDKs & client libraries pinned to semver with helper functions to detect breaking fields.
- Sandbox environment mirroring prod with new versions for partner testing.
- Usage dashboards and alerts showing clients still on older versions; offer one-click rollout helpers for internal teams.
Trade-offs
- URL-based: more visible & cacheable but requires endpoint proliferation. Header-based: cleaner URLs, flexible, but harder for caching, less discoverable, and trickier for some proxies and browser tools.
- Hybrid gives clarity for breaking changes while enabling smoother evolution via headers.
Operational notes
- Enforce schema evolution rules (no changing field types, make new fields optional) via CI hooks.
- Log API version per request and expose metrics to prioritize migration outreach.
This strategy balances clarity for external partners with flexibility for iterative improvements and provides operational controls to manage risk and migration burden.