Guide
How to deprecate an API version without breaking your customers
Every API team eventually has to turn off v1. The code is the easy part. The
hard part is the question nobody can answer with confidence: who breaks when we do?
Most teams answer it by announcing a date, waiting, and hoping. The version's status lives in a changelog, the usage data lives in a monitoring tool, and nothing joins the two. So the retirement slips, the old version keeps running for years, and every breaking change after it costs more.
Here is the process that works, whether or not you use a tool for it.
1. Find out who is still calling the old version
You need usage broken down by client and version, not just total traffic. "v1 still gets 4% of requests" is not actionable. "Three clients still call v1, and one of them is your largest customer" is. If your gateway or logs cannot answer this by client identity, fix that first: everything else depends on it.
2. Decide what "deprecated" means, and write it down
A deprecation policy answers three questions:
- How much notice consumers get before a version is retired.
- What support a deprecated version still receives: security fixes only, or nothing.
- Who can grant an exception, and for how long.
Publish it where consumers will find it before they need it.
3. Tell consumers in the response, not only in an email
Two standard response headers exist for exactly this. The Deprecation
header (RFC 9745) says when the endpoint was, or will be, deprecated, and the
Sunset
header (RFC 8594) says when it will stop working:
HTTP/1.1 200 OK
Deprecation: @1798761600
Sunset: Wed, 30 Jun 2027 00:00:00 GMT
Link: <https://api.example.com/docs/migrate-to-v2>; rel="deprecation"
Client libraries and monitoring can read these. Emails get lost when the engineer who built the integration has moved on; a header reaches whoever is running the code today.
4. Give every caller a migration path
For each client still on the old version, know which endpoints they call and what replaces
each one. A generic "please upgrade to v2" loses to a specific "your two calls to
/v1/charges
map to /v2/payments
like this".
5. Set a date, and remind people as it approaches
A date nobody is reminded about is a date nobody remembers. Reminders a month, a week and a day before the date, sent to the people who actually own the integration, catch most stragglers.
6. Retire on evidence, not on the calendar
On the day, check usage again. If a client is still calling, decide deliberately: extend the date for that client, or go ahead knowing exactly who breaks. Either is fine. Finding out from a support ticket is not.
7. Leave a clear failure behind
After retirement, return a clear error, such as 410 Gone
with a link to the migration guide, rather than a generic 404. The last
straggler should be able to fix their integration from the error alone.
Before you flip the switch, the deprecation checklist walks through the evidence, owners and cutover controls to have in place.
Where EndPointBlank fits
EndPointBlank keeps each endpoint version's lifecycle state next to the record of which clients still call it, so step 1 is a list rather than a log search. Mark a version deprecated in the portal and consumers are told, with no deploy. Attach a date and the version reads Retires in 30 days to you and to every consumer, with reminders 30, 7 and 1 day out. When the version leaves production, having been deprecated first, it is retired automatically.