Engineering Leadership & Technical HiringPlaybook3 min readUpdated September 2026

Retiring an API Without Breaking the Callers You Forgot About

The hard part of retiring an API endpoint is never the code, it's finding out who's still calling it. A changelog post reaches the callers who read changelogs, which is rarely all of them, and the ones who don't find out from a 404 in production, usually during their own busiest period.

This is a step-by-step runbook for a sunset that doesn't rely on hoping people read your documentation.

How Do You Announce a Deprecation in the Response Itself?

Add a `Deprecation` header to responses from the endpoint the moment you decide to sunset it, well before you set an actual cutoff date, and a `Sunset` header with the real date once you've set one, per RFC 8594's convention. This means every caller finds out on their very next request, in a way their own logging or monitoring can pick up automatically, rather than relying on them having read an announcement somewhere. Machine-readable deprecation notices reach automated clients that a blog post never will.

Measure Who's Actually Still Calling It

Before you set a hard cutoff date, instrument the endpoint to log caller identity, API key, client ID, or IP as a fallback, and volume over at least a full billing or usage cycle. This turns "we think most people have migrated" into an actual list of accounts still sending traffic, which is what you need for the next step, and it often surfaces a handful of high-volume callers that would have caused a real incident if the cutoff happened without you knowing they existed.

Reach the Stragglers Directly, Not Through a Changelog

For the accounts still showing real traffic in your telemetry, email them directly, ideally including their own recent usage numbers so the message is concrete instead of generic, and give them a migration guide specific to what they're calling. A changelog post or a banner in a developer portal reaches engineers who are actively reading documentation that week; a direct email with "your account made twelve thousand calls to this endpoint last month" reaches the ones who aren't, and who are the actual risk when the cutoff happens.

How Do You Set a Grace Period Based on Data?

A ninety-day deprecation window is a common default, but the right window depends on how quickly your telemetry shows usage actually declining after the announcement goes out. If volume from most accounts drops to near zero within the first few weeks but a handful of accounts are still steady, extend individual outreach to those accounts rather than extending the deadline for everyone; a blanket extension mostly rewards callers who ignored the first notice and penalizes nobody in particular.

Monitor for Stragglers Right Up to, and Past, the Cutoff

On cutoff day, don't just flip the endpoint off and assume the plan worked: alert if call volume on the deprecated endpoint doesn't drop to zero, since that's a sign either your outreach missed an account or a caller has a retry loop that will keep hammering a now-dead endpoint indefinitely. A short window returning a clear error with the migration guide's URL in the response body, rather than an immediate hard 404, gives any straggler one more chance to notice before you remove the endpoint entirely.

The sunset sequence in short:

  1. Add a Deprecation header as soon as you decide to retire the endpoint, then a Sunset header once the date is firm.
  2. Log caller identity and volume for at least a full billing or usage cycle to build a list of accounts still calling it.
  3. Email stragglers directly with their own usage numbers and a migration guide specific to what they call.
  4. Set the grace period from how fast your telemetry shows usage falling, not from a round number.
  5. On cutoff day, alert if call volume doesn't drop to zero, and check for internal callers you forgot.

Internal Callers Are Easy to Forget and Just as Risky

A deprecation plan aimed entirely at external partners often misses internal services still calling the old endpoint, a batch job nobody's touched in a year, a dashboard built by a team that's since moved on to other projects. Search your own codebase and internal service logs for calls to the endpoint with the same rigor you'd apply to external caller telemetry; an internal straggler is just as capable of breaking on cutoff day, and it's usually more embarrassing when the outage traces back to your own team's unmaintained code.

Versioning Strategy Determines How Painful the Next Deprecation Is

A clear versioning convention, whether that's a version number in the URL path or a version header, makes every future deprecation easier by giving you a clean boundary: old-version callers keep working against the old version while new functionality ships only in the new one, rather than every change being a potential breaking change against a single unversioned endpoint. Retrofitting versioning onto an API that's never had it is real work, but it pays for itself the first time you need to sunset something without a scramble to identify every caller from scratch.

Executive Capability Standard

What Good Looks Like

A deprecated endpoint should tell callers it's dying, in its response headers, with a real date, well before you ever turn it off.

Building The Capability (5-Stage Skill Ladder)

1. Learn:Read RFC 8594 on the Sunset header before writing your own deprecation policy from scratch.
2. Do Manually:Email your top callers directly before you rely on a changelog post reaching them.
3. Delegate:Give one engineer ownership of tracking which accounts are still calling deprecated endpoints.
4. Automate:Add Deprecation and Sunset headers automatically and alert when volume on a dying endpoint stalls instead of dropping.
5. Buy:Consider an API management platform with built-in versioning and deprecation tooling once you're sunsetting endpoints often enough to justify it.

How to Get Started

Frequently Asked Questions

What's the difference between the Deprecation and Sunset HTTP headers?

Deprecation signals the endpoint is on its way out without necessarily committing to a date yet; Sunset specifies the actual date it will stop working, per RFC 8594. Send Deprecation as soon as you decide to retire something, and add Sunset once you've committed to a firm cutoff date.

How long should a typical deprecation grace period be?

It should be driven by how quickly your own usage telemetry shows callers migrating after you announce, not by a universal number. Set a floor generous enough that a caller who only checks your documentation occasionally still has a real chance to notice and act.

What if a straggler account never responds to outreach before the cutoff?

Extend a short, explicit final grace period for that specific account rather than the whole cutoff, and make clear in every remaining response from the endpoint that it will stop working on a fixed date. A hard cutoff with no warning at all risks an outage for a customer who genuinely never saw any of the earlier signals.

About the numbers

This guide doesn't quote a sourced benchmark. Figures in it are estimates or general guidance, so check them against your own numbers.

Related Guides