Process
Deprecation policy
Matter's deprecation contract with customers. Minimum 90-day notice; minimum 24-month sunset window from deprecation; automatic Deprecation + Sunset + Link headers on deprecated endpoints; personalised migration emails monthly. Sacred.
Last updated
Backwards compatibility is a sacred principle for Matter. The deprecation policy below is how that principle survives the inevitable need to replace endpoints.
The contract
When Matter deprecates an endpoint:
- At least 90 days' notice before the deprecation is announced publicly.
- At least 24 months' sunset window from the announcement to the date the endpoint stops working.
- Automatic headers on every response from a deprecated endpoint:
Deprecation: <date>,Sunset: <date>,Link: <migration-guide-URL>. - Personalised emails to customers actively using a deprecated endpoint, sent monthly until they migrate or the endpoint sunsets.
- Migration tooling (
matter migrate-deprecatedCLI command) auto-suggests replacement calls based on the customer's actual traffic. - Sunset endpoint returns 410 Gone with
code: op_endpoint_sunset+ migration guide link indetail. Never silently 404; never silently 200 with a different shape.
These commitments are stricter than what is industry-typical. They are stricter on purpose — Matter is the corporate infrastructure layer; customers integrate against us with code that will outlive most projects. The contract has to be longer than the integration's lifetime.
How a deprecation is decided
Endpoint deprecation is never an offhand decision. It is:
- Proposed in an RFC. The proposer explains why the deprecation is necessary, what replaces it (or what new shape it takes), and the migration path. RFC at
apps/docs/rfcs/<yyyy-mm-dd>-<slug>.mdx. - Reviewed by the API Council. The Council weighs the cost of breaking customer integrations against the cost of maintaining the old surface. Approval requires ≥ 3 reviewers including the bounded-context owner.
- Production-readiness review for the replacement endpoint. The replacement must be at least Beta before the old endpoint is announced as deprecated.
- Customer impact analysis. Per-endpoint usage telemetry identifies who is currently calling the endpoint. The analysis informs the personalised email plan.
- Announcement. Status page entry + customer email to active users + changelog entry + deprecation guide page at
apps/docs/content/docs/changelog/deprecations/<endpoint>.mdx. - Telemetry monitoring. Active usage tracked until sunset. If usage is not declining, intensive customer outreach.
What counts as a deprecation
The following all require the deprecation procedure:
- Removing an endpoint. Obvious.
- Renaming an endpoint. Old name is deprecated; new name introduced.
- Renaming a field on a request or response. Old name deprecated in the schema; CI gate emits a deprecation header for any response that includes the old name.
- Removing an enum value. Existing rows that used the value continue to read correctly; new mutations using the value emit a deprecation header.
- Changing a default value for an optional field in a way that changes behaviour. Old default deprecated; new default opt-in for a sunset window.
- Changing an error code's family (e.g.,
auth_token_invalid→validation_token_format). Old code deprecated; new code introduced. - Lowering a rate limit for a tier (this is a customer-visible regression).
- Changing a webhook event payload shape beyond additive.
The following are not deprecations and may ship freely within a minor:
- Adding a new endpoint. Pure addition.
- Adding a new optional field to a request or response.
- Adding a new enum value (the schema marks as
x-matter-enum-extensible). - Adding a new error code (the family is open).
- Loosening a rate limit.
- Adding a new webhook event type.
- Improving an error's
detailtext.
The Spectral spec lint + oasdiff backwards-compat gate enforces this distinction.
How deprecation headers work
When an endpoint is deprecated, the spec carries:
paths:
/v1/legacy_endpoint:
post:
x-matter-maturity: deprecated
x-matter-deprecation:
announced: 2026-06-01
sunset: 2028-06-01
migration_guide: https://docs.mattermode.com/changelog/deprecations/legacy-endpoint
replacement: POST /v1/new_endpointThe maturity-gate middleware automatically emits the headers on every response from this endpoint. No handler code is required.
Customers who watch for the Deprecation header in their HTTP client see the deprecation immediately on their next call. SDKs surface the header as a warning to stderr. CLI surfaces it inline.
Personalised emails
Monthly cron sends emails to customers whose tokens have called a deprecated endpoint in the last 30 days. The email includes:
- The endpoint deprecated and the sunset date.
- The replacement with example payload.
- The customer's recent call patterns (anonymised; no PII) so they recognise their own integration.
- The migration CLI command they can run today.
- A direct link to the migration guide.
The email cron is at apps/api/app/api/cron/personalised-deprecation-emails/route.ts (P11.33).
Migration tooling
The CLI command matter migrate-deprecated (P11.34):
- Reads the customer's recent traffic from the request inspector.
- Identifies deprecated-endpoint calls.
- For each, suggests the replacement call with the customer's actual payload remapped.
- Offers a code-rewrite preview (TypeScript / Python / Go).
- Optionally writes the diff to the customer's local repo.
The customer never feels alone in the migration.
Sunset behaviour
On the sunset date, the endpoint returns 410 Gone with:
{
"type": "https://docs.mattermode.com/errors/op_endpoint_sunset",
"title": "Endpoint sunset",
"code": "op_endpoint_sunset",
"detail": "POST /v1/legacy_endpoint was sunset on 2028-06-01. Migrate to POST /v1/new_endpoint per https://docs.mattermode.com/changelog/deprecations/legacy-endpoint.",
"instance": "urn:matter:request:<request_id>"
}The endpoint does not silently become 404 (that would be ambiguous with a misspelled path). It does not return a different shape (that would be a breaking change). It returns 410 Gone with full context.
A sunset endpoint stays sunset for 12 months after the sunset date, returning 410 Gone for any call. After that, the endpoint may be removed from the spec and the 410 handler may be removed; calls then return the default 404 from the route resolver. By that point, no live customer is calling.
Extension and exception
In rare cases, a customer with an enterprise contract may request an extension of a sunset window for their organisation. Extensions require:
- Customer Success approval. Documented business reason.
- Engineering approval. Cost of maintaining the endpoint for one customer is bounded.
- Extension contract. Per-customer feature flag keeps the endpoint alive for them specifically.
- Time-bounded. Extensions are ≤ 12 months from the original sunset. Beyond that, the endpoint is removed regardless.
Extensions are rare. They are accounted for in the engineering capacity plan.
Why the policy is this strict
Matter's customers integrate against the API to run the legal lifecycle of their company. A customer who incorporated their company through Matter in year 1 expects to dissolve the company through Matter in year 7. The API surface they integrated against must still work — not the same UI, not the same dashboard, the same API.
If we let endpoints sunset on a 6-month timeline, we tell those customers their integration is disposable. We are not in that business.
24 months is the floor. In practice, GA endpoints will be supported for the foreseeable lifetime of the platform. Deprecations happen; they just happen with respect for the customer's integration timeline.
See also
- API design philosophy — principle 9 (Backwards compatibility is sacred)
- API Council — approves deprecations.
- API review checklist — items 60–63 cover deprecation.
- Customer SLA — the customer-facing commitment.