Skip to content
Muhammet Şafak
tr
Asked by: Burak Answered:

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


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?

Answer

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.

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/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

Share:

Comments

Sign in with your GitHub account to join the discussion. Comments are stored in GitHub Discussions.

More Questions

All questions

Search the site

Start typing to search posts, projects and pages.

Esc to close Powered by Pagefind