# How should I run the sunset process when deprecating an endpoint in my public API?

> Instrument usage per partner, publish a dated sunset with Sunset and Deprecation headers on every response, run brownouts, and cut when usage nears zero.

- Asked: 2026-07-11
- Answered: 2026-07-17
- Asked by: Burak
- Tags: api, api-design
- Source: https://muhammetsafak.com/just-ask/how-should-i-run-the-sunset-process-when-deprecating-an-endpoint/
- Language: en-US
- Author: Muhammet Şafak

---
**Question:** I run a public API and I've flagged three legacy endpoints for removal. But several paying partners still hit those endpoints every single day.

How do I retire these endpoints without breaking the partners' integrations? How should I run the sunset process step by step, what signals should I send, and when exactly should I actually cut it off?


Short answer: never silently delete an endpoint paying partners use.

## Short answer

Run an announced, dated, measured sunset — communicate, signal it in the response, watch usage drop to zero, then remove it. The core mistake is treating removal as an engineering event when it's really a communication process; the code change that finally deletes the route is the last and smallest step of the whole thing. The layer above this decision — retiring a whole version rather than an endpoint — is something I worked through in [the API versioning post](/blog/api-versioning-strategies-and-tradeoffs/).

## Why

1. **No date means no urgency.** And no urgency means nobody migrates; a "we'll remove this soon" notice with no concrete replacement and no realistic window changes no behavior at all.
2. **Humans don't read the announcement — machines do.** Email and a changelog alone aren't enough; unless the signal travels inside the response, the integration itself never learns about the removal.
3. **You can't retire what you can't see.** A cut-off date set without knowing who calls it and how often is a gamble; without measurement you can never say "usage is near zero" with a straight face.
4. **Contractual reality outranks the calendar.** Breaking a big paying partner's production mid-migration costs far more than slipping a tidy deprecation schedule.

## What to do

1. **Announce with a hard date and a migration path.** Email + changelog + docs; give the partner a concrete replacement and a realistic window (weeks/months for paying B2B, not days).
2. **Signal it in the response itself.** These are two separate headers from two separate RFCs: `Sunset` (RFC 8594) says when the resource becomes unresponsive, `Deprecation` (RFC 9745) says when it was deprecated. Add a `Link` header pointing at the migration docs as the third. Put all three on every response from the doomed endpoint, so machines and logs see it too, not just humans who ignore the email.

   Note: `Deprecation` is not a boolean — RFC 9745 requires the value to be a Date (a structured field; a Unix timestamp prefixed with `@`).

   ```http
   HTTP/1.1 200 OK
   Deprecation: @1780272000
   Sunset: Sat, 31 Oct 2026 23:59:59 GMT
   Link: <https://api.example.com/docs/migrate-v2>; rel="deprecation"; type="text/html"
   ```

3. **Measure usage per consumer.** Log calls by API key/partner; you need to know exactly who still calls it and how often, and reach those partners directly.
4. **Run brownouts before you cut.** As the date approaches, apply short, scheduled outages (return `410`/`503` for a few minutes, escalating the duration). This surfaces integrations that ignored every header and email while the impact is still reversible.
5. **Return the right status on removal.** Not a silent `500`; return `410 Gone` (or `404`) with a body that explains the replacement. Keep that explanatory response up for a long time after removal.
6. **Keep an escalation valve.** For a big paying partner mid-migration, a temporary allowlist/extension beats breaking their production. Just document who got an extension and until when, so the valve doesn't quietly become permanent.

**Bottom line:** personally I'd instrument per-partner usage first, then publish a dated sunset with those headers on every response, run a couple of brownouts near the date, and only cut when usage is near zero — while leaving a manual extension valve for the one partner who always misses the memo. In a public API, reputation is lost with a single silent removal.

## Related Reading

- [API versioning strategies and trade-offs](/blog/api-versioning-strategies-and-tradeoffs/) — Blog
- [Should I move my API error bodies to the RFC 7807 problem+json format?](https://muhammetsafak.com/just-ask/move-api-error-bodies-rfc-7807-problem-json/) — Just Ask
- [Should I author the OpenAPI spec first or generate it from my code?](https://muhammetsafak.com/just-ask/should-i-author-the-openapi-spec-first-or-generate-it-from/) — Just Ask
- [The payment webhook keeps re-sending the same notification; how do I set up idempotency?](https://muhammetsafak.com/just-ask/webhook-idempotency-and-hmac-for-duplicate-payment-notifications/) — Just Ask
