How to Deprecate an API Endpoint Without Abandoning Your Users
by Eric Hanson, Backend Developer at Clean Systems Consulting
Deprecation is where most APIs break trust
Shipping an API is straightforward compared to evolving it. The real test comes when you need to remove or replace something that clients are already using.
Most teams handle this poorly. They either:
- Leave deprecated endpoints running forever (creating long-term maintenance debt), or
- Remove them too quickly and break clients in production
Neither scales. Deprecation is not just a cleanup task—it’s part of your API contract.
If clients depend on an endpoint, removing it without a clear path forward is effectively abandoning them.
Step 1: Make deprecation explicit in the protocol
The first mistake teams make is announcing deprecation only in documentation or release notes. That’s not enough.
Deprecation needs to be visible in the API responses themselves.
Use standard HTTP headers defined in RFC 8594:
Deprecation: true
Sunset: Wed, 01 Jan 2027 00:00:00 GMT
Deprecationsignals that the endpoint is no longer recommendedSunsetprovides a concrete removal date
This ensures that even clients who ignore your docs will see the signal in production traffic.
If you rely only on external communication, you’ll miss consumers you didn’t know existed.
Step 2: Provide a migration path, not just a warning
Telling users something is going away isn’t helpful unless you tell them what to do instead.
Every deprecated endpoint should point to a replacement:
Link: </v2/users>; rel="successor-version"
And that replacement should be:
- Functionally equivalent (or clearly improved)
- Documented with examples
- Available before deprecation begins
If the new version requires significant changes, call them out explicitly. Don’t make clients reverse-engineer the difference.
Step 3: Measure who is still using it
You can’t deprecate safely if you don’t know who’s still calling the endpoint.
At minimum, track:
- Request volume per endpoint
- Version or route usage (
/v1/usersvs/v2/users) - API keys or client identifiers
Example logging strategy:
app.use((req, res, next) => {
metrics.increment('api.requests', {
path: req.path,
version: extractVersion(req.path),
apiKey: req.headers['x-api-key'],
})
next()
})
This gives you a clear picture of:
- Which clients have migrated
- Which ones haven’t
- How risky it is to remove the endpoint
Without this, you’re guessing.
Step 4: Set a timeline and stick to it
Indefinite deprecation is just avoidance. You need a clear timeline.
A typical window:
- Announce deprecation
- Give 6–12 months for migration (depending on client complexity)
- Send reminders as the sunset date approaches
- Remove the endpoint on schedule
If you keep extending the deadline, clients will learn they can ignore your timelines.
Consistency matters more than being generous.
Step 5: Reduce blast radius before removal
Before fully removing an endpoint, you can gradually reduce risk:
- Throttle deprecated endpoints
- Add warning payloads in responses
- Return partial data if appropriate
In some cases, teams introduce a “soft failure” phase:
{
"warning": "This endpoint will be removed on 2027-01-01",
"data": { ... }
}
This is controversial—some clients ignore it—but it can surface issues earlier.
The goal is to make the final removal unsurprising.
Step 6: Remove it cleanly
When the sunset date arrives, remove the endpoint decisively.
Don’t leave partial behavior or silent fallbacks. Return a clear error:
410 Gone
This signals that the resource is intentionally no longer available—not just temporarily broken.
Anything less creates confusion and slows down client fixes.
The real tradeoffs
Deprecation done properly has costs:
- You maintain old behavior longer than you’d like
- Observability and tracking become mandatory
- Documentation must stay accurate across versions
But the alternative is worse:
- Breaking clients without warning
- Losing trust with integrators
- Turning every change into a negotiation
APIs are long-lived contracts. Deprecation is how you evolve them without burning those contracts.
What to do on Monday
Pick one endpoint that you know needs to go away and formalize its deprecation:
- Add
DeprecationandSunsetheaders - Define and document its replacement
- Start tracking who is still using it
- Set a real removal date
Don’t wait for a large-scale cleanup. Deprecation is easier when it’s routine, not when it’s urgent.