Versioning and deprecation

What you can build against, what can change under you, and how much warning you get before anything is removed.

Versioning

The major version is in the URL path. There is no version header, and no date-pinned version to choose.

bash
https://api.stack0.dev/v1/mail/emails

Within v1, only additive changes ship. A breaking change requires a new major version at a new path prefix, and both run side by side through the deprecation window below.

What can change within v1

Ships any time

  • A new endpoint.
  • A new optional request parameter or body field.
  • A new field in a response body.
  • A new value in an enum that only appears in a response.
  • A new error code, alongside the existing HTTP status.
  • A new response header.

Needs a new version

  • Removing an endpoint, a field, or a parameter.
  • Renaming an endpoint, a field, or a parameter.
  • Narrowing a type, or making an optional request field required.
  • Changing the HTTP status an existing condition returns.
  • Changing the meaning of an existing field.
  • Removing a value from an enum that appears in a request.

Because new response fields can appear at any time, parse responses tolerantly: ignore fields you do not recognize rather than rejecting the payload.

How deprecation works

1. Announced

The endpoint is marked deprecated in the OpenAPI document and in these docs, and the replacement is named. Behaviour does not change.

2. Signalled on the wire

Every response to the endpoint carries a Deprecation header, a Link to the migration note, and a Sunset header with the removal date.

3. Sunset

On the date in the Sunset header, the endpoint stops responding and returns 410 Gone. The replacement stays available.

Notice period

What is being removedMinimum notice
A whole major version, such as v112 months
A stable endpoint or field12 months
An endpoint documented as beta or preview30 days
A change forced by a security issue or a legal obligationAs much as is safe; announced by email to affected accounts

Headers on a deprecated endpoint

You do not have to read a changelog to notice a deprecation. It is on every response.

http
HTTP/1.1 200 OK
Deprecation: @1780272000
Sunset: Wed, 01 Jul 2026 00:00:00 GMT
Link: <https://www.stack0.dev/docs/versioning>; rel="deprecation"; type="text/html"
Link: <https://www.stack0.dev/docs/versioning>; rel="sunset"; type="text/html"
HeaderSpecificationMeaning
DeprecationRFC 9745When the endpoint was deprecated, as a structured-field Date: @ followed by Unix seconds.
SunsetRFC 8594When it stops responding, as an HTTP-date. Never earlier than the Deprecation date.
Link; rel="deprecation"RFC 9745The migration note for this endpoint.
Link; rel="sunset"RFC 8594The same note, at the relation the sunset specification registers.

Detecting it from code

Log the header once per deployment and you will hear about a deprecation the day it is announced, not the day the endpoint stops working.

typescript
const response = await fetch("https://api.stack0.dev/v1/mail/emails", {
headers: { Authorization: `Bearer ${process.env.STACK0_API_KEY}` },
});
const deprecation = response.headers.get("Deprecation");
if (deprecation) {
// Structured-field Date: "@1780272000"
const deprecatedAt = new Date(Number(deprecation.slice(1)) * 1000);
const sunset = response.headers.get("Sunset");
console.warn(
`Stack0 endpoint deprecated ${deprecatedAt.toISOString()}` +
(sunset ? `, removed ${sunset}` : "") +
`. See ${response.headers.get("Link")}`,
);
}

Currently deprecated

Nothing. Every endpoint in v1 is current. When that changes, the endpoint will be listed here and will carry the headers above.

SDK versioning

The client libraries follow semantic versioning independently of the API version. A major SDK release can change the client surface without the API changing, and a new API version does not force a major SDK release. Pin the SDK the way you pin any other dependency.

The machine-readable contract is at /openapi.json. Related: Rate limits and Error handling.