Versioning and deprecation

The version is part of the path: /api/v1/…, /api/v2/…. It is never a header and never a query parameter — a version you can see in the URL is a version you can pin, log and grep for.

The guarantee

Within a published version we may add: a new endpoint, a new optional field in a response, a new optional parameter. We will not remove a field, rename one, tighten a type or change a status code. Any of those is a breaking change, and a breaking change means a new version, never a change to the existing one.

This is enforced in our pipeline: a contract diff runs on every change and blocks the build when a breaking change appears in a version already published. It is a gate, not a habit.

So write your client to ignore unknown fields. A strict parser that rejects them turns our non-breaking addition into your outage.

Versions in parallel

v1 and v2 of the same endpoint are served at the same time and reach the same underlying logic; only the public contract differs. Migrate when it suits you, endpoint by endpoint — there is no flag day.

Deprecation headers

When a version is on its way out, its responses announce it. The headers are present on every response of that endpoint, including errors — you do not have to make a successful call to discover it.

Header Format Example
Deprecation @ + seconds since the Unix epoch Deprecation: @1788220800
Sunset HTTP-date (RFC 9110) Sunset: Sun, 30 Nov 2025 00:00:00 GMT
Link Documentation, rel="deprecation" Link: <https://…>; rel="deprecation"

The two date formats deliberately differ — Deprecation carries a structured-field date (@epoch), Sunset an HTTP-date. Parse each accordingly rather than assuming they match.

Deprecation is the date the endpoint became deprecated; Sunset is when it stops being served. Between them, the endpoint works exactly as before.

What to do about them

Log these headers. An integration that ignores them keeps working right up to the moment it does not, and the sunset date is precisely the warning you were given.

A practical setup: raise an alert the first time a response carries Deprecation, and a louder one as Sunset approaches. The migration path is always documented at the Link URL when one is published.

One caveat: these headers are written by the endpoint itself, so a 401 from an expired token — rejected before reaching the endpoint — carries no announcement. Read them from calls that actually authenticate.