Designing API Deprecation Headers: How the Deprecation and Sunset HTTP Headers Actually Work
The HTTP Deprecation and Sunset headers let an API tell clients which endpoints are deprecated and when they will stop working. Most APIs do not use them. The reasons are mostly cultural, and the small group of APIs that do use them get most of their value from the surrounding discipline.
The HTTP Deprecation and Sunset headers, defined respectively in draft-ietf-httpapi-deprecation-header and RFC 8594, let an API tell clients which endpoints are deprecated and when they will stop working. Most APIs do not use them. The reasons are partly that the standards are recent and partly that the value of the headers is not visible until well-instrumented client libraries notice them. The small group of APIs that do use the headers get most of their value not from the protocol but from the surrounding discipline that adopting the headers requires.
What the headers say
The Deprecation header carries either a boolean (the older non-standard form, just Deprecation: true) or an HTTP-date (the standardized form: Deprecation: Sun, 11 Nov 2026 00:00:00 GMT, which is the date deprecation went into effect). The presence of the header on a response indicates that the endpoint is deprecated. The date form lets the client know when the deprecation started, which is useful for distinguishing endpoints that are about to disappear from endpoints that have been deprecated for years and continue to work.
The Sunset header carries an HTTP-date indicating when the endpoint will stop working: Sunset: Sun, 11 Nov 2027 00:00:00 GMT. The two headers usually appear together, with Deprecation marking the start of the deprecation window and Sunset marking the end. The window between them is when clients can still use the endpoint but should be migrating off it.
Both headers can be accompanied by a Link header pointing to documentation: Link: <https://anethoth.com/api/migrations/v1-to-v2>; rel="sunset". The link is the part most client libraries actually surface to engineers, because it is the part most likely to contain actionable information.
What the client side is supposed to do
The intended client behavior is for HTTP libraries or SDKs to notice the headers and emit warnings to the engineer's console or logs. The warning should include the endpoint, the deprecation date, the sunset date, and the migration link. The engineer sees the warning during development or in production logs and has time to migrate before the sunset date arrives.
This intended behavior happens unevenly in practice. Some SDKs implement deprecation-header handling and emit clear warnings; many do not. Generic HTTP libraries usually do not emit warnings unless the engineer explicitly checks for the headers in their code. The result is that the headers reach client code but are often discarded silently unless the client team has specifically built infrastructure to consume them.
The corollary is that the value of emitting the headers is conditional on what the customer's tooling does with them. APIs that ship official SDKs alongside the API can guarantee the headers are surfaced because the SDK is the customer's tool. APIs that do not ship SDKs and rely on customers using generic HTTP clients get less mechanical benefit from the headers and more value from the discipline of structured deprecation communication.
The two-year deprecation window
The standard B2B SaaS deprecation window is two years between Deprecation and Sunset. This matches the customer-side planning cycle: most B2B customers have annual or multi-year roadmaps and need a window that fits inside their planning horizon. A six-month window is too short for many customers to schedule and complete an integration migration; a five-year window is so long that customers forget about the deprecation until it is imminent.
Stripe, GitHub, and several other reference cases use two-year windows. The shorter windows that occasionally appear (60-day deprecations for security-sensitive changes) are exceptions justified by specific reasons rather than the standard pattern. The longer windows that occasionally appear (multi-year stability commitments for specific endpoint families) are also exceptions, usually associated with enterprise contracts.
The pipeline that surrounds the two-year window is the part that matters more than the duration. Month 0 is the announcement, posted to the changelog, sent to a deprecation email list, emitted in the Deprecation header. Month 6 is a reminder, sent to customers identified as still using the deprecated endpoint via usage telemetry. Month 12 is a second reminder. Month 18 is a final warning. Month 24 is the Sunset date; the endpoint starts returning 410 Gone. Month 24+90 is the hard cutoff; the endpoint returns 404 Not Found and the route is removed from the application.
The 90-day final phase between Sunset and complete removal is the safety net for customers who missed the earlier signals. Returning 410 Gone with the same Link header gives one last clear signal that the endpoint is deliberately removed, distinguishing it from a transient outage or a routing problem.
The customer identification problem
The reminder pipeline depends on knowing which customers are still using deprecated endpoints. The minimum implementation is to instrument the deprecated endpoint with usage logging that records the customer ID per request. The logs are then queried periodically to produce the list of customers to notify.
The query is straightforward but easily neglected. Most APIs do not invest in deprecation telemetry until they have had an unsuccessful deprecation and learned that announcement alone does not work. The pattern is consistent enough that it is worth building deprecation telemetry from the start, as a small extension of the existing per-endpoint usage metrics.
The customer-side action that the reminder is supposed to trigger is for the customer's team to read the migration guide, schedule the change, and complete the migration before the sunset date. The fraction of customers who do this on the first reminder is small; the fraction by the third reminder is larger; the fraction by the final warning is most. There is always a small tail that does not migrate at all, and the question of how to handle that tail is one of the structural questions of API deprecation.
The grandfather-clause option
One handling pattern for the unmigrated tail is the explicit grandfather clause, where specific customers are granted indefinite continued access to the deprecated endpoint. The reasons can be enterprise contracts, paid migration assistance, or simple risk-aversion about breaking high-value customers. The grandfather clause is invisible at the API level (the endpoint still exists for those customers) but visible at the routing layer (most customers get 410 Gone, grandfathered customers get the old behavior).
The grandfather pattern works but has long-term costs. The deprecated code stays in the codebase indefinitely. The grandfathered customers are not motivated to migrate. The deprecation is partial rather than complete, and the deprecation-completion rate at the team level is permanently lower than 100 percent.
The alternative is hard sunset: the endpoint goes away for all customers on the sunset date, including grandfathered ones. This forces the unmigrated tail to migrate or to lose API access. The risk is losing customers who refuse to migrate; the reward is closing the deprecation cleanly and removing the deprecated code from the codebase.
Our position across our four products has been hard sunset with substantial advance notice. The cost of indefinite grandfathering is more than the value of retaining the small number of customers who would otherwise leave. The judgment is dependent on the specific customer base and the specific deprecated endpoint; for high-volume B2B SaaS the math usually favors hard sunset.
The migration guide as core artifact
The Link header pointing to a migration guide is only as useful as the migration guide is. The standard for the guide is high: it should include the old and new endpoint signatures side by side, the differences in request and response shape called out explicitly, working code examples in the major languages the customer base uses (typically curl, Python, Node.js, Go, possibly PHP), the timing requirements (when the deprecation starts, when the sunset hits), and the contact path for migration assistance.
The guides that work are the ones that let a customer engineer copy the new code, change the endpoint URL, and have a working migration within an hour. The guides that fail are the ones that describe the change in prose without giving the customer a tested code path to copy. The investment in writing good migration guides is one of the higher-leverage investments an API team can make; the cost is hours of writing per deprecated endpoint, the value is hundreds or thousands of customer engineers' time saved.
The headers vs the changelog
The headers are not a substitute for an out-of-band changelog. Customers who do not look at response headers (which is most customers most of the time) need to find out about deprecations through other channels: email, dashboard banners, RSS-feed changelogs, blog posts. The headers complement these channels by giving the deprecation a machine-readable representation that tooling can consume.
The structured changelog is the part that scales. A team that writes one changelog entry per deprecation and configures the rest (Deprecation headers, email notifications, dashboard banners) to derive from that entry has a maintainable deprecation process. A team that writes deprecations one channel at a time has a process that drifts as the team grows.
What does not work
Several patterns appear regularly and consistently fail. Surprise removals (sunsetting an endpoint without prior deprecation) destroy customer trust and produce avoidable churn. Silent behavior changes (an endpoint that changes meaning without changing its URL or version) are worse than removals because they break customers without giving them a visible error to debug. Inconsistent advance notice (deprecations announced with varying windows that customers cannot rely on) makes the announcements less actionable because customers cannot plan against an unpredictable signal.
The pattern that consistently works is the predictable two-year window, with structured changelog plus headers plus reminders plus quality migration guides, applied uniformly across endpoints. The discipline matters more than any specific technical choice; the headers are part of the discipline but not the load-bearing part.
Our use across products
None of our four products (DocuMint, CronPing, FlagBit, WebhookVault) have had a deprecation yet, because they are too young. The first deprecations are likely in mid-2026 or 2027, and we will implement the full pattern: changelog entries, Deprecation and Sunset headers, customer reminders via usage telemetry, migration guides, and hard sunset.
The investment in the deprecation infrastructure is being made before the first deprecation because retrofitting deprecation handling onto an already-existing API is harder than building it in from the start. The headers cost almost nothing to emit; the changelog and migration-guide infrastructure costs more but pays back over many deprecations.
Three observations
First: the Deprecation and Sunset headers are a small standard with disproportionate impact for the APIs that adopt them, because the adoption forces the team to formalize the deprecation pipeline that the headers express. The headers without the pipeline are not very useful; the pipeline with or without the headers is useful, but adopting the headers usually leads to building the pipeline.
Second: the gap between the headers existing and the headers being used is a typical example of how slowly the HTTP ecosystem moves. The standards have been around for years and most APIs still do not use them. The reasons are not technical (the implementation is trivial) but cultural and organizational (the deprecation pipeline is not in place to motivate the headers). This pattern repeats for many HTTP features: the technical adoption is gated on the surrounding practice.
Third: deprecation is the highest-leverage place to invest in API trust. Customers integrate APIs based on a calculation that includes the assumption that breaking changes will be handled responsibly. APIs that handle deprecations well accumulate trust; APIs that handle them poorly accumulate distrust that is hard to recover from. The investment in deprecation infrastructure is one of the things that compounds over the lifetime of an API.
The deeper observation is that backwards-compatibility discipline is largely about respecting customer time. The deprecation pipeline is a series of choices that minimize the customer engineer's effort to keep working: advance notice, structured information, working code examples, predictable timing. Each step in the pipeline saves a particular cost the customer would otherwise pay. The Deprecation and Sunset headers are one part of that pipeline, machine-readable and useful for tooling, but they are not the substance; the substance is the team's commitment to handling deprecations as a recurring, formal process rather than as a series of ad-hoc decisions.